diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000..3c4605c943bdb --- /dev/null +++ b/.gitattributes @@ -0,0 +1,13 @@ +**/*.pb.go linguist-generated=true +**/mocks/*.go linguist-generated=true +assets/swagger.json linguist-generated=true +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/crds/*-crd.yaml linguist-generated=true +manifests/ha/install.yaml linguist-generated=true +manifests/ha/namespace-install.yaml linguist-generated=true +manifests/install.yaml linguist-generated=true +manifests/namespace-install.yaml linguist-generated=true +pkg/apis/api-rules/violation_exceptions.list linguist-generated=true diff --git a/.github/ISSUE_TEMPLATE/new_dev_tool.md b/.github/ISSUE_TEMPLATE/new_dev_tool.md new file mode 100644 index 0000000000000..6100922376b9d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/new_dev_tool.md @@ -0,0 +1,43 @@ +--- +name: New Dev Tool Request +about: This is a request for adding a new tool for setting up a dev environment. +title: '' +labels: '' +assignees: '' +--- + +Checklist: + +* [ ] I am willing to maintain this tool, or have another Argo CD maintainer who is. +* [ ] I have another Argo CD maintainer who is willing to help maintain this tool (there needs to be at least two maintainers willing to maintain this tool) +* [ ] I have a lead sponsor who is a core Argo CD maintainer +* [ ] There is a PR which adds said tool - this is so that the maintainers can assess the impact of having this in the tree +* [ ] I have given a motivation why this should be added + +### The proposer + +<-- The username(s) of the person(s) proposing the tool --> + +### The proposed tool + + + +### Motivation + + + +### Link to PR (Optional) + + + +### Lead Sponsor(s) + +Final approval requires sponsorship from at least one core maintainer. + +- @ + +### Co-sponsors + +These will be the co-maintainers of the specified tool. + +- @ diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e10453f61b17b..6205c1098d1f9 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,8 +4,13 @@ updates: directory: "/" schedule: interval: "daily" + open-pull-requests-limit: 20 ignore: - dependency-name: k8s.io/* + groups: + otel: + patterns: + - "^go.opentelemetry.io/.*" - package-ecosystem: "github-actions" directory: "/" diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index 51de323f3b76c..5fe31bf6ca9f9 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -31,7 +31,7 @@ jobs: docs: ${{ steps.filter.outputs.docs_any_changed }} steps: - uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - - uses: tj-actions/changed-files@d6babd6899969df1a11d14c368283ea4436bca78 # v44.5.2 + - uses: tj-actions/changed-files@48d8f15b2aaa3d255ca5af3eba4870f807ce6b3c # v45.0.2 id: filter with: # Any file which is not under docs/, ui/ or is not a markdown file is counted as a backend file @@ -56,7 +56,7 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: ${{ env.GOLANG_VERSION }} - name: Download all Go modules @@ -77,7 +77,7 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: ${{ env.GOLANG_VERSION }} - name: Restore go build cache @@ -104,11 +104,11 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: ${{ env.GOLANG_VERSION }} - name: Run golangci-lint - uses: golangci/golangci-lint-action@a4f60bb28d35aeee14e6880718e0c85ff1882e64 # v6.0.1 + uses: golangci/golangci-lint-action@aaa42aa0628b4ae2578232a66b541047968fac86 # v6.1.0 with: version: v1.58.2 args: --verbose @@ -131,7 +131,7 @@ jobs: - name: Create symlink in GOPATH run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd - name: Setup Golang - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: ${{ env.GOLANG_VERSION }} - name: Install required packages @@ -172,7 +172,7 @@ jobs: - name: Run all unit tests run: make test-local - name: Generate test results artifacts - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: test-results path: test-results @@ -195,7 +195,7 @@ jobs: - name: Create symlink in GOPATH run: ln -s $(pwd) ~/go/src/github.com/argoproj/argo-cd - name: Setup Golang - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: ${{ env.GOLANG_VERSION }} - name: Install required packages @@ -236,7 +236,7 @@ jobs: - name: Run all unit tests run: make test-race-local - name: Generate test results artifacts - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: race-results path: test-results/ @@ -251,7 +251,7 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: ${{ env.GOLANG_VERSION }} - name: Create symlink in GOPATH @@ -303,7 +303,7 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup NodeJS - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 with: node-version: '21.6.1' - name: Restore node dependency cache @@ -323,6 +323,8 @@ jobs: NODE_ENV: production NODE_ONLINE_ENV: online HOST_ARCH: amd64 + # If we're on the master branch, set the codecov token so that we upload bundle analysis + CODECOV_TOKEN: ${{ github.ref == 'refs/heads/master' && secrets.CODECOV_TOKEN || '' }} working-directory: ui/ - name: Run ESLint run: yarn lint @@ -354,21 +356,22 @@ jobs: run: | rm -rf ui/node_modules/argo-ui/node_modules - name: Get e2e code coverage - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: name: e2e-code-coverage path: e2e-code-coverage - name: Get unit test code coverage - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: name: test-results path: test-results - name: combine-go-coverage - # We generate coverage reports for all Argo CD components, but only the applicationset-controller report - # contains coverage data. The other components currently don't shut down gracefully, so no coverage data is - # produced. Once those components are fixed, we can add references to their coverage output directories. + # We generate coverage reports for all Argo CD components, but only the applicationset-controller, + # app-controller, and repo-server report contain coverage data. The other components currently don't shut down + # gracefully, so no coverage data is produced. Once those components are fixed, we can add references to their + # coverage output directories. run: | - go tool covdata percent -i=test-results,e2e-code-coverage/applicationset-controller -o test-results/full-coverage.out + go tool covdata percent -i=test-results,e2e-code-coverage/applicationset-controller,e2e-code-coverage/repo-server,e2e-code-coverage/app-controller -o test-results/full-coverage.out - name: Upload code coverage information to codecov.io uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0 with: @@ -376,11 +379,18 @@ jobs: fail_ci_if_error: true env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + - name: Upload test results to Codecov + if: github.ref == 'refs/heads/master' && github.event_name == 'push' && github.repository == 'argoproj/argo-cd' + uses: codecov/test-results-action@1b5b448b98e58ba90d1a1a1d9fcb72ca2263be46 # v1.0.0 + with: + file: test-results/junit.xml + fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} - name: Perform static code analysis using SonarCloud env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - uses: SonarSource/sonarqube-scan-action@540792c588b5c2740ad2bb4667db5cd46ae678f2 # v2.2 + uses: SonarSource/sonarqube-scan-action@aecaf43ae57e412bd97d70ef9ce6076e672fe0a9 # v2.2 if: env.sonar_secret != '' test-e2e: name: Run end-to-end tests @@ -390,14 +400,14 @@ jobs: fail-fast: false matrix: k3s: - - version: v1.29.1 + - version: v1.30.2 # We designate the latest version because we only collect code coverage for that version. latest: true - - version: v1.28.6 + - version: v1.29.6 latest: false - - version: v1.27.10 + - version: v1.28.11 latest: false - - version: v1.26.13 + - version: v1.27.15 latest: false needs: - build-go @@ -419,7 +429,7 @@ jobs: - name: Checkout code uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0 - name: Setup Golang - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: ${{ env.GOLANG_VERSION }} - name: GH actions workaround - Kill XSP4 process @@ -464,7 +474,7 @@ 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.38.0 + docker pull ghcr.io/dexidp/dex:v2.41.1 docker pull argoproj/argo-cd-ci-builder:v1.0.0 docker pull redis:7.0.15-alpine - name: Create target directory for binaries in the build-process @@ -496,13 +506,13 @@ jobs: goreman run stop-all || echo "goreman trouble" sleep 30 - name: Upload e2e coverage report - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: e2e-code-coverage path: /tmp/coverage if: ${{ matrix.k3s.latest }} - name: Upload e2e-server logs - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: e2e-server-k8s${{ matrix.k3s.version }}.log path: /tmp/e2e-server.log diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 7dcc9f6e24bca..530340127708c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,7 +23,7 @@ jobs: actions: read # for github/codeql-action/init to get workflow details contents: read # for actions/checkout to fetch code security-events: write # for github/codeql-action/autobuild to send a status report - if: github.repository == 'argoproj/argo-cd' + if: github.repository == 'argoproj/argo-cd' || vars.enable_codeql # CodeQL runs on ubuntu-latest and windows-latest runs-on: ubuntu-22.04 @@ -33,7 +33,7 @@ jobs: # Use correct go version. https://github.com/github/codeql-action/issues/1842#issuecomment-1704398087 - name: Setup Golang - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version-file: go.mod diff --git a/.github/workflows/image-reuse.yaml b/.github/workflows/image-reuse.yaml index 5848f65be088b..f4b7a851816a8 100644 --- a/.github/workflows/image-reuse.yaml +++ b/.github/workflows/image-reuse.yaml @@ -69,15 +69,15 @@ jobs: if: ${{ github.ref_type != 'tag'}} - name: Setup Golang - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: ${{ inputs.go-version }} - name: Install cosign - uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3.5.0 + uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3.6.0 - - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 - - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + - uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 + - uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1 - name: Setup tags for container image as a CSV type run: | @@ -104,7 +104,7 @@ jobs: echo 'EOF' >> $GITHUB_ENV - name: Login to Quay.io - uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: registry: quay.io username: ${{ secrets.quay_username }} @@ -112,7 +112,7 @@ jobs: if: ${{ inputs.quay_image_name && inputs.push }} - name: Login to GitHub Container Registry - uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: registry: ghcr.io username: ${{ secrets.ghcr_username }} @@ -120,7 +120,7 @@ jobs: if: ${{ inputs.ghcr_image_name && inputs.push }} - name: Login to dockerhub Container Registry - uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: username: ${{ secrets.docker_username }} password: ${{ secrets.docker_password }} @@ -143,7 +143,7 @@ jobs: - name: Build and push container image id: image - uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 #v5.4.0 + uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85 #v6.7.0 with: context: . platforms: ${{ inputs.platforms }} diff --git a/.github/workflows/init-release.yaml b/.github/workflows/init-release.yaml index 70de72d391dba..8353e8a67ae84 100644 --- a/.github/workflows/init-release.yaml +++ b/.github/workflows/init-release.yaml @@ -64,7 +64,7 @@ jobs: git stash pop - name: Create pull request - uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e # v6.0.5 + uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5 with: commit-message: "Bump version to ${{ inputs.TARGET_VERSION }}" title: "Bump version to ${{ inputs.TARGET_VERSION }} on ${{ inputs.TARGET_BRANCH }} branch" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index bc8f73bfc6f6f..a30e44ec0ec7a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -77,7 +77,7 @@ jobs: fi - name: Setup Golang - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: ${{ env.GOLANG_VERSION }} @@ -153,7 +153,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Golang - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: ${{ env.GOLANG_VERSION }} @@ -197,7 +197,7 @@ jobs: echo "hashes=$(sha256sum /tmp/sbom.tar.gz | base64 -w0)" >> "$GITHUB_OUTPUT" - name: Upload SBOM - uses: softprops/action-gh-release@69320dbe05506a9a39fc8ae11030b214ec2d1f87 # v2.0.5 + uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v2.0.8 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -291,11 +291,11 @@ jobs: # Replace the 'project-release: vX.X.X-rcX' line in SECURITY-INSIGHTS.yml sed -i "s/project-release: v.*$/project-release: v${{ env.NEW_VERSION }}/" SECURITY-INSIGHTS.yml # Update the 'commit-hash: XXXXXXX' line in SECURITY-INSIGHTS.yml - sed -i "s/commit-hash: .*/commit-hash: ${{ env.NEW_VERSION }}/" SECURITY-INSIGHTS.yml + sed -i "s/commit-hash: .*/commit-hash: ${{ env.COMMIT_HASH }}/" SECURITY-INSIGHTS.yml if: ${{ env.UPDATE_VERSION == 'true' }} - name: Create PR to update VERSION on master branch - uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e # v6.0.5 + uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5 with: commit-message: Bump version in master title: "chore: Bump version in master" diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml index 28621c86666c5..6975868f4a78a 100644 --- a/.github/workflows/scorecard.yaml +++ b/.github/workflows/scorecard.yaml @@ -35,7 +35,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3 + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 with: results_file: results.sarif results_format: sarif @@ -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@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: SARIF file path: results.sarif diff --git a/.gitpod.Dockerfile b/.gitpod.Dockerfile index 87afd912bcef0..ec47f2553d19d 100644 --- a/.gitpod.Dockerfile +++ b/.gitpod.Dockerfile @@ -1,4 +1,4 @@ -FROM gitpod/workspace-full@sha256:8dd34e72ae5b9e6f60d267dd6287befc2cf5ad1a11c64e9d93daa60c952a2154 +FROM gitpod/workspace-full@sha256:230285e0b949e6d728d384b2029a4111db7b9c87c182f22f32a0be9e36b225df USER root diff --git a/.golangci.yaml b/.golangci.yaml index 7226203cf2fd1..2140cf08a7bd9 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,14 +1,12 @@ issues: exclude: - - SA1019 - SA5011 - exclude-rules: - - path: "(applicationset|cmpserver|controller|pkg|reposerver)/" - text: "require-error:" - linters: - - testifylint max-issues-per-linter: 0 max-same-issues: 0 + exclude-rules: + - path: '(.+)_test\.go' + linters: + - unparam linters: enable: - errcheck @@ -22,6 +20,7 @@ linters: - misspell - staticcheck - testifylint + - unparam - unused - whitespace linters-settings: @@ -41,8 +40,6 @@ linters-settings: testifylint: enable-all: true disable: - - error-is-as - - float-compare - go-require run: timeout: 50m diff --git a/.mockery.yaml b/.mockery.yaml new file mode 100644 index 0000000000000..3a8b437ef347d --- /dev/null +++ b/.mockery.yaml @@ -0,0 +1,69 @@ +# global config +filename: "{{.InterfaceName}}.go" +dir: "{{.InterfaceDir}}/mocks" +outpkg: "mocks" +mockname: "{{.InterfaceName}}" +with-expecter: false +# individual interface config +packages: + github.com/argoproj/argo-cd/v2/applicationset/generators: + interfaces: + Generator: + github.com/argoproj/argo-cd/v2/applicationset/services: + interfaces: + Repos: + github.com/argoproj/argo-cd/v2/applicationset/services/scm_provider: + config: + dir: "applicationset/services/scm_provider/aws_codecommit/mocks" + interfaces: + AWSCodeCommitClient: + AWSTaggingClient: + github.com/microsoft/azure-devops-go-api/azuredevops/git: + config: + dir: "applicationset/services/scm_provider/azure_devops/git/mocks" + interfaces: + Client: + github.com/argoproj/argo-cd/v2/applicationset/utils: + interfaces: + Renderer: + 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: diff --git a/Dockerfile b/Dockerfile index ac5f16db425a7..bc4e6debbfaa1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:3f85b7caad41a95462cf5b787d8 # Initial stage which pulls prepares build dependencies and CLI tooling we need for our final image # Also used as the image in CI jobs so needs all dependencies #################################################################################################### -FROM docker.io/library/golang:1.22.4@sha256:a0679accac8685cc5389bd2298e045e570100940e6bdcca666a8ca7b32a1276c AS builder +FROM docker.io/library/golang:1.23.1@sha256:2fe82a3f3e006b4f2a316c6a21f62b66e1330ae211d039bb8d1128e12ed57bf1 AS builder RUN echo 'deb http://archive.debian.org/debian buster-backports main' >> /etc/apt/sources.list @@ -83,7 +83,7 @@ WORKDIR /home/argocd #################################################################################################### # Argo CD UI stage #################################################################################################### -FROM --platform=$BUILDPLATFORM docker.io/library/node:22.3.0@sha256:5e4044ff6001d06e7748e35bfa4f80c73cf5f5a7360a1b782995e038a01b0585 AS argocd-ui +FROM --platform=$BUILDPLATFORM docker.io/library/node:22.9.0@sha256:cbe2d5f94110cea9817dd8c5809d05df49b4bd1aac5203f3594d88665ad37988 AS argocd-ui WORKDIR /src COPY ["ui/package.json", "ui/yarn.lock", "./"] @@ -101,7 +101,7 @@ RUN HOST_ARCH=$TARGETARCH NODE_ENV='production' NODE_ONLINE_ENV='online' NODE_OP #################################################################################################### # Argo CD Build stage which performs the actual build of Argo CD binaries #################################################################################################### -FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.22.4@sha256:a0679accac8685cc5389bd2298e045e570100940e6bdcca666a8ca7b32a1276c AS argocd-build +FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.23.1@sha256:2fe82a3f3e006b4f2a316c6a21f62b66e1330ae211d039bb8d1128e12ed57bf1 AS argocd-build WORKDIR /go/src/github.com/argoproj/argo-cd diff --git a/Makefile b/Makefile index edcb8bfbcf9d0..d6f8cdf62d5d8 100644 --- a/Makefile +++ b/Makefile @@ -192,6 +192,10 @@ endif .PHONY: all all: cli image +.PHONY: mockgen +mockgen: + ./hack/generate-mock.sh + .PHONY: gogen gogen: export GO111MODULE=off @@ -229,13 +233,16 @@ clientgen: clidocsgen: go run tools/cmd-docs/main.go +.PHONY: actionsdocsgen +actionsdocsgen: + hack/generate-actions-list.sh .PHONY: codegen-local -codegen-local: mod-vendor-local gogen protogen clientgen openapigen clidocsgen manifests-local notification-docs notification-catalog +codegen-local: mod-vendor-local mockgen gogen protogen clientgen openapigen clidocsgen actionsdocsgen manifests-local notification-docs notification-catalog rm -rf vendor/ .PHONY: codegen-local-fast -codegen-local-fast: gogen protogen-fast clientgen openapigen clidocsgen manifests-local notification-docs notification-catalog +codegen-local-fast: mockgen gogen protogen-fast clientgen openapigen clidocsgen manifests-local notification-docs notification-catalog .PHONY: codegen codegen: test-tools-image @@ -247,7 +254,7 @@ cli: test-tools-image .PHONY: cli-local cli-local: clean-debug - CGO_ENABLED=${CGO_FLAG} GODEBUG="tarinsecurepath=0,zipinsecurepath=0" go build $(COVERAGE_FLAG) -v -ldflags '${LDFLAGS}' -o ${DIST_DIR}/${CLI_NAME} ./cmd + CGO_ENABLED=${CGO_FLAG} GODEBUG="tarinsecurepath=0,zipinsecurepath=0" go build -gcflags="all=-N -l" $(COVERAGE_FLAG) -v -ldflags '${LDFLAGS}' -o ${DIST_DIR}/${CLI_NAME} ./cmd .PHONY: gen-resources-cli-local gen-resources-cli-local: clean-debug @@ -546,7 +553,7 @@ build-docs-local: .PHONY: build-docs build-docs: - $(DOCKER) run ${MKDOCS_RUN_ARGS} --rm -it -v ${CURRENT_DIR}:/docs -w /docs --entrypoint "" ${MKDOCS_DOCKER_IMAGE} sh -c 'pip install -r docs/requirements.txt; mkdocs build' + $(DOCKER) run ${MKDOCS_RUN_ARGS} --rm -it -v ${CURRENT_DIR}:/docs -w /docs --entrypoint "" ${MKDOCS_DOCKER_IMAGE} sh -c 'pip install mkdocs; pip install $$(mkdocs get-deps); mkdocs build' .PHONY: serve-docs-local serve-docs-local: @@ -554,7 +561,7 @@ serve-docs-local: .PHONY: serve-docs serve-docs: - $(DOCKER) run ${MKDOCS_RUN_ARGS} --rm -it -p 8000:8000 -v ${CURRENT_DIR}:/docs -w /docs --entrypoint "" ${MKDOCS_DOCKER_IMAGE} sh -c 'pip install -r docs/requirements.txt; mkdocs serve -a $$(ip route get 1 | awk '\''{print $$7}'\''):8000' + $(DOCKER) run ${MKDOCS_RUN_ARGS} --rm -it -p 8000:8000 -v ${CURRENT_DIR}:/docs -w /docs --entrypoint "" ${MKDOCS_DOCKER_IMAGE} sh -c 'pip install mkdocs; pip install $$(mkdocs get-deps); mkdocs serve -a $$(ip route get 1 | awk '\''{print $$7}'\''):8000' # Verify that kubectl can connect to your K8s cluster from Docker .PHONY: verify-kube-connect diff --git a/OWNERS b/OWNERS index 56e037e282a0a..ca6588fd3d6c8 100644 --- a/OWNERS +++ b/OWNERS @@ -1,5 +1,6 @@ owners: - alexmt +- crenshaw-dev - jessesuen approvers: diff --git a/Procfile b/Procfile index 25f9c7206eef6..fd955a39ac416 100644 --- a/Procfile +++ b/Procfile @@ -1,7 +1,7 @@ controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/app-controller} HOSTNAME=testappcontroller-1 FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} --server-side-diff-enabled=${ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF:-'false'}" api-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/api-server} FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-server $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''}" 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: bash -c "if [ \"$ARGOCD_REDIS_LOCAL\" = 'true' ]; then redis-server --save '' --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}; else docker run --rm --name argocd-redis -i -p ${ARGOCD_E2E_REDIS_PORT:-6379}:${ARGOCD_E2E_REDIS_PORT:-6379} docker.io/library/redis:$(grep "image: redis" manifests/base/redis/argocd-redis-deployment.yaml | cut -d':' -f3) --save '' --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}; fi" +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}" ui: sh -c 'cd ui && ${ARGOCD_E2E_YARN_CMD:-yarn} start' diff --git a/README.md b/README.md index 707848191c830..b369043821010 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,7 @@ [![Integration tests](https://github.com/argoproj/argo-cd/workflows/Integration%20tests/badge.svg?branch=master)](https://github.com/argoproj/argo-cd/actions?query=workflow%3A%22Integration+tests%22) [![codecov](https://codecov.io/gh/argoproj/argo-cd/branch/master/graph/badge.svg)](https://codecov.io/gh/argoproj/argo-cd) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4486/badge)](https://bestpractices.coreinfrastructure.org/projects/4486) -[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/argoproj/argo-cd/badge)](https://api.securityscorecards.dev/projects/github.com/argoproj/argo-cd) -[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fargoproj%2Fargo-cd.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fargoproj%2Fargo-cd?ref=badge_shield) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/argoproj/argo-cd/badge)](https://scorecard.dev/viewer/?uri=github.com/argoproj/argo-cd) **Social:** [![Twitter Follow](https://img.shields.io/twitter/follow/argoproj?style=social)](https://twitter.com/argoproj) @@ -57,7 +56,7 @@ Participation in the Argo CD project is governed by the [CNCF Code of Conduct](h ### Blogs and Presentations 1. [Awesome-Argo: A Curated List of Awesome Projects and Resources Related to Argo](https://github.com/terrytangyuan/awesome-argo) -1. [Unveil the Secret Ingredients of Continuous Delivery at Enterprise Scale with Argo CD](https://akuity.io/blog/unveil-the-secret-ingredients-of-continuous-delivery-at-enterprise-scale-with-argocd-kubecon-china-2021/) +1. [Unveil the Secret Ingredients of Continuous Delivery at Enterprise Scale with Argo CD](https://akuity.io/blog/secret-ingredients-of-continuous-delivery-at-enterprise-scale-with-argocd/) 1. [GitOps Without Pipelines With ArgoCD Image Updater](https://youtu.be/avPUQin9kzU) 1. [Combining Argo CD (GitOps), Crossplane (Control Plane), And KubeVela (OAM)](https://youtu.be/eEcgn_gU3SM) 1. [How to Apply GitOps to Everything - Combining Argo CD and Crossplane](https://youtu.be/yrj4lmScKHQ) diff --git a/SECURITY-INSIGHTS.yml b/SECURITY-INSIGHTS.yml index 8ac4bc36b04ae..74236df3b1a27 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: b71277c6beb949d0199d647a582bc25822b88838 + commit-hash: 74a367d10e7110209610ba3ec225539ebe5f7522 project-url: https://github.com/argoproj/argo-cd - project-release: v2.9.0-rc3 + 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 609129ee498dd..ab5dbc8c745c1 100644 --- a/USERS.md +++ b/USERS.md @@ -11,6 +11,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [7shifts](https://www.7shifts.com/) 1. [Adevinta](https://www.adevinta.com/) 1. [Adfinis](https://adfinis.com) +1. [Adobe](https://www.adobe.com/) 1. [Adventure](https://jp.adventurekk.com/) 1. [Adyen](https://www.adyen.com) 1. [AirQo](https://airqo.net/) @@ -29,6 +30,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Arctiq Inc.](https://www.arctiq.ca) 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) 1. [Axians ACSP](https://www.axians.fr) 1. [Axual B.V.](https://axual.com) @@ -43,9 +45,11 @@ Currently, the following organizations are **officially** using Argo CD: 1. [BioBox Analytics](https://biobox.io) 1. [BMW Group](https://www.bmwgroup.com/) 1. [Boozt](https://www.booztgroup.com/) +1. [Bosch](https://www.bosch.com/) 1. [Boticario](https://www.boticario.com.br/) 1. [Broker Consulting, a.s.](https://www.bcas.cz/en/) 1. [Bulder Bank](https://bulderbank.no) +1. [Cabify](https://cabify.com/en) 1. [CAM](https://cam-inc.co.jp) 1. [Camptocamp](https://camptocamp.com) 1. [Candis](https://www.candis.io) @@ -62,12 +66,14 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Cisco ET&I](https://eti.cisco.com/) 1. [Cloud Posse](https://www.cloudposse.com/) 1. [Cloud Scale](https://cloudscaleinc.com/) +1. [CloudScript](https://www.cloudscript.com.br/) 1. [CloudGeometry](https://www.cloudgeometry.io/) 1. [Cloudmate](https://cloudmt.co.kr/) 1. [Cloudogu](https://cloudogu.com/) 1. [Cobalt](https://www.cobalt.io/) 1. [Codefresh](https://www.codefresh.io/) 1. [Codility](https://www.codility.com/) +1. [Cognizant](https://www.cognizant.com/) 1. [Commonbond](https://commonbond.co/) 1. [Contlo](https://contlo.com/) 1. [Coralogix](https://coralogix.com/) @@ -109,9 +115,11 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Freshop, Inc](https://www.freshop.com/) 1. [Future PLC](https://www.futureplc.com/) 1. [G DATA CyberDefense AG](https://www.gdata-software.com/) +1. [G-Research](https://www.gresearch.com/teams/open-source-software/) 1. [Garner](https://www.garnercorp.com) 1. [Generali Deutschland AG](https://www.generali.de/) 1. [Gepardec](https://gepardec.com/) +1. [Getir](https://getir.com) 1. [GetYourGuide](https://www.getyourguide.com/) 1. [Gitpod](https://www.gitpod.io) 1. [Gllue](https://gllue.com) @@ -128,6 +136,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Groww](https://groww.in) 1. [Grupo MasMovil](https://grupomasmovil.com/en/) 1. [Handelsbanken](https://www.handelsbanken.se) +1. [Hazelcast](https://hazelcast.com/) 1. [Healy](https://www.healyworld.net) 1. [Helio](https://helio.exchange) 1. [Hetki](https://hetki.ai) @@ -146,6 +155,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Index Exchange](https://www.indexexchange.com/) 1. [Info Support](https://www.infosupport.com/) 1. [InsideBoard](https://www.insideboard.com) +1. [Instruqt](https://www.instruqt.com) 1. [Intuit](https://www.intuit.com/) 1. [Jellysmack](https://www.jellysmack.com) 1. [Joblift](https://joblift.com/) @@ -155,6 +165,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Karrot](https://www.daangn.com/) 1. [KarrotPay](https://www.daangnpay.com/) 1. [Kasa](https://kasa.co.kr/) +1. [Kave Home](https://kavehome.com) 1. [Keeeb](https://www.keeeb.com/) 1. [KelkooGroup](https://www.kelkoogroup.com) 1. [Keptn](https://keptn.sh) @@ -167,6 +178,8 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Kurly](https://www.kurly.com/) 1. [Kvist](https://kvistsolutions.com) 1. [Kyriba](https://www.kyriba.com/) +1. [LeFigaro](https://www.lefigaro.fr/) +1. [Lely](https://www.lely.com/) 1. [LexisNexis](https://www.lexisnexis.com/) 1. [Lian Chu Securities](https://lczq.com) 1. [Liatrio](https://www.liatrio.com) @@ -196,12 +209,16 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Moengage](https://www.moengage.com/) 1. [Money Forward](https://corp.moneyforward.com/en/) 1. [MOO Print](https://www.moo.com/) +1. [Mozilla](https://www.mozilla.org) 1. [MTN Group](https://www.mtn.com/) +1. [Municipality of The Hague](https://www.denhaag.nl/) +1. [My Job Glasses](https://myjobglasses.com) 1. [Natura &Co](https://naturaeco.com/) 1. [Nethopper](https://nethopper.io) 1. [New Relic](https://newrelic.com/) 1. [Nextbasket](https://nextbasket.com) 1. [Nextdoor](https://nextdoor.com/) +1. [Next Fit Sistemas](https://nextfit.com.br/) 1. [Nikkei](https://www.nikkei.co.jp/nikkeiinfo/en/) 1. [Nitro](https://gonitro.com) 1. [NYCU, CS IT Center](https://it.cs.nycu.edu.tw) @@ -213,6 +230,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [omegaUp](https://omegaUp.com) 1. [Omni](https://omni.se/) 1. [Oncourse Home Solutions](https://oncoursehome.com/) +1. [Open Analytics](https://openanalytics.eu) 1. [openEuler](https://openeuler.org) 1. [openGauss](https://opengauss.org/) 1. [OpenGov](https://opengov.com) @@ -245,6 +263,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [PostFinance](https://github.com/postfinance) 1. [Preferred Networks](https://preferred.jp/en/) 1. [Previder BV](https://previder.nl) +1. [Priceline](https://priceline.com) 1. [Procore](https://www.procore.com) 1. [Productboard](https://www.productboard.com/) 1. [Prudential](https://prudential.com.sg) @@ -260,6 +279,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Redpill Linpro](https://www.redpill-linpro.com/) 1. [Reenigne Cloud](https://reenigne.ca) 1. [reev.com](https://www.reev.com/) +1. [Relex Solutions](https://www.relexsolutions.com/) 1. [RightRev](https://rightrev.com/) 1. [Rijkswaterstaat](https://www.rijkswaterstaat.nl/en) 1. [Rise](https://www.risecard.eu/) @@ -276,13 +296,17 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Schwarz IT](https://jobs.schwarz/it-mission) 1. [SCRM Lidl International Hub](https://scrm.lidl) 1. [SEEK](https://seek.com.au) +1. [SEKAI](https://www.sekai.io/) 1. [Semgrep](https://semgrep.com) 1. [Shield](https://shield.com) 1. [SI Analytics](https://si-analytics.ai) +1. [Sidewalk Entertainment](https://sidewalkplay.com/) 1. [Skit](https://skit.ai/) +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) +1. [Smilegate Stove](https://www.onstove.com/) 1. [Smood.ch](https://www.smood.ch/) 1. [Snapp](https://snapp.ir/) 1. [Snyk](https://snyk.io/) diff --git a/VERSION b/VERSION index d8b698973a491..edcfe40d1984a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.12.0 +2.14.0 diff --git a/applicationset/controllers/applicationset_controller.go b/applicationset/controllers/applicationset_controller.go index e0cba5955fe56..d3911f1e0c7c4 100644 --- a/applicationset/controllers/applicationset_controller.go +++ b/applicationset/controllers/applicationset_controller.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "reflect" + "sort" "strings" "time" @@ -31,11 +32,10 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/client-go/kubernetes" - k8scache "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/record" + "k8s.io/client-go/util/retry" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -43,11 +43,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/predicate" + "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" - "github.com/argoproj/argo-cd/v2/util/glob" argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" @@ -88,7 +90,7 @@ type ApplicationSetReconciler struct { SCMRootCAPath string GlobalPreservedAnnotations []string GlobalPreservedLabels []string - Cache cache.Cache + Metrics *metrics.ApplicationsetMetrics } // +kubebuilder:rbac:groups=argoproj.io,resources=applicationsets,verbs=get;list;watch;create;update;patch;delete @@ -99,7 +101,7 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque var applicationSetInfo argov1alpha1.ApplicationSet parametersGenerated := false - + startTime := time.Now() if err := r.Get(ctx, req.NamespacedName, &applicationSetInfo); err != nil { if client.IgnoreNotFound(err) != nil { logCtx.WithError(err).Infof("unable to get ApplicationSet: '%v' ", err) @@ -107,6 +109,10 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque return ctrl.Result{}, client.IgnoreNotFound(err) } + defer func() { + r.Metrics.ObserveReconcile(&applicationSetInfo, time.Since(startTime)) + }() + // Do not attempt to further reconcile the ApplicationSet if it is being deleted. if applicationSetInfo.ObjectMeta.DeletionTimestamp != nil { appsetName := applicationSetInfo.ObjectMeta.Name @@ -126,23 +132,26 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque return ctrl.Result{}, nil } + if err := r.migrateStatus(ctx, &applicationSetInfo); err != nil { + logCtx.Errorf("failed to migrate status subresource %v", err) + return ctrl.Result{}, err + } + // Log a warning if there are unrecognized generators _ = utils.CheckInvalidGenerators(&applicationSetInfo) // desiredApplications is the main list of all expected Applications from all generators in this appset. - desiredApplications, applicationSetReason, generatorsErr := r.generateApplications(logCtx, applicationSetInfo) - if generatorsErr != nil { + desiredApplications, applicationSetReason, err := template.GenerateApplications(logCtx, applicationSetInfo, r.Generators, r.Renderer, r.Client) + if err != nil { _ = r.setApplicationSetStatusCondition(ctx, &applicationSetInfo, argov1alpha1.ApplicationSetCondition{ Type: argov1alpha1.ApplicationSetConditionErrorOccurred, - Message: generatorsErr.Error(), + Message: err.Error(), Reason: string(applicationSetReason), Status: argov1alpha1.ApplicationSetConditionStatusTrue, }, parametersGenerated, ) - if len(desiredApplications) < 1 { - return ctrl.Result{}, generatorsErr - } + return ctrl.Result{RequeueAfter: ReconcileRequeueOnValidationError}, err } parametersGenerated = true @@ -237,20 +246,8 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque if r.EnableProgressiveSyncs { // trigger appropriate application syncs if RollingSync strategy is enabled - if progressiveSyncsStrategyEnabled(&applicationSetInfo, "RollingSync") { - validApps, err = r.syncValidApplications(logCtx, &applicationSetInfo, appSyncMap, appMap, validApps) - if err != nil { - _ = r.setApplicationSetStatusCondition(ctx, - &applicationSetInfo, - argov1alpha1.ApplicationSetCondition{ - Type: argov1alpha1.ApplicationSetConditionErrorOccurred, - Message: err.Error(), - Reason: argov1alpha1.ApplicationSetReasonSyncApplicationError, - Status: argov1alpha1.ApplicationSetConditionStatusTrue, - }, parametersGenerated, - ) - return ctrl.Result{}, err - } + if progressiveSyncsRollingSyncStrategyEnabled(&applicationSetInfo) { + validApps = r.syncValidApplications(logCtx, &applicationSetInfo, appSyncMap, appMap, validApps) } } @@ -320,7 +317,7 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque requeueAfter := r.getMinRequeueAfter(&applicationSetInfo) - if len(validateErrors) == 0 && generatorsErr == nil { + if len(validateErrors) == 0 { if err := r.setApplicationSetStatusCondition(ctx, &applicationSetInfo, argov1alpha1.ApplicationSetCondition{ @@ -404,8 +401,21 @@ func (r *ApplicationSetReconciler) setApplicationSetStatusCondition(ctx context. paramtersGeneratedCondition := getParametersGeneratedCondition(paramtersGenerated, condition.Message) resourceUpToDateCondition := getResourceUpToDateCondition(errOccurred, condition.Message, condition.Reason) + evaluatedTypes := map[argov1alpha1.ApplicationSetConditionType]bool{ + argov1alpha1.ApplicationSetConditionErrorOccurred: true, + argov1alpha1.ApplicationSetConditionParametersGenerated: true, + argov1alpha1.ApplicationSetConditionResourcesUpToDate: true, + } newConditions := []argov1alpha1.ApplicationSetCondition{errOccurredCondition, paramtersGeneratedCondition, resourceUpToDateCondition} + if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) { + evaluatedTypes[argov1alpha1.ApplicationSetConditionRolloutProgressing] = true + + if condition.Type == argov1alpha1.ApplicationSetConditionRolloutProgressing { + newConditions = append(newConditions, condition) + } + } + needToUpdateConditions := false for _, condition := range newConditions { // do nothing if appset already has same condition @@ -416,28 +426,32 @@ func (r *ApplicationSetReconciler) setApplicationSetStatusCondition(ctx context. } } } - evaluatedTypes := map[argov1alpha1.ApplicationSetConditionType]bool{ - argov1alpha1.ApplicationSetConditionErrorOccurred: true, - argov1alpha1.ApplicationSetConditionParametersGenerated: true, - argov1alpha1.ApplicationSetConditionResourcesUpToDate: true, - } - if needToUpdateConditions || len(applicationSet.Status.Conditions) < 3 { + if needToUpdateConditions || len(applicationSet.Status.Conditions) < len(newConditions) { // fetch updated Application Set object before updating it - namespacedName := types.NamespacedName{Namespace: applicationSet.Namespace, Name: applicationSet.Name} - if err := r.Get(ctx, namespacedName, applicationSet); err != nil { - if client.IgnoreNotFound(err) != nil { - return nil + // DefaultRetry will retry 5 times with a backoff factor of 1, jitter of 0.1 and a duration of 10ms + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + namespacedName := types.NamespacedName{Namespace: applicationSet.Namespace, Name: applicationSet.Name} + updatedAppset := &argov1alpha1.ApplicationSet{} + if err := r.Get(ctx, namespacedName, updatedAppset); err != nil { + if client.IgnoreNotFound(err) != nil { + return nil + } + return fmt.Errorf("error fetching updated application set: %w", err) } - return fmt.Errorf("error fetching updated application set: %w", err) - } - applicationSet.Status.SetConditions( - newConditions, evaluatedTypes, - ) + updatedAppset.Status.SetConditions( + newConditions, evaluatedTypes, + ) - // Update the newly fetched object with new set of conditions - err := r.Client.Status().Update(ctx, applicationSet) + // Update the newly fetched object with new set of conditions + err := r.Client.Status().Update(ctx, updatedAppset) + if err != nil { + return err + } + updatedAppset.DeepCopyInto(applicationSet) + return nil + }) if err != nil && !apierr.IsNotFound(err) { return fmt.Errorf("unable to set application set condition: %w", err) } @@ -495,92 +509,10 @@ func (r *ApplicationSetReconciler) getMinRequeueAfter(applicationSetInfo *argov1 return res } -func getTempApplication(applicationSetTemplate argov1alpha1.ApplicationSetTemplate) *argov1alpha1.Application { - var tmplApplication argov1alpha1.Application - tmplApplication.Annotations = applicationSetTemplate.Annotations - tmplApplication.Labels = applicationSetTemplate.Labels - tmplApplication.Namespace = applicationSetTemplate.Namespace - tmplApplication.Name = applicationSetTemplate.Name - tmplApplication.Spec = applicationSetTemplate.Spec - tmplApplication.Finalizers = applicationSetTemplate.Finalizers - - return &tmplApplication -} - -func (r *ApplicationSetReconciler) generateApplications(logCtx *log.Entry, applicationSetInfo argov1alpha1.ApplicationSet) ([]argov1alpha1.Application, argov1alpha1.ApplicationSetReasonType, error) { - var res []argov1alpha1.Application - - var firstError error - var applicationSetReason argov1alpha1.ApplicationSetReasonType - - for _, requestedGenerator := range applicationSetInfo.Spec.Generators { - t, err := generators.Transform(requestedGenerator, r.Generators, applicationSetInfo.Spec.Template, &applicationSetInfo, map[string]interface{}{}, r.Client) - if err != nil { - logCtx.WithError(err).WithField("generator", requestedGenerator). - Error("error generating application from params") - if firstError == nil { - firstError = err - applicationSetReason = argov1alpha1.ApplicationSetReasonApplicationParamsGenerationError - } - continue - } - - for _, a := range t { - tmplApplication := getTempApplication(a.Template) - - for _, p := range a.Params { - app, err := r.Renderer.RenderTemplateParams(tmplApplication, applicationSetInfo.Spec.SyncPolicy, p, applicationSetInfo.Spec.GoTemplate, applicationSetInfo.Spec.GoTemplateOptions) - if err != nil { - logCtx.WithError(err).WithField("params", a.Params).WithField("generator", requestedGenerator). - Error("error generating application from params") - - if firstError == nil { - firstError = err - applicationSetReason = argov1alpha1.ApplicationSetReasonRenderTemplateParamsError - } - continue - } - - if applicationSetInfo.Spec.TemplatePatch != nil { - patchedApplication, err := r.applyTemplatePatch(app, applicationSetInfo, p) - if err != nil { - log.WithError(err).WithField("params", a.Params).WithField("generator", requestedGenerator). - Error("error generating application from params") - - if firstError == nil { - firstError = err - applicationSetReason = argov1alpha1.ApplicationSetReasonRenderTemplateParamsError - } - continue - } - - app = patchedApplication - } - - res = append(res, *app) - } - } - - logCtx.WithField("generator", requestedGenerator).Infof("generated %d applications", len(res)) - logCtx.WithField("generator", requestedGenerator).Debugf("apps from generator: %+v", res) - } - - return res, applicationSetReason, firstError -} - -func (r *ApplicationSetReconciler) applyTemplatePatch(app *argov1alpha1.Application, applicationSetInfo argov1alpha1.ApplicationSet, params map[string]interface{}) (*argov1alpha1.Application, error) { - replacedTemplate, err := r.Renderer.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) - } - - return applyTemplatePatch(app, replacedTemplate) -} - func ignoreNotAllowedNamespaces(namespaces []string) predicate.Predicate { return predicate.Funcs{ CreateFunc: func(e event.CreateEvent) bool { - return glob.MatchStringInList(namespaces, e.Object.GetNamespace(), false) + return utils.IsNamespaceAllowed(namespaces, e.Object.GetNamespace()) }, } } @@ -623,25 +555,6 @@ func (r *ApplicationSetReconciler) SetupWithManager(mgr ctrl.Manager, enableProg Complete(r) } -func (r *ApplicationSetReconciler) updateCache(ctx context.Context, obj client.Object, logger *log.Entry) { - informer, err := r.Cache.GetInformer(ctx, obj) - if err != nil { - logger.Errorf("failed to get informer: %v", err) - return - } - // The controller runtime abstract away informers creation - // so unfortunately could not find any other way to access informer store. - k8sInformer, ok := informer.(k8scache.SharedInformer) - if !ok { - logger.Error("informer is not a kubernetes informer") - return - } - if err := k8sInformer.GetStore().Update(obj); err != nil { - logger.Errorf("failed to update cache: %v", err) - return - } -} - // createOrUpdateInCluster will create / update application resources in the cluster. // - For new applications, it will call create // - For existing application, it will call update @@ -650,10 +563,6 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context, var firstError error // Creates or updates the application in appList for _, generatedApp := range desiredApplications { - // The app's namespace must be the same as the AppSet's namespace to preserve the appsets-in-any-namespace - // security boundary. - generatedApp.Namespace = applicationSet.Namespace - appLog := logCtx.WithFields(log.Fields{"app": generatedApp.QualifiedName()}) // Normalize to avoid fighting with the application controller. @@ -743,7 +652,6 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context, } continue } - r.updateCache(ctx, found, appLog) if action != controllerutil.OperationResultNone { // Don't pollute etcd with "unchanged Application" events @@ -910,7 +818,6 @@ func (r *ApplicationSetReconciler) removeFinalizerOnInvalidDestination(ctx conte if err := r.Client.Patch(ctx, updated, patch); err != nil { return fmt.Errorf("error updating finalizers: %w", err) } - r.updateCache(ctx, updated, appLog) // Application must have updated list of finalizers updated.DeepCopyInto(app) @@ -925,14 +832,14 @@ func (r *ApplicationSetReconciler) removeFinalizerOnInvalidDestination(ctx conte func (r *ApplicationSetReconciler) removeOwnerReferencesOnDeleteAppSet(ctx context.Context, applicationSet argov1alpha1.ApplicationSet) error { applications, err := r.getCurrentApplications(ctx, applicationSet) if err != nil { - return err + return fmt.Errorf("error getting current applications for ApplicationSet: %w", err) } for _, app := range applications { app.SetOwnerReferences([]metav1.OwnerReference{}) err := r.Client.Update(ctx, &app) if err != nil { - return err + return fmt.Errorf("error updating application: %w", err) } } @@ -940,12 +847,9 @@ func (r *ApplicationSetReconciler) removeOwnerReferencesOnDeleteAppSet(ctx conte } func (r *ApplicationSetReconciler) performProgressiveSyncs(ctx context.Context, logCtx *log.Entry, appset argov1alpha1.ApplicationSet, applications []argov1alpha1.Application, desiredApplications []argov1alpha1.Application, appMap map[string]argov1alpha1.Application) (map[string]bool, error) { - appDependencyList, appStepMap, err := r.buildAppDependencyList(logCtx, appset, desiredApplications) - if err != nil { - return nil, fmt.Errorf("failed to build app dependency list: %w", err) - } + appDependencyList, appStepMap := r.buildAppDependencyList(logCtx, appset, desiredApplications) - _, err = r.updateApplicationSetApplicationStatus(ctx, logCtx, &appset, applications, appStepMap) + _, err := r.updateApplicationSetApplicationStatus(ctx, logCtx, &appset, applications, appStepMap) if err != nil { return nil, fmt.Errorf("failed to update applicationset app status: %w", err) } @@ -955,34 +859,27 @@ func (r *ApplicationSetReconciler) performProgressiveSyncs(ctx context.Context, logCtx.Infof("step %v: %+v", i+1, step) } - appSyncMap, err := r.buildAppSyncMap(ctx, appset, appDependencyList, appMap) - if err != nil { - return nil, fmt.Errorf("failed to build app sync map: %w", err) - } - + appSyncMap := r.buildAppSyncMap(appset, appDependencyList, appMap) logCtx.Infof("Application allowed to sync before maxUpdate?: %+v", appSyncMap) - _, err = r.updateApplicationSetApplicationStatusProgress(ctx, logCtx, &appset, appSyncMap, appStepMap, appMap) + _, err = r.updateApplicationSetApplicationStatusProgress(ctx, logCtx, &appset, appSyncMap, appStepMap) if err != nil { return nil, fmt.Errorf("failed to update applicationset application status progress: %w", err) } - _, err = r.updateApplicationSetApplicationStatusConditions(ctx, &appset) - if err != nil { - return nil, fmt.Errorf("failed to update applicationset application status conditions: %w", err) - } + _ = r.updateApplicationSetApplicationStatusConditions(ctx, &appset) return appSyncMap, nil } // this list tracks which Applications belong to each RollingUpdate step -func (r *ApplicationSetReconciler) buildAppDependencyList(logCtx *log.Entry, applicationSet argov1alpha1.ApplicationSet, applications []argov1alpha1.Application) ([][]string, map[string]int, error) { +func (r *ApplicationSetReconciler) buildAppDependencyList(logCtx *log.Entry, applicationSet argov1alpha1.ApplicationSet, applications []argov1alpha1.Application) ([][]string, map[string]int) { if applicationSet.Spec.Strategy == nil || applicationSet.Spec.Strategy.Type == "" || applicationSet.Spec.Strategy.Type == "AllAtOnce" { - return [][]string{}, map[string]int{}, nil + return [][]string{}, map[string]int{} } steps := []argov1alpha1.ApplicationSetRolloutStep{} - if progressiveSyncsStrategyEnabled(&applicationSet, "RollingSync") { + if progressiveSyncsRollingSyncStrategyEnabled(&applicationSet) { steps = applicationSet.Spec.Strategy.RollingSync.Steps } @@ -1023,7 +920,7 @@ func (r *ApplicationSetReconciler) buildAppDependencyList(logCtx *log.Entry, app } } - return appDependencyList, appStepMap, nil + return appDependencyList, appStepMap } func labelMatchedExpression(logCtx *log.Entry, val string, matchExpression argov1alpha1.ApplicationMatchExpression) bool { @@ -1047,7 +944,7 @@ func labelMatchedExpression(logCtx *log.Entry, val string, matchExpression argov } // this map is used to determine which stage of Applications are ready to be updated in the reconciler loop -func (r *ApplicationSetReconciler) buildAppSyncMap(ctx context.Context, applicationSet argov1alpha1.ApplicationSet, appDependencyList [][]string, appMap map[string]argov1alpha1.Application) (map[string]bool, error) { +func (r *ApplicationSetReconciler) buildAppSyncMap(applicationSet argov1alpha1.ApplicationSet, appDependencyList [][]string, appMap map[string]argov1alpha1.Application) map[string]bool { appSyncMap := map[string]bool{} syncEnabled := true @@ -1084,11 +981,11 @@ func (r *ApplicationSetReconciler) buildAppSyncMap(ctx context.Context, applicat } } - return appSyncMap, nil + return appSyncMap } func appSyncEnabledForNextStep(appset *argov1alpha1.ApplicationSet, app argov1alpha1.Application, appStatus argov1alpha1.ApplicationSetApplicationStatus) bool { - if progressiveSyncsStrategyEnabled(appset, "RollingSync") { + if progressiveSyncsRollingSyncStrategyEnabled(appset) { // we still need to complete the current step if the Application is not yet Healthy or there are still pending Application changes return isApplicationHealthy(app) && appStatus.Status == "Healthy" } @@ -1096,16 +993,8 @@ func appSyncEnabledForNextStep(appset *argov1alpha1.ApplicationSet, app argov1al return true } -func progressiveSyncsStrategyEnabled(appset *argov1alpha1.ApplicationSet, strategyType string) bool { - if appset.Spec.Strategy == nil || appset.Spec.Strategy.Type != strategyType { - return false - } - - if strategyType == "RollingSync" && appset.Spec.Strategy.RollingSync == nil { - return false - } - - return true +func progressiveSyncsRollingSyncStrategyEnabled(appset *argov1alpha1.ApplicationSet) bool { + return appset.Spec.Strategy != nil && appset.Spec.Strategy.RollingSync != nil && appset.Spec.Strategy.Type == "RollingSync" } func isApplicationHealthy(app argov1alpha1.Application) bool { @@ -1153,10 +1042,17 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con } else { // we have an existing AppStatus currentAppStatus = applicationSet.Status.ApplicationStatus[idx] + + // upgrade any existing AppStatus that might have been set by an older argo-cd version + // note: currentAppStatus.TargetRevisions may be set to empty list earlier during migrations, + // to prevent other usage of r.Client.Status().Update to fail before reaching here. + if len(currentAppStatus.TargetRevisions) == 0 { + currentAppStatus.TargetRevisions = app.Status.GetRevisions() + } } appOutdated := false - if progressiveSyncsStrategyEnabled(applicationSet, "RollingSync") { + if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) { appOutdated = syncStatusString == "OutOfSync" } @@ -1222,7 +1118,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con } // check Applications that are in Waiting status and promote them to Pending if needed -func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress(ctx context.Context, logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, appSyncMap map[string]bool, appStepMap map[string]int, appMap map[string]argov1alpha1.Application) ([]argov1alpha1.ApplicationSetApplicationStatus, error) { +func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress(ctx context.Context, logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, appSyncMap map[string]bool, appStepMap map[string]int) ([]argov1alpha1.ApplicationSetApplicationStatus, error) { now := metav1.Now() appStatuses := make([]argov1alpha1.ApplicationSetApplicationStatus, 0, len(applicationSet.Status.ApplicationStatus)) @@ -1233,7 +1129,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress totalCountMap := []int{} length := 0 - if progressiveSyncsStrategyEnabled(applicationSet, "RollingSync") { + if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) { length = len(applicationSet.Spec.Strategy.RollingSync.Steps) } for s := 0; s < length; s++ { @@ -1245,7 +1141,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress for _, appStatus := range applicationSet.Status.ApplicationStatus { totalCountMap[appStepMap[appStatus.Application]] += 1 - if progressiveSyncsStrategyEnabled(applicationSet, "RollingSync") { + if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) { if appStatus.Status == "Pending" || appStatus.Status == "Progressing" { updateCountMap[appStepMap[appStatus.Application]] += 1 } @@ -1255,7 +1151,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress for _, appStatus := range applicationSet.Status.ApplicationStatus { maxUpdateAllowed := true maxUpdate := &intstr.IntOrString{} - if progressiveSyncsStrategyEnabled(applicationSet, "RollingSync") { + if progressiveSyncsRollingSyncStrategyEnabled(applicationSet) { maxUpdate = applicationSet.Spec.Strategy.RollingSync.Steps[appStepMap[appStatus.Application]].MaxUpdate } @@ -1299,7 +1195,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress return appStatuses, nil } -func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusConditions(ctx context.Context, applicationSet *argov1alpha1.ApplicationSet) ([]argov1alpha1.ApplicationSetCondition, error) { +func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusConditions(ctx context.Context, applicationSet *argov1alpha1.ApplicationSet) []argov1alpha1.ApplicationSetCondition { appSetProgressing := false for _, appStatus := range applicationSet.Status.ApplicationStatus { if appStatus.Status != "Healthy" { @@ -1324,7 +1220,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusConditio Message: "ApplicationSet Rollout Rollout started", Reason: argov1alpha1.ApplicationSetReasonApplicationSetModified, Status: argov1alpha1.ApplicationSetConditionStatusTrue, - }, false, + }, true, ) } else if !appSetProgressing && appSetConditionProgressing { _ = r.setApplicationSetStatusCondition(ctx, @@ -1334,11 +1230,11 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusConditio Message: "ApplicationSet Rollout Rollout complete", Reason: argov1alpha1.ApplicationSetReasonApplicationSetRolloutComplete, Status: argov1alpha1.ApplicationSetConditionStatusFalse, - }, false, + }, true, ) } - return applicationSet.Status.Conditions, nil + return applicationSet.Status.Conditions } func findApplicationStatusIndex(appStatuses []argov1alpha1.ApplicationSetApplicationStatus, application string) int { @@ -1350,86 +1246,89 @@ func findApplicationStatusIndex(appStatuses []argov1alpha1.ApplicationSetApplica return -1 } -func (r *ApplicationSetReconciler) updateResourcesStatus(ctx context.Context, logCtx *log.Entry, appset *argov1alpha1.ApplicationSet, apps []argov1alpha1.Application) error { - statusMap := getResourceStatusMap(appset) - statusMap = buildResourceStatus(statusMap, apps) - - statuses := []argov1alpha1.ResourceStatus{} - for _, status := range statusMap { - statuses = append(statuses, status) +// migrateStatus run migrations on the status subresource of ApplicationSet early during the run of ApplicationSetReconciler.Reconcile +// this handles any defaulting of values - which would otherwise cause the references to r.Client.Status().Update to fail given missing required fields. +func (r *ApplicationSetReconciler) migrateStatus(ctx context.Context, appset *argov1alpha1.ApplicationSet) error { + update := false + if statusList := appset.Status.ApplicationStatus; statusList != nil { + for idx := range statusList { + if statusList[idx].TargetRevisions == nil { + statusList[idx].TargetRevisions = []string{} + update = true + } + } } - appset.Status.Resources = statuses - namespacedName := types.NamespacedName{Namespace: appset.Namespace, Name: appset.Name} - err := r.Client.Status().Update(ctx, appset) - if err != nil { - logCtx.Errorf("unable to set application set status: %v", err) - return fmt.Errorf("unable to set application set status: %w", err) - } + if update { + // DefaultRetry will retry 5 times with a backoff factor of 1, jitter of 0.1 and a duration of 10ms + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + namespacedName := types.NamespacedName{Namespace: appset.Namespace, Name: appset.Name} + updatedAppset := &argov1alpha1.ApplicationSet{} + if err := r.Get(ctx, namespacedName, updatedAppset); err != nil { + if client.IgnoreNotFound(err) != nil { + return nil + } + return fmt.Errorf("error fetching updated application set: %w", err) + } - if err := r.Get(ctx, namespacedName, appset); err != nil { - if client.IgnoreNotFound(err) != nil { + updatedAppset.Status.ApplicationStatus = appset.Status.ApplicationStatus + + // Update the newly fetched object with new set of ApplicationStatus + err := r.Client.Status().Update(ctx, updatedAppset) + if err != nil { + return err + } + updatedAppset.DeepCopyInto(appset) return nil + }) + if err != nil && !apierr.IsNotFound(err) { + return fmt.Errorf("unable to set application set condition: %w", err) } - return fmt.Errorf("error fetching updated application set: %w", err) } - return nil } -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() - // 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 = &appCopy.Status.Health +func (r *ApplicationSetReconciler) updateResourcesStatus(ctx context.Context, logCtx *log.Entry, appset *argov1alpha1.ApplicationSet, apps []argov1alpha1.Application) error { + statusMap := status.GetResourceStatusMap(appset) + statusMap = status.BuildResourceStatus(statusMap, apps) - statusMap[app.Name] = status + statuses := []argov1alpha1.ResourceStatus{} + for _, status := range statusMap { + statuses = append(statuses, status) } - cleanupDeletedApplicationStatuses(statusMap, appMap) - - return statusMap -} + sort.Slice(statuses, func(i, j int) bool { + return statuses[i].Name < statuses[j].Name + }) + appset.Status.Resources = statuses + // DefaultRetry will retry 5 times with a backoff factor of 1, jitter of 0.1 and a duration of 10ms + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + namespacedName := types.NamespacedName{Namespace: appset.Namespace, Name: appset.Name} + updatedAppset := &argov1alpha1.ApplicationSet{} + if err := r.Get(ctx, namespacedName, updatedAppset); err != nil { + if client.IgnoreNotFound(err) != nil { + return nil + } + return fmt.Errorf("error fetching updated application set: %w", err) + } -func getResourceStatusMap(appset *argov1alpha1.ApplicationSet) map[string]argov1alpha1.ResourceStatus { - statusMap := map[string]argov1alpha1.ResourceStatus{} - for _, status := range appset.Status.Resources { - statusMap[status.Name] = status - } - return statusMap -} + updatedAppset.Status.Resources = appset.Status.Resources -func cleanupDeletedApplicationStatuses(statusMap map[string]argov1alpha1.ResourceStatus, apps map[string]argov1alpha1.Application) { - for name := range statusMap { - if _, ok := apps[name]; !ok { - delete(statusMap, name) + // Update the newly fetched object with new status resources + err := r.Client.Status().Update(ctx, updatedAppset) + if err != nil { + return err } + updatedAppset.DeepCopyInto(appset) + return nil + }) + if err != nil { + logCtx.Errorf("unable to set application set status: %v", err) + return fmt.Errorf("unable to set application set status: %w", err) } + return nil } -// setApplicationSetApplicationStatus updates the ApplicationSet's status field +// setAppSetApplicationStatus updates the ApplicationSet's status field // with any new/changed Application statuses. func (r *ApplicationSetReconciler) setAppSetApplicationStatus(ctx context.Context, logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, applicationStatuses []argov1alpha1.ApplicationSetApplicationStatus) error { needToUpdateStatus := false @@ -1460,26 +1359,36 @@ func (r *ApplicationSetReconciler) setAppSetApplicationStatus(ctx context.Contex for i := range applicationStatuses { applicationSet.Status.SetApplicationStatus(applicationStatuses[i]) } + // DefaultRetry will retry 5 times with a backoff factor of 1, jitter of 0.1 and a duration of 10ms + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + updatedAppset := &argov1alpha1.ApplicationSet{} + if err := r.Get(ctx, namespacedName, updatedAppset); err != nil { + if client.IgnoreNotFound(err) != nil { + return nil + } + return fmt.Errorf("error fetching updated application set: %w", err) + } - // Update the newly fetched object with new set of ApplicationStatus - err := r.Client.Status().Update(ctx, applicationSet) + updatedAppset.Status.ApplicationStatus = applicationSet.Status.ApplicationStatus + + // Update the newly fetched object with new set of ApplicationStatus + err := r.Client.Status().Update(ctx, updatedAppset) + if err != nil { + return err + } + updatedAppset.DeepCopyInto(applicationSet) + return nil + }) if err != nil { logCtx.Errorf("unable to set application set status: %v", err) return fmt.Errorf("unable to set application set status: %w", err) } - - if err := r.Get(ctx, namespacedName, applicationSet); err != nil { - if client.IgnoreNotFound(err) != nil { - return nil - } - return fmt.Errorf("error fetching updated application set: %w", err) - } } return nil } -func (r *ApplicationSetReconciler) syncValidApplications(logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, appSyncMap map[string]bool, appMap map[string]argov1alpha1.Application, validApps []argov1alpha1.Application) ([]argov1alpha1.Application, error) { +func (r *ApplicationSetReconciler) syncValidApplications(logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, appSyncMap map[string]bool, appMap map[string]argov1alpha1.Application, validApps []argov1alpha1.Application) []argov1alpha1.Application { rolloutApps := []argov1alpha1.Application{} for i := range validApps { pruneEnabled := false @@ -1500,15 +1409,15 @@ func (r *ApplicationSetReconciler) syncValidApplications(logCtx *log.Entry, appl // check appSyncMap to determine which Applications are ready to be updated and which should be skipped if appSyncMap[validApps[i].Name] && appMap[validApps[i].Name].Status.Sync.Status == "OutOfSync" && appSetStatusPending { logCtx.Infof("triggering sync for application: %v, prune enabled: %v", validApps[i].Name, pruneEnabled) - validApps[i], _ = syncApplication(validApps[i], pruneEnabled) + validApps[i] = syncApplication(validApps[i], pruneEnabled) } rolloutApps = append(rolloutApps, validApps[i]) } - return rolloutApps, nil + return rolloutApps } // used by the RollingSync Progressive Sync strategy to trigger a sync of a particular Application resource -func syncApplication(application argov1alpha1.Application, prune bool) (argov1alpha1.Application, error) { +func syncApplication(application argov1alpha1.Application, prune bool) argov1alpha1.Application { operation := argov1alpha1.Operation{ InitiatedBy: argov1alpha1.OperationInitiator{ Username: "applicationset-controller", @@ -1534,7 +1443,7 @@ func syncApplication(application argov1alpha1.Application, prune bool) (argov1al } application.Operation = &operation - return application, nil + return application } func getOwnsHandlerPredicates(enableProgressiveSyncs bool) predicate.Funcs { diff --git a/applicationset/controllers/applicationset_controller_test.go b/applicationset/controllers/applicationset_controller_test.go index 33e27cb53ff5f..02608175245b4 100644 --- a/applicationset/controllers/applicationset_controller_test.go +++ b/applicationset/controllers/applicationset_controller_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "reflect" + "strconv" "strings" "testing" "time" @@ -12,6 +13,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "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" @@ -19,12 +21,8 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" kubefake "k8s.io/client-go/kubernetes/fake" - k8scache "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/cache" - crtcache "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client" crtclient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -34,332 +32,24 @@ import ( "github.com/argoproj/gitops-engine/pkg/sync/common" "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" "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/collections" dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" "github.com/argoproj/argo-cd/v2/pkg/apis/application" ) -type fakeStore struct { - k8scache.Store -} - -func (f *fakeStore) Update(obj interface{}) error { - return nil -} - -type fakeInformer struct { - k8scache.SharedInformer -} - -func (f *fakeInformer) AddIndexers(indexers k8scache.Indexers) error { - return nil -} - -func (f *fakeInformer) GetStore() k8scache.Store { - return &fakeStore{} -} - -type fakeCache struct { - cache.Cache -} - -func (f *fakeCache) GetInformer(ctx context.Context, obj crtclient.Object, opt ...crtcache.InformerGetOption) (cache.Informer, error) { - return &fakeInformer{}, nil -} - -type generatorMock struct { - mock.Mock -} - -func (g *generatorMock) GetTemplate(appSetGenerator *v1alpha1.ApplicationSetGenerator) *v1alpha1.ApplicationSetTemplate { - args := g.Called(appSetGenerator) - - return args.Get(0).(*v1alpha1.ApplicationSetTemplate) -} - -func (g *generatorMock) GenerateParams(appSetGenerator *v1alpha1.ApplicationSetGenerator, _ *v1alpha1.ApplicationSet, client client.Client) ([]map[string]interface{}, error) { - args := g.Called(appSetGenerator) - - return args.Get(0).([]map[string]interface{}), args.Error(1) -} - -func (g *generatorMock) Replace(tmpl string, replaceMap map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (string, error) { - args := g.Called(tmpl, replaceMap, useGoTemplate, goTemplateOptions) - - return args.Get(0).(string), args.Error(1) -} - -type rendererMock struct { - mock.Mock -} - -func (g *generatorMock) GetRequeueAfter(appSetGenerator *v1alpha1.ApplicationSetGenerator) time.Duration { - args := g.Called(appSetGenerator) - - return args.Get(0).(time.Duration) -} - -func (r *rendererMock) RenderTemplateParams(tmpl *v1alpha1.Application, syncPolicy *v1alpha1.ApplicationSetSyncPolicy, params map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (*v1alpha1.Application, error) { - args := r.Called(tmpl, params, useGoTemplate, goTemplateOptions) - - if args.Error(1) != nil { - return nil, args.Error(1) - } - - return args.Get(0).(*v1alpha1.Application), args.Error(1) -} - -func (r *rendererMock) Replace(tmpl string, replaceMap map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (string, error) { - args := r.Called(tmpl, replaceMap, useGoTemplate, goTemplateOptions) - - return args.Get(0).(string), args.Error(1) -} - -func TestExtractApplications(t *testing.T) { - scheme := runtime.NewScheme() - err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) - - for _, c := range []struct { - name string - params []map[string]interface{} - template v1alpha1.ApplicationSetTemplate - generateParamsError error - rendererError error - expectErr bool - expectedReason v1alpha1.ApplicationSetReasonType - }{ - { - name: "Generate two applications", - params: []map[string]interface{}{{"name": "app1"}, {"name": "app2"}}, - template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ - Name: "name", - Namespace: "namespace", - Labels: map[string]string{"label_name": "label_value"}, - }, - Spec: v1alpha1.ApplicationSpec{}, - }, - expectedReason: "", - }, - { - name: "Handles error from the generator", - generateParamsError: fmt.Errorf("error"), - expectErr: true, - expectedReason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, - }, - { - name: "Handles error from the render", - params: []map[string]interface{}{{"name": "app1"}, {"name": "app2"}}, - template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ - Name: "name", - Namespace: "namespace", - Labels: map[string]string{"label_name": "label_value"}, - }, - Spec: v1alpha1.ApplicationSpec{}, - }, - rendererError: fmt.Errorf("error"), - expectErr: true, - expectedReason: v1alpha1.ApplicationSetReasonRenderTemplateParamsError, - }, - } { - cc := c - app := v1alpha1.Application{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - }, - } - - t.Run(cc.name, func(t *testing.T) { - appSet := &v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "name", - Namespace: "namespace", - }, - } - - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(appSet).Build() - - generatorMock := generatorMock{} - generator := v1alpha1.ApplicationSetGenerator{ - List: &v1alpha1.ListGenerator{}, - } - - generatorMock.On("GenerateParams", &generator). - Return(cc.params, cc.generateParamsError) - - generatorMock.On("GetTemplate", &generator). - Return(&v1alpha1.ApplicationSetTemplate{}) - - rendererMock := rendererMock{} - - var expectedApps []v1alpha1.Application - - if cc.generateParamsError == nil { - for _, p := range cc.params { - if cc.rendererError != nil { - rendererMock.On("RenderTemplateParams", getTempApplication(cc.template), p, false, []string(nil)). - Return(nil, cc.rendererError) - } else { - rendererMock.On("RenderTemplateParams", getTempApplication(cc.template), p, false, []string(nil)). - Return(&app, nil) - expectedApps = append(expectedApps, app) - } - } - } - - r := ApplicationSetReconciler{ - Client: client, - Scheme: scheme, - Recorder: record.NewFakeRecorder(1), - Generators: map[string]generators.Generator{ - "List": &generatorMock, - }, - Renderer: &rendererMock, - KubeClientset: kubefake.NewSimpleClientset(), - Cache: &fakeCache{}, - } - - got, reason, err := r.generateApplications(log.NewEntry(log.StandardLogger()), v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "name", - Namespace: "namespace", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Generators: []v1alpha1.ApplicationSetGenerator{generator}, - Template: cc.template, - }, - }) - - if cc.expectErr { - assert.Error(t, err) - } else { - assert.NoError(t, err) - } - assert.Equal(t, expectedApps, got) - assert.Equal(t, cc.expectedReason, reason) - generatorMock.AssertNumberOfCalls(t, "GenerateParams", 1) - - if cc.generateParamsError == nil { - rendererMock.AssertNumberOfCalls(t, "RenderTemplateParams", len(cc.params)) - } - }) - } -} - -func TestMergeTemplateApplications(t *testing.T) { - scheme := runtime.NewScheme() - _ = v1alpha1.AddToScheme(scheme) - _ = v1alpha1.AddToScheme(scheme) - - client := fake.NewClientBuilder().WithScheme(scheme).Build() - - for _, c := range []struct { - name string - params []map[string]interface{} - template v1alpha1.ApplicationSetTemplate - overrideTemplate v1alpha1.ApplicationSetTemplate - expectedMerged v1alpha1.ApplicationSetTemplate - expectedApps []v1alpha1.Application - }{ - { - name: "Generate app", - params: []map[string]interface{}{{"name": "app1"}}, - template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ - Name: "name", - Namespace: "namespace", - Labels: map[string]string{"label_name": "label_value"}, - }, - Spec: v1alpha1.ApplicationSpec{}, - }, - overrideTemplate: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ - Name: "test", - Labels: map[string]string{"foo": "bar"}, - }, - Spec: v1alpha1.ApplicationSpec{}, - }, - expectedMerged: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ - Name: "test", - Namespace: "namespace", - Labels: map[string]string{"label_name": "label_value", "foo": "bar"}, - }, - Spec: v1alpha1.ApplicationSpec{}, - }, - expectedApps: []v1alpha1.Application{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - Namespace: "test", - Labels: map[string]string{"foo": "bar"}, - }, - Spec: v1alpha1.ApplicationSpec{}, - }, - }, - }, - } { - cc := c - - t.Run(cc.name, func(t *testing.T) { - generatorMock := generatorMock{} - generator := v1alpha1.ApplicationSetGenerator{ - List: &v1alpha1.ListGenerator{}, - } - - generatorMock.On("GenerateParams", &generator). - Return(cc.params, nil) - - generatorMock.On("GetTemplate", &generator). - Return(&cc.overrideTemplate) - - rendererMock := rendererMock{} - - rendererMock.On("RenderTemplateParams", getTempApplication(cc.expectedMerged), cc.params[0], false, []string(nil)). - Return(&cc.expectedApps[0], nil) - - r := ApplicationSetReconciler{ - Client: client, - Scheme: scheme, - Recorder: record.NewFakeRecorder(1), - Generators: map[string]generators.Generator{ - "List": &generatorMock, - }, - Renderer: &rendererMock, - KubeClientset: kubefake.NewSimpleClientset(), - } - - got, _, _ := r.generateApplications(log.NewEntry(log.StandardLogger()), v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "name", - Namespace: "namespace", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Generators: []v1alpha1.ApplicationSetGenerator{generator}, - Template: cc.template, - }, - }, - ) - - assert.Equal(t, cc.expectedApps, got) - }) - } -} - func TestCreateOrUpdateInCluster(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) for _, c := range []struct { // name is human-readable test name @@ -385,8 +75,10 @@ func TestCreateOrUpdateInCluster(t *testing.T) { desiredApps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app1", + Name: "app1", + Namespace: "namespace", }, + Spec: v1alpha1.ApplicationSpec{Project: "default"}, }, }, expected: []v1alpha1.Application{ @@ -438,7 +130,8 @@ func TestCreateOrUpdateInCluster(t *testing.T) { desiredApps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app1", + Name: "app1", + Namespace: "namespace", }, Spec: v1alpha1.ApplicationSpec{ Project: "project", @@ -496,7 +189,8 @@ func TestCreateOrUpdateInCluster(t *testing.T) { desiredApps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app2", + Name: "app2", + Namespace: "namespace", }, Spec: v1alpha1.ApplicationSpec{ Project: "project", @@ -555,6 +249,7 @@ func TestCreateOrUpdateInCluster(t *testing.T) { { ObjectMeta: metav1.ObjectMeta{ Name: "app1", + Namespace: "namespace", Labels: map[string]string{"label-key": "label-value"}, Annotations: map[string]string{"annot-key": "annot-value"}, }, @@ -618,7 +313,8 @@ func TestCreateOrUpdateInCluster(t *testing.T) { desiredApps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app1", + Name: "app1", + Namespace: "namespace", }, Spec: v1alpha1.ApplicationSpec{ Project: "project", @@ -684,7 +380,8 @@ func TestCreateOrUpdateInCluster(t *testing.T) { desiredApps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app1", + Name: "app1", + Namespace: "namespace", }, Spec: v1alpha1.ApplicationSpec{ Project: "project", @@ -757,6 +454,7 @@ func TestCreateOrUpdateInCluster(t *testing.T) { { ObjectMeta: metav1.ObjectMeta{ Name: "app1", + Namespace: "namespace", Labels: map[string]string{"label-key": "label-value"}, Annotations: map[string]string{"annot-key": "annot-value"}, }, @@ -834,7 +532,8 @@ func TestCreateOrUpdateInCluster(t *testing.T) { desiredApps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app1", + Name: "app1", + Namespace: "namespace", }, Spec: v1alpha1.ApplicationSpec{ Project: "project", @@ -903,7 +602,8 @@ func TestCreateOrUpdateInCluster(t *testing.T) { desiredApps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app1", + Name: "app1", + Namespace: "namespace", }, Spec: v1alpha1.ApplicationSpec{ Project: "project", @@ -953,7 +653,8 @@ func TestCreateOrUpdateInCluster(t *testing.T) { desiredApps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app1", + Name: "app1", + Namespace: "namespace", }, Spec: v1alpha1.ApplicationSpec{ Project: "project", @@ -1031,7 +732,8 @@ func TestCreateOrUpdateInCluster(t *testing.T) { desiredApps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app1", + Name: "app1", + Namespace: "namespace", }, Spec: v1alpha1.ApplicationSpec{ Project: "project", @@ -1134,7 +836,8 @@ func TestCreateOrUpdateInCluster(t *testing.T) { desiredApps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app1", + Name: "app1", + Namespace: "namespace", }, Spec: v1alpha1.ApplicationSpec{ Project: "project", @@ -1235,7 +938,8 @@ func TestCreateOrUpdateInCluster(t *testing.T) { desiredApps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app1", + Name: "app1", + Namespace: "namespace", }, Spec: v1alpha1.ApplicationSpec{ Project: "project", @@ -1316,7 +1020,8 @@ func TestCreateOrUpdateInCluster(t *testing.T) { desiredApps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app1", + Name: "app1", + Namespace: "namespace", }, Spec: v1alpha1.ApplicationSpec{ Project: "project", @@ -1350,21 +1055,22 @@ func TestCreateOrUpdateInCluster(t *testing.T) { for _, a := range c.existingApps { err = controllerutil.SetControllerReference(&c.appSet, &a, scheme) - assert.NoError(t, err) + require.NoError(t, err) initObjs = append(initObjs, &a) } client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(len(initObjs) + len(c.expected)), - Cache: &fakeCache{}, + Metrics: metrics, } err = r.createOrUpdateInCluster(context.TODO(), log.NewEntry(log.StandardLogger()), c.appSet, c.desiredApps) - assert.NoError(t, err) + require.NoError(t, err) for _, obj := range c.expected { got := &v1alpha1.Application{} @@ -1383,10 +1089,10 @@ func TestCreateOrUpdateInCluster(t *testing.T) { func TestRemoveFinalizerOnInvalidDestination_FinalizerTypes(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) for _, c := range []struct { // name is human-readable test name @@ -1465,30 +1171,31 @@ func TestRemoveFinalizerOnInvalidDestination_FinalizerTypes(t *testing.T) { objects := append([]runtime.Object{}, secret) kubeclientset := kubefake.NewSimpleClientset(objects...) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(10), KubeClientset: kubeclientset, - Cache: &fakeCache{}, + Metrics: metrics, } // 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") - assert.NoError(t, err, "Unexpected error") + require.NoError(t, err, "Unexpected error") appLog := log.WithFields(log.Fields{"app": app.Name, "appSet": ""}) appInputParam := app.DeepCopy() err = r.removeFinalizerOnInvalidDestination(context.Background(), appSet, appInputParam, clusterList, appLog) - assert.NoError(t, err, "Unexpected error") + require.NoError(t, err, "Unexpected error") retrievedApp := v1alpha1.Application{} err = client.Get(context.Background(), crtclient.ObjectKeyFromObject(&app), &retrievedApp) - assert.NoError(t, err, "Unexpected error") + require.NoError(t, err, "Unexpected error") // App on the cluster should have the expected finalizers assert.ElementsMatch(t, c.expectedFinalizers, retrievedApp.Finalizers) @@ -1505,10 +1212,10 @@ func TestRemoveFinalizerOnInvalidDestination_FinalizerTypes(t *testing.T) { func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) for _, c := range []struct { // name is human-readable test name @@ -1623,30 +1330,31 @@ func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) { objects := append([]runtime.Object{}, secret) kubeclientset := kubefake.NewSimpleClientset(objects...) + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(10), KubeClientset: kubeclientset, - Cache: &fakeCache{}, + Metrics: metrics, } // 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") - assert.NoError(t, err, "Unexpected error") + require.NoError(t, err, "Unexpected error") appLog := log.WithFields(log.Fields{"app": app.Name, "appSet": ""}) appInputParam := app.DeepCopy() err = r.removeFinalizerOnInvalidDestination(context.Background(), appSet, appInputParam, clusterList, appLog) - assert.NoError(t, err, "Unexpected error") + require.NoError(t, err, "Unexpected error") retrievedApp := v1alpha1.Application{} err = client.Get(context.Background(), crtclient.ObjectKeyFromObject(&app), &retrievedApp) - assert.NoError(t, err, "Unexpected error") + require.NoError(t, err, "Unexpected error") finalizerRemoved := len(retrievedApp.Finalizers) == 0 @@ -1661,10 +1369,10 @@ func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) { func TestRemoveOwnerReferencesOnDeleteAppSet(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) for _, c := range []struct { // name is human-readable test name @@ -1706,26 +1414,27 @@ func TestRemoveOwnerReferencesOnDeleteAppSet(t *testing.T) { } err := controllerutil.SetControllerReference(&appSet, &app, scheme) - assert.NoError(t, err, "Unexpected error") + require.NoError(t, err, "Unexpected error") initObjs := []crtclient.Object{&app, &appSet} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(10), KubeClientset: nil, - Cache: &fakeCache{}, + Metrics: metrics, } err = r.removeOwnerReferencesOnDeleteAppSet(context.Background(), appSet) - assert.NoError(t, err, "Unexpected error") + require.NoError(t, err, "Unexpected error") retrievedApp := v1alpha1.Application{} err = client.Get(context.Background(), crtclient.ObjectKeyFromObject(&app), &retrievedApp) - assert.NoError(t, err, "Unexpected error") + require.NoError(t, err, "Unexpected error") ownerReferencesRemoved := len(retrievedApp.OwnerReferences) == 0 assert.True(t, ownerReferencesRemoved) @@ -1736,10 +1445,10 @@ func TestRemoveOwnerReferencesOnDeleteAppSet(t *testing.T) { func TestCreateApplications(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) testCases := []struct { name string @@ -1760,7 +1469,8 @@ func TestCreateApplications(t *testing.T) { apps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app1", + Name: "app1", + Namespace: "namespace", }, }, }, @@ -1815,7 +1525,8 @@ func TestCreateApplications(t *testing.T) { apps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app1", + Name: "app1", + Namespace: "namespace", }, Spec: v1alpha1.ApplicationSpec{ Project: "project", @@ -1873,7 +1584,8 @@ func TestCreateApplications(t *testing.T) { apps: []v1alpha1.Application{ { ObjectMeta: metav1.ObjectMeta{ - Name: "app2", + Name: "app2", + Namespace: "namespace", }, Spec: v1alpha1.ApplicationSpec{ Project: "project", @@ -1904,21 +1616,22 @@ func TestCreateApplications(t *testing.T) { initObjs := []crtclient.Object{&c.appSet} for _, a := range c.existsApps { err = controllerutil.SetControllerReference(&c.appSet, &a, scheme) - assert.NoError(t, err) + require.NoError(t, err) initObjs = append(initObjs, &a) } client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(len(initObjs) + len(c.expected)), - Cache: &fakeCache{}, + Metrics: metrics, } err = r.createInCluster(context.TODO(), log.NewEntry(log.StandardLogger()), c.appSet, c.apps) - assert.NoError(t, err) + require.NoError(t, err) for _, obj := range c.expected { got := &v1alpha1.Application{} @@ -1928,7 +1641,7 @@ func TestCreateApplications(t *testing.T) { }, got) err = controllerutil.SetControllerReference(&c.appSet, &obj, r.Scheme) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, obj, *got) } @@ -1939,9 +1652,9 @@ func TestCreateApplications(t *testing.T) { func TestDeleteInCluster(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) for _, c := range []struct { // appSet is the application set on which the delete function is called @@ -2047,21 +1760,23 @@ func TestDeleteInCluster(t *testing.T) { for _, a := range c.existingApps { temp := a err = controllerutil.SetControllerReference(&c.appSet, &temp, scheme) - assert.NoError(t, err) + require.NoError(t, err) initObjs = append(initObjs, &temp) } client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(len(initObjs) + len(c.expected)), KubeClientset: kubefake.NewSimpleClientset(), + Metrics: metrics, } err = r.deleteInCluster(context.TODO(), log.NewEntry(log.StandardLogger()), c.appSet, c.desiredApps) - assert.NoError(t, err) + require.NoError(t, err) // For each of the expected objects, verify they exist on the cluster for _, obj := range c.expected { @@ -2072,7 +1787,7 @@ func TestDeleteInCluster(t *testing.T) { }, got) err = controllerutil.SetControllerReference(&c.appSet, &obj, r.Scheme) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, obj, *got) } @@ -2093,11 +1808,12 @@ func TestDeleteInCluster(t *testing.T) { func TestGetMinRequeueAfter(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) client := fake.NewClientBuilder().WithScheme(scheme).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) generator := v1alpha1.ApplicationSetGenerator{ List: &v1alpha1.ListGenerator{}, @@ -2105,15 +1821,15 @@ func TestGetMinRequeueAfter(t *testing.T) { Clusters: &v1alpha1.ClusterGenerator{}, } - generatorMock0 := generatorMock{} + generatorMock0 := mocks.Generator{} generatorMock0.On("GetRequeueAfter", &generator). Return(generators.NoRequeueAfter) - generatorMock1 := generatorMock{} + generatorMock1 := mocks.Generator{} generatorMock1.On("GetRequeueAfter", &generator). Return(time.Duration(1) * time.Second) - generatorMock10 := generatorMock{} + generatorMock10 := mocks.Generator{} generatorMock10.On("GetRequeueAfter", &generator). Return(time.Duration(10) * time.Second) @@ -2121,7 +1837,7 @@ func TestGetMinRequeueAfter(t *testing.T) { Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(0), - Cache: &fakeCache{}, + Metrics: metrics, Generators: map[string]generators.Generator{ "List": &generatorMock10, "Git": &generatorMock1, @@ -2138,15 +1854,70 @@ func TestGetMinRequeueAfter(t *testing.T) { assert.Equal(t, time.Duration(1)*time.Second, got) } +func TestRequeueGeneratorFails(t *testing.T) { + scheme := runtime.NewScheme() + err := v1alpha1.AddToScheme(scheme) + require.NoError(t, err) + err = v1alpha1.AddToScheme(scheme) + require.NoError(t, err) + + appSet := v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "argocd", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Generators: []v1alpha1.ApplicationSetGenerator{{ + PullRequest: &v1alpha1.PullRequestGenerator{}, + }}, + }, + } + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).Build() + + generator := v1alpha1.ApplicationSetGenerator{ + PullRequest: &v1alpha1.PullRequestGenerator{}, + } + + generatorMock := mocks.Generator{} + generatorMock.On("GetTemplate", &generator). + Return(&v1alpha1.ApplicationSetTemplate{}) + generatorMock.On("GenerateParams", &generator, mock.AnythingOfType("*v1alpha1.ApplicationSet"), mock.Anything). + Return([]map[string]interface{}{}, fmt.Errorf("Simulated error generating params that could be related to an external service/API call")) + + metrics := appsetmetrics.NewFakeAppsetMetrics(client) + + r := ApplicationSetReconciler{ + Client: client, + Scheme: scheme, + Recorder: record.NewFakeRecorder(0), + Generators: map[string]generators.Generator{ + "PullRequest": &generatorMock, + }, + Metrics: metrics, + } + + req := ctrl.Request{ + NamespacedName: types.NamespacedName{ + Namespace: "argocd", + Name: "name", + }, + } + + res, err := r.Reconcile(context.Background(), req) + require.Error(t, err) + assert.Equal(t, ReconcileRequeueOnValidationError, res.RequeueAfter) +} + func TestValidateGeneratedApplications(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) client := fake.NewClientBuilder().WithScheme(scheme).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) // Valid cluster myCluster := v1alpha1.Cluster{ @@ -2332,12 +2103,12 @@ func TestValidateGeneratedApplications(t *testing.T) { Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(1), - Cache: &fakeCache{}, Generators: map[string]generators.Generator{}, ArgoDB: &argoDBMock, ArgoCDNamespace: "namespace", ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), KubeClientset: kubeclientset, + Metrics: metrics, } appSetInfo := v1alpha1.ApplicationSet{} @@ -2378,9 +2149,9 @@ func TestValidateGeneratedApplications(t *testing.T) { func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) project := v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "good-project", Namespace: "argocd"}, @@ -2422,6 +2193,7 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) { argoObjs := []runtime.Object{&project} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"} badCluster := v1alpha1.Cluster{Server: "https://bad-cluster", Name: "bad-cluster"} argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil) @@ -2435,7 +2207,6 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) { Scheme: scheme, Renderer: &utils.Render{}, Recorder: record.NewFakeRecorder(1), - Cache: &fakeCache{}, Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, @@ -2444,6 +2215,7 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) { KubeClientset: kubeclientset, Policy: v1alpha1.ApplicationsSyncPolicySync, ArgoCDNamespace: "argocd", + Metrics: metrics, } req := ctrl.Request{ @@ -2455,168 +2227,209 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) { // Verify that on validation error, no error is returned, but the object is requeued res, err := r.Reconcile(context.Background(), req) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, ReconcileRequeueOnValidationError, res.RequeueAfter) var app v1alpha1.Application // make sure good app got created err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "good-project"}, &app) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "good-project", app.Name) // make sure bad app was not created err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "bad-project"}, &app) - assert.Error(t, err) + require.Error(t, err) } -func TestReconcilerCreateAppsRecoveringRenderError(t *testing.T) { +func TestSetApplicationSetStatusCondition(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) - project := v1alpha1.AppProject{ - ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "argocd"}, - } - appSet := v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "name", - Namespace: "argocd", - }, - Spec: v1alpha1.ApplicationSetSpec{ - GoTemplate: true, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - List: &v1alpha1.ListGenerator{ - Elements: []apiextensionsv1.JSON{{ - Raw: []byte(`{"name": "very-good-app"}`), - }, { - Raw: []byte(`{"name": "bad-app"}`), + testCases := []struct { + appset v1alpha1.ApplicationSet + conditions []v1alpha1.ApplicationSetCondition + testfunc func(t *testing.T, appset v1alpha1.ApplicationSet) + }{ + { + appset: v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "argocd", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Generators: []v1alpha1.ApplicationSetGenerator{ + {List: &v1alpha1.ListGenerator{ + Elements: []apiextensionsv1.JSON{{ + Raw: []byte(`{"cluster": "my-cluster","url": "https://kubernetes.default.svc"}`), + }}, }}, }, + Template: v1alpha1.ApplicationSetTemplate{}, }, }, - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ - Name: "{{ index (splitList \"-\" .name ) 2 }}", + conditions: []v1alpha1.ApplicationSetCondition{ + { + Type: v1alpha1.ApplicationSetConditionResourcesUpToDate, + Message: "All applications have been generated successfully", + Reason: v1alpha1.ApplicationSetReasonApplicationSetUpToDate, + Status: v1alpha1.ApplicationSetConditionStatusTrue, + }, + }, + testfunc: func(t *testing.T, appset v1alpha1.ApplicationSet) { + assert.Len(t, appset.Status.Conditions, 3) + }, + }, + { + appset: v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", Namespace: "argocd", }, - Spec: v1alpha1.ApplicationSpec{ - Source: &v1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argocd-example-apps", Path: "guestbook"}, - Project: "default", - Destination: v1alpha1.ApplicationDestination{Server: "https://kubernetes.default.svc"}, + Spec: v1alpha1.ApplicationSetSpec{ + Generators: []v1alpha1.ApplicationSetGenerator{ + {List: &v1alpha1.ListGenerator{ + Elements: []apiextensionsv1.JSON{{ + Raw: []byte(`{"cluster": "my-cluster","url": "https://kubernetes.default.svc"}`), + }}, + }}, + }, + Template: v1alpha1.ApplicationSetTemplate{}, }, }, - }, - } - - kubeclientset := kubefake.NewSimpleClientset() - argoDBMock := dbmocks.ArgoDB{} - argoObjs := []runtime.Object{&project} + conditions: []v1alpha1.ApplicationSetCondition{ + { + Type: v1alpha1.ApplicationSetConditionResourcesUpToDate, + Message: "All applications have been generated successfully", + Reason: v1alpha1.ApplicationSetReasonApplicationSetUpToDate, + Status: v1alpha1.ApplicationSetConditionStatusTrue, + }, + { + Type: v1alpha1.ApplicationSetConditionRolloutProgressing, + Message: "ApplicationSet Rollout Rollout started", + Reason: v1alpha1.ApplicationSetReasonApplicationSetUpToDate, + Status: v1alpha1.ApplicationSetConditionStatusTrue, + }, + }, + testfunc: func(t *testing.T, appset v1alpha1.ApplicationSet) { + assert.Len(t, appset.Status.Conditions, 3) - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + isProgressingCondition := false - r := ApplicationSetReconciler{ - Client: client, - Scheme: scheme, - Renderer: &utils.Render{}, - Recorder: record.NewFakeRecorder(1), - Cache: &fakeCache{}, - Generators: map[string]generators.Generator{ - "List": generators.NewListGenerator(), - }, - ArgoDB: &argoDBMock, - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), - KubeClientset: kubeclientset, - Policy: v1alpha1.ApplicationsSyncPolicySync, - ArgoCDNamespace: "argocd", - } + for _, condition := range appset.Status.Conditions { + if condition.Type == v1alpha1.ApplicationSetConditionRolloutProgressing { + isProgressingCondition = true + break + } + } - req := ctrl.Request{ - NamespacedName: types.NamespacedName{ - Namespace: "argocd", - Name: "name", + assert.False(t, isProgressingCondition, "no RolloutProgressing should be set for applicationsets that don't have rolling strategy") + }, }, - } - - // Verify that on generatorsError, no error is returned, but the object is requeued - res, err := r.Reconcile(context.Background(), req) - assert.NoError(t, err) - assert.Equal(t, ReconcileRequeueOnValidationError, res.RequeueAfter) - - var app v1alpha1.Application + { + appset: v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "argocd", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Generators: []v1alpha1.ApplicationSetGenerator{ + {List: &v1alpha1.ListGenerator{ + Elements: []apiextensionsv1.JSON{{ + Raw: []byte(`{"cluster": "my-cluster","url": "https://kubernetes.default.svc"}`), + }}, + }}, + }, + Template: v1alpha1.ApplicationSetTemplate{}, + Strategy: &v1alpha1.ApplicationSetStrategy{ + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{ + Steps: []v1alpha1.ApplicationSetRolloutStep{ + { + MatchExpressions: []v1alpha1.ApplicationMatchExpression{ + { + Key: "test", + Operator: "In", + Values: []string{"test"}, + }, + }, + }, + }, + }, + }, + }, + }, + conditions: []v1alpha1.ApplicationSetCondition{ + { + Type: v1alpha1.ApplicationSetConditionResourcesUpToDate, + Message: "All applications have been generated successfully", + Reason: v1alpha1.ApplicationSetReasonApplicationSetUpToDate, + Status: v1alpha1.ApplicationSetConditionStatusTrue, + }, + { + Type: v1alpha1.ApplicationSetConditionRolloutProgressing, + Message: "ApplicationSet Rollout Rollout started", + Reason: v1alpha1.ApplicationSetReasonApplicationSetUpToDate, + Status: v1alpha1.ApplicationSetConditionStatusTrue, + }, + }, + testfunc: func(t *testing.T, appset v1alpha1.ApplicationSet) { + assert.Len(t, appset.Status.Conditions, 4) - // make sure good app got created - err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "app"}, &app) - assert.NoError(t, err) - assert.Equal(t, "app", app.Name) -} + isProgressingCondition := false -func TestSetApplicationSetStatusCondition(t *testing.T) { - scheme := runtime.NewScheme() - err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) - err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + for _, condition := range appset.Status.Conditions { + if condition.Type == v1alpha1.ApplicationSetConditionRolloutProgressing { + isProgressingCondition = true + break + } + } - appSet := v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "name", - Namespace: "argocd", - }, - Spec: v1alpha1.ApplicationSetSpec{ - Generators: []v1alpha1.ApplicationSetGenerator{ - {List: &v1alpha1.ListGenerator{ - Elements: []apiextensionsv1.JSON{{ - Raw: []byte(`{"cluster": "my-cluster","url": "https://kubernetes.default.svc"}`), - }}, - }}, + assert.True(t, isProgressingCondition, "RolloutProgressing should be set for rollout strategy appset") }, - Template: v1alpha1.ApplicationSetTemplate{}, }, } - appCondition := v1alpha1.ApplicationSetCondition{ - Type: v1alpha1.ApplicationSetConditionResourcesUpToDate, - Message: "All applications have been generated successfully", - Reason: v1alpha1.ApplicationSetReasonApplicationSetUpToDate, - Status: v1alpha1.ApplicationSetConditionStatusTrue, - } - kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) argoDBMock := dbmocks.ArgoDB{} argoObjs := []runtime.Object{} - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + 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(client) - r := ApplicationSetReconciler{ - Client: client, - Scheme: scheme, - Renderer: &utils.Render{}, - Recorder: record.NewFakeRecorder(1), - Cache: &fakeCache{}, - Generators: map[string]generators.Generator{ - "List": generators.NewListGenerator(), - }, - ArgoDB: &argoDBMock, - ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), - KubeClientset: kubeclientset, - } + r := ApplicationSetReconciler{ + Client: client, + Scheme: scheme, + Renderer: &utils.Render{}, + Recorder: record.NewFakeRecorder(1), + Generators: map[string]generators.Generator{ + "List": generators.NewListGenerator(), + }, + ArgoDB: &argoDBMock, + ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), + KubeClientset: kubeclientset, + Metrics: metrics, + } - err = r.setApplicationSetStatusCondition(context.TODO(), &appSet, appCondition, true) - assert.NoError(t, err) + for _, condition := range testCase.conditions { + err = r.setApplicationSetStatusCondition(context.TODO(), &testCase.appset, condition, true) + require.NoError(t, err) + } - assert.Len(t, appSet.Status.Conditions, 3) + testCase.testfunc(t, testCase.appset) + } } func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alpha1.ApplicationsSyncPolicy, recordBuffer int, allowPolicyOverride bool) v1alpha1.Application { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) defaultProject := v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "argocd"}, @@ -2659,6 +2472,7 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp argoObjs := []runtime.Object{&defaultProject} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"} argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil) argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{ @@ -2670,7 +2484,6 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp Scheme: scheme, Renderer: &utils.Render{}, Recorder: record.NewFakeRecorder(recordBuffer), - Cache: &fakeCache{}, Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, @@ -2680,6 +2493,7 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp KubeClientset: kubeclientset, Policy: v1alpha1.ApplicationsSyncPolicySync, EnablePolicyOverride: allowPolicyOverride, + Metrics: metrics, } req := ctrl.Request{ @@ -2691,20 +2505,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(context.Background(), req) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, time.Duration(0), resCreate.RequeueAfter) var app v1alpha1.Application // make sure good app got created err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "good-cluster"}, &app) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "good-cluster", app.Name) // Update resource var retrievedApplicationSet v1alpha1.ApplicationSet err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "name"}, &retrievedApplicationSet) - assert.NoError(t, err) + require.NoError(t, err) retrievedApplicationSet.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} retrievedApplicationSet.Spec.Template.Labels = map[string]string{"label-key": "label-value"} @@ -2714,13 +2528,13 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp } err = r.Client.Update(context.TODO(), &retrievedApplicationSet) - assert.NoError(t, err) + require.NoError(t, err) resUpdate, err := r.Reconcile(context.Background(), req) - assert.NoError(t, err) + require.NoError(t, err) err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "good-cluster"}, &app) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, time.Duration(0), resUpdate.RequeueAfter) assert.Equal(t, "good-cluster", app.Name) @@ -2778,9 +2592,9 @@ func TestUpdatePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *t func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alpha1.ApplicationsSyncPolicy, recordBuffer int, allowPolicyOverride bool) v1alpha1.ApplicationList { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) defaultProject := v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "argocd"}, @@ -2823,6 +2637,7 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp argoObjs := []runtime.Object{&defaultProject} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"} argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil) argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{ @@ -2834,7 +2649,6 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp Scheme: scheme, Renderer: &utils.Render{}, Recorder: record.NewFakeRecorder(recordBuffer), - Cache: &fakeCache{}, Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, @@ -2844,6 +2658,7 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp KubeClientset: kubeclientset, Policy: v1alpha1.ApplicationsSyncPolicySync, EnablePolicyOverride: allowPolicyOverride, + Metrics: metrics, } req := ctrl.Request{ @@ -2855,20 +2670,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(context.Background(), req) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, time.Duration(0), resCreate.RequeueAfter) var app v1alpha1.Application // make sure good app got created err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "good-cluster"}, &app) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "good-cluster", app.Name) // Update resource var retrievedApplicationSet v1alpha1.ApplicationSet err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "name"}, &retrievedApplicationSet) - assert.NoError(t, err) + require.NoError(t, err) retrievedApplicationSet.Spec.Generators = []v1alpha1.ApplicationSetGenerator{ { List: &v1alpha1.ListGenerator{ @@ -2878,15 +2693,15 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp } err = r.Client.Update(context.TODO(), &retrievedApplicationSet) - assert.NoError(t, err) + require.NoError(t, err) resUpdate, err := r.Reconcile(context.Background(), req) - assert.NoError(t, err) + require.NoError(t, err) var apps v1alpha1.ApplicationList err = r.Client.List(context.TODO(), &apps) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, time.Duration(0), resUpdate.RequeueAfter) return apps @@ -2906,153 +2721,39 @@ func TestDeleteNotPerformedWithSyncPolicyCreateUpdate(t *testing.T) { apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 2, true) assert.Equal(t, "good-cluster", apps.Items[0].Name) -} - -func TestDeletePerformedWithSyncPolicyCreateDelete(t *testing.T) { - applicationsSyncPolicy := v1alpha1.ApplicationsSyncPolicyCreateDelete - - apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, true) - - assert.Empty(t, apps.Items) -} - -func TestDeletePerformedWithSyncPolicySync(t *testing.T) { - applicationsSyncPolicy := v1alpha1.ApplicationsSyncPolicySync - - apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, true) - - assert.Empty(t, apps.Items) -} - -func TestDeletePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *testing.T) { - applicationsSyncPolicy := v1alpha1.ApplicationsSyncPolicyCreateOnly - - apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, false) - - assert.Empty(t, apps.Items) -} - -// Test app generation from a go template application set using a pull request generator -func TestGenerateAppsUsingPullRequestGenerator(t *testing.T) { - scheme := runtime.NewScheme() - client := fake.NewClientBuilder().WithScheme(scheme).Build() - - for _, cases := range []struct { - name string - 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]interface{}{ - { - "number": "1", - "branch": "branch1", - "branch_slug": "branchSlug1", - "head_sha": "089d92cbf9ff857a39e6feccd32798ca700fb958", - "head_short_sha": "089d92cb", - "branch_slugify_default": "feat/a_really+long_pull_request_name_to_test_argo_slugification_and_branch_name_shortening_feature", - "branch_slugify_smarttruncate_disabled": "feat/areallylongpullrequestnametotestargoslugificationandbranchnameshorteningfeature", - "branch_slugify_smarttruncate_enabled": "feat/testwithsmarttruncateenabledramdomlonglistofcharacters", - "labels": []string{"label1"}, - }, - }, - template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ - Name: "AppSet-{{.branch}}-{{.number}}", - Labels: map[string]string{ - "app1": "{{index .labels 0}}", - "branch-test1": "AppSet-{{.branch_slugify_default | slugify }}", - "branch-test2": "AppSet-{{.branch_slugify_smarttruncate_disabled | slugify 49 false }}", - "branch-test3": "AppSet-{{.branch_slugify_smarttruncate_enabled | slugify 50 true }}", - }, - }, - Spec: v1alpha1.ApplicationSpec{ - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://testurl/testRepo", - TargetRevision: "{{.head_short_sha}}", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "AppSet-{{.branch_slug}}-{{.head_sha}}", - }, - }, - }, - expectedApp: []v1alpha1.Application{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "AppSet-branch1-1", - Labels: map[string]string{ - "app1": "label1", - "branch-test1": "AppSet-feat-a-really-long-pull-request-name-to-test-argo", - "branch-test2": "AppSet-feat-areallylongpullrequestnametotestargoslugific", - "branch-test3": "AppSet-feat", - }, - }, - Spec: v1alpha1.ApplicationSpec{ - Source: &v1alpha1.ApplicationSource{ - RepoURL: "https://testurl/testRepo", - TargetRevision: "089d92cb", - }, - Destination: v1alpha1.ApplicationDestination{ - Server: "https://kubernetes.default.svc", - Namespace: "AppSet-branchSlug1-089d92cbf9ff857a39e6feccd32798ca700fb958", - }, - }, - }, - }, - }, - } { - t.Run(cases.name, func(t *testing.T) { - generatorMock := generatorMock{} - generator := v1alpha1.ApplicationSetGenerator{ - PullRequest: &v1alpha1.PullRequestGenerator{}, - } +} - generatorMock.On("GenerateParams", &generator). - Return(cases.params, nil) +func TestDeletePerformedWithSyncPolicyCreateDelete(t *testing.T) { + applicationsSyncPolicy := v1alpha1.ApplicationsSyncPolicyCreateDelete - generatorMock.On("GetTemplate", &generator). - Return(&cases.template, nil) + apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, true) - appSetReconciler := ApplicationSetReconciler{ - Client: client, - Scheme: scheme, - Recorder: record.NewFakeRecorder(1), - Cache: &fakeCache{}, - Generators: map[string]generators.Generator{ - "PullRequest": &generatorMock, - }, - Renderer: &utils.Render{}, - KubeClientset: kubefake.NewSimpleClientset(), - } + assert.Empty(t, apps.Items) +} - gotApp, _, _ := appSetReconciler.generateApplications(log.NewEntry(log.StandardLogger()), v1alpha1.ApplicationSet{ - Spec: v1alpha1.ApplicationSetSpec{ - GoTemplate: true, - Generators: []v1alpha1.ApplicationSetGenerator{{ - PullRequest: &v1alpha1.PullRequestGenerator{}, - }}, - Template: cases.template, - }, - }, - ) - assert.EqualValues(t, cases.expectedApp[0].ObjectMeta.Name, gotApp[0].ObjectMeta.Name) - assert.EqualValues(t, cases.expectedApp[0].Spec.Source.TargetRevision, gotApp[0].Spec.Source.TargetRevision) - assert.EqualValues(t, cases.expectedApp[0].Spec.Destination.Namespace, gotApp[0].Spec.Destination.Namespace) - assert.True(t, collections.StringMapsEqual(cases.expectedApp[0].ObjectMeta.Labels, gotApp[0].ObjectMeta.Labels)) - }) - } +func TestDeletePerformedWithSyncPolicySync(t *testing.T) { + applicationsSyncPolicy := v1alpha1.ApplicationsSyncPolicySync + + apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, true) + + assert.Empty(t, apps.Items) +} + +func TestDeletePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *testing.T) { + applicationsSyncPolicy := v1alpha1.ApplicationsSyncPolicyCreateOnly + + apps := applicationsDeleteSyncPolicyTest(t, applicationsSyncPolicy, 3, false) + + assert.Empty(t, apps.Items) } func TestPolicies(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) defaultProject := v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "argocd"}, @@ -3139,13 +2840,13 @@ func TestPolicies(t *testing.T) { } client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithStatusSubresource(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Renderer: &utils.Render{}, Recorder: record.NewFakeRecorder(10), - Cache: &fakeCache{}, Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, @@ -3154,6 +2855,7 @@ func TestPolicies(t *testing.T) { ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), KubeClientset: kubeclientset, Policy: policy, + Metrics: metrics, } req := ctrl.Request{ @@ -3165,25 +2867,25 @@ func TestPolicies(t *testing.T) { // Check if Application is created res, err := r.Reconcile(context.Background(), req) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, time.Duration(0), res.RequeueAfter) var app v1alpha1.Application err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "my-app"}, &app) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "value", app.Annotations["key"]) // Check if Application is updated app.Annotations["key"] = "edited" err = r.Client.Update(context.TODO(), &app) - assert.NoError(t, err) + require.NoError(t, err) res, err = r.Reconcile(context.Background(), req) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, time.Duration(0), res.RequeueAfter) err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "my-app"}, &app) - assert.NoError(t, err) + require.NoError(t, err) if c.allowedUpdate { assert.Equal(t, "value", app.Annotations["key"]) @@ -3193,21 +2895,21 @@ func TestPolicies(t *testing.T) { // Check if Application is deleted err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "name"}, &appSet) - assert.NoError(t, err) + require.NoError(t, err) appSet.Spec.Generators[0] = v1alpha1.ApplicationSetGenerator{ List: &v1alpha1.ListGenerator{ Elements: []apiextensionsv1.JSON{}, }, } err = r.Client.Update(context.TODO(), &appSet) - assert.NoError(t, err) + require.NoError(t, err) res, err = r.Reconcile(context.Background(), req) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, time.Duration(0), res.RequeueAfter) err = r.Client.Get(context.TODO(), crtclient.ObjectKey{Namespace: "argocd", Name: "my-app"}, &app) - assert.NoError(t, err) + require.NoError(t, err) if c.allowedDelete { assert.NotNil(t, app.DeletionTimestamp) } else { @@ -3220,9 +2922,9 @@ func TestPolicies(t *testing.T) { func TestSetApplicationSetApplicationStatus(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) argoDBMock := dbmocks.ArgoDB{} @@ -3300,23 +3002,24 @@ 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(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Renderer: &utils.Render{}, Recorder: record.NewFakeRecorder(1), - Cache: &fakeCache{}, Generators: map[string]generators.Generator{ "List": generators.NewListGenerator(), }, ArgoDB: &argoDBMock, ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), KubeClientset: kubeclientset, + Metrics: metrics, } err = r.setAppSetApplicationStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appStatuses) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, cc.expectedAppStatuses, cc.appSet.Status.ApplicationStatus) }) @@ -3326,12 +3029,13 @@ func TestSetApplicationSetApplicationStatus(t *testing.T) { func TestBuildAppDependencyList(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) client := fake.NewClientBuilder().WithScheme(scheme).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) for _, cc := range []struct { name string @@ -4068,15 +3772,14 @@ func TestBuildAppDependencyList(t *testing.T) { Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(1), - Cache: &fakeCache{}, Generators: map[string]generators.Generator{}, ArgoDB: &argoDBMock, ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), KubeClientset: kubeclientset, + Metrics: metrics, } - appDependencyList, appStepMap, err := r.buildAppDependencyList(log.NewEntry(log.StandardLogger()), cc.appSet, cc.apps) - assert.NoError(t, err, "expected no errors, but errors occurred") + appDependencyList, appStepMap := r.buildAppDependencyList(log.NewEntry(log.StandardLogger()), cc.appSet, cc.apps) assert.Equal(t, cc.expectedList, appDependencyList, "expected appDependencyList did not match actual") assert.Equal(t, cc.expectedStepMap, appStepMap, "expected appStepMap did not match actual") }) @@ -4086,12 +3789,13 @@ func TestBuildAppDependencyList(t *testing.T) { func TestBuildAppSyncMap(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) client := fake.NewClientBuilder().WithScheme(scheme).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) for _, cc := range []struct { name string @@ -4659,15 +4363,14 @@ func TestBuildAppSyncMap(t *testing.T) { Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(1), - Cache: &fakeCache{}, Generators: map[string]generators.Generator{}, ArgoDB: &argoDBMock, ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), KubeClientset: kubeclientset, + Metrics: metrics, } - appSyncMap, err := r.buildAppSyncMap(context.TODO(), cc.appSet, cc.appDependencyList, cc.appMap) - assert.NoError(t, err, "expected no errors, but errors occurred") + appSyncMap := r.buildAppSyncMap(cc.appSet, cc.appDependencyList, cc.appMap) assert.Equal(t, cc.expectedMap, appSyncMap, "expected appSyncMap did not match actual") }) } @@ -4676,10 +4379,10 @@ func TestBuildAppSyncMap(t *testing.T) { func TestUpdateApplicationSetApplicationStatus(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) for _, cc := range []struct { name string @@ -4790,6 +4493,58 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, }, }, + { + name: "handles an outdated list of statuses with a healthy application, setting required variables", + appSet: v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "argocd", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Strategy: &v1alpha1.ApplicationSetStrategy{ + Type: "RollingSync", + RollingSync: &v1alpha1.ApplicationSetRolloutStrategy{}, + }, + }, + Status: v1alpha1.ApplicationSetStatus{ + ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{ + { + Application: "app1", + Message: "Application resource is already Healthy, updating status from Waiting to Healthy.", + Status: "Healthy", + Step: "1", + }, + }, + }, + }, + apps: []v1alpha1.Application{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "app1", + }, + Status: v1alpha1.ApplicationStatus{ + Health: v1alpha1.HealthStatus{ + Status: health.HealthStatusHealthy, + }, + OperationState: &v1alpha1.OperationState{ + Phase: common.OperationSucceeded, + }, + Sync: v1alpha1.SyncStatus{ + Status: v1alpha1.SyncStatusCodeSynced, + }, + }, + }, + }, + expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ + { + Application: "app1", + Message: "Application resource is already Healthy, updating status from Waiting to Healthy.", + Status: "Healthy", + Step: "1", + TargetRevisions: []string{}, + }, + }, + }, { name: "progresses an OutOfSync RollingSync application to waiting", appSet: v1alpha1.ApplicationSet{ @@ -4879,10 +4634,11 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Status: v1alpha1.ApplicationSetStatus{ ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{ { - Application: "app1", - Message: "", - Status: "Pending", - Step: "1", + Application: "app1", + Message: "", + Status: "Pending", + Step: "1", + TargetRevisions: []string{"Next"}, }, }, }, @@ -4901,15 +4657,16 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { - Application: "app1", - Message: "Application resource became Progressing, updating status from Pending to Progressing.", - Status: "Progressing", - Step: "1", + Application: "app1", + Message: "Application resource became Progressing, updating status from Pending to Progressing.", + Status: "Progressing", + Step: "1", + TargetRevisions: []string{"Next"}, }, }, }, { - name: "progresses a pending syncing application to progressing", + name: "progresses a pending synced application to progressing", appSet: v1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "name", @@ -4924,10 +4681,11 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Status: v1alpha1.ApplicationSetStatus{ ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{ { - Application: "app1", - Message: "", - Status: "Pending", - Step: "1", + Application: "app1", + Message: "", + Status: "Pending", + Step: "1", + TargetRevisions: []string{"Current"}, }, }, }, @@ -4952,10 +4710,11 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { - Application: "app1", - Message: "Application resource became Progressing, updating status from Pending to Progressing.", - Status: "Progressing", - Step: "1", + Application: "app1", + Message: "Application resource became Progressing, updating status from Pending to Progressing.", + Status: "Progressing", + Step: "1", + TargetRevisions: []string{"Current"}, }, }, }, @@ -4975,10 +4734,11 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Status: v1alpha1.ApplicationSetStatus{ ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{ { - Application: "app1", - Message: "", - Status: "Progressing", - Step: "1", + Application: "app1", + Message: "", + Status: "Progressing", + Step: "1", + TargetRevisions: []string{"Next"}, }, }, }, @@ -5003,10 +4763,11 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { - Application: "app1", - Message: "Application resource became Healthy, updating status from Progressing to Healthy.", - Status: "Healthy", - Step: "1", + Application: "app1", + Message: "Application resource became Healthy, updating status from Progressing to Healthy.", + Status: "Healthy", + Step: "1", + TargetRevisions: []string{"Next"}, }, }, }, @@ -5026,10 +4787,11 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Status: v1alpha1.ApplicationSetStatus{ ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{ { - Application: "app1", - Message: "", - Status: "Waiting", - Step: "1", + Application: "app1", + Message: "", + Status: "Waiting", + Step: "1", + TargetRevisions: []string{"Current"}, }, }, }, @@ -5054,10 +4816,11 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { - Application: "app1", - Message: "Application resource is already Healthy, updating status from Waiting to Healthy.", - Status: "Healthy", - Step: "1", + Application: "app1", + Message: "Application resource is already Healthy, updating status from Waiting to Healthy.", + Status: "Healthy", + Step: "1", + TargetRevisions: []string{"Current"}, }, }, }, @@ -5333,16 +5096,18 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { Status: v1alpha1.ApplicationSetStatus{ ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{ { - Application: "app1", - Message: "Application has pending changes, setting status to Waiting.", - Status: "Waiting", - Step: "1", + Application: "app1", + Message: "Application has pending changes, setting status to Waiting.", + Status: "Waiting", + Step: "1", + TargetRevisions: []string{"Current"}, }, { - Application: "app2", - Message: "Application has pending changes, setting status to Waiting.", - Status: "Waiting", - Step: "1", + Application: "app2", + Message: "Application has pending changes, setting status to Waiting.", + Status: "Waiting", + Step: "1", + TargetRevisions: []string{"Current"}, }, }, }, @@ -5367,10 +5132,11 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { }, expectedAppStatus: []v1alpha1.ApplicationSetApplicationStatus{ { - Application: "app1", - Message: "Application resource is already Healthy, updating status from Waiting to Healthy.", - Status: "Healthy", - Step: "1", + Application: "app1", + Message: "Application resource is already Healthy, updating status from Waiting to Healthy.", + Status: "Healthy", + Step: "1", + TargetRevisions: []string{"Current"}, }, }, }, @@ -5381,16 +5147,17 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { argoObjs := []runtime.Object{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&cc.appSet).WithStatusSubresource(&cc.appSet).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(1), - Cache: &fakeCache{}, Generators: map[string]generators.Generator{}, ArgoDB: &argoDBMock, ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), KubeClientset: kubeclientset, + Metrics: metrics, } appStatuses, err := r.updateApplicationSetApplicationStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps, cc.appStepMap) @@ -5400,7 +5167,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { appStatuses[i].LastTransitionTime = nil } - assert.NoError(t, err, "expected no errors, but errors occurred") + require.NoError(t, err, "expected no errors, but errors occurred") assert.Equal(t, cc.expectedAppStatus, appStatuses, "expected appStatuses did not match actual") }) } @@ -5409,10 +5176,10 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) for _, cc := range []struct { name string @@ -5532,9 +5299,10 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) { Status: v1alpha1.ApplicationSetStatus{ ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{ { - Application: "app1", - Message: "Application is out of date with the current AppSet generation, setting status to Waiting.", - Status: "Waiting", + Application: "app1", + Message: "Application is out of date with the current AppSet generation, setting status to Waiting.", + Status: "Waiting", + TargetRevisions: []string{"Next"}, }, }, }, @@ -5552,6 +5320,7 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) { Message: "Application moved to Pending status, watching for the Application resource to start Progressing.", Status: "Pending", Step: "1", + TargetRevisions: []string{"Next"}, }, }, }, @@ -6132,26 +5901,27 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) { argoObjs := []runtime.Object{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&cc.appSet).WithStatusSubresource(&cc.appSet).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(1), - Cache: &fakeCache{}, Generators: map[string]generators.Generator{}, ArgoDB: &argoDBMock, ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), KubeClientset: kubeclientset, + Metrics: metrics, } - appStatuses, err := r.updateApplicationSetApplicationStatusProgress(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appSyncMap, cc.appStepMap, cc.appMap) + 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 { appStatuses[i].LastTransitionTime = nil } - assert.NoError(t, err, "expected no errors, but errors occurred") + require.NoError(t, err, "expected no errors, but errors occurred") assert.Equal(t, cc.expectedAppStatus, appStatuses, "expected appStatuses did not match actual") }) } @@ -6160,10 +5930,10 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) { func TestUpdateResourceStatus(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) for _, cc := range []struct { name string @@ -6347,21 +6117,120 @@ func TestUpdateResourceStatus(t *testing.T) { argoObjs := []runtime.Object{} client := fake.NewClientBuilder().WithScheme(scheme).WithStatusSubresource(&cc.appSet).WithObjects(&cc.appSet).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) + + r := ApplicationSetReconciler{ + Client: client, + Scheme: scheme, + Recorder: record.NewFakeRecorder(1), + Generators: map[string]generators.Generator{}, + ArgoDB: &argoDBMock, + ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), + KubeClientset: kubeclientset, + Metrics: metrics, + } + + 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") + }) + } +} + +func generateNAppResourceStatuses(n int) []v1alpha1.ResourceStatus { + var r []v1alpha1.ResourceStatus + for i := 0; i < n; i++ { + r = append(r, v1alpha1.ResourceStatus{ + Name: "app" + strconv.Itoa(i), + Status: v1alpha1.SyncStatusCodeSynced, + Health: &v1alpha1.HealthStatus{ + Status: health.HealthStatusHealthy, + Message: "OK", + }, + }, + ) + } + return r +} + +func generateNHealthyApps(n int) []v1alpha1.Application { + var r []v1alpha1.Application + for i := 0; i < n; i++ { + r = append(r, v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Name: "app" + strconv.Itoa(i), + }, + Status: v1alpha1.ApplicationStatus{ + Sync: v1alpha1.SyncStatus{ + Status: v1alpha1.SyncStatusCodeSynced, + }, + Health: v1alpha1.HealthStatus{ + Status: health.HealthStatusHealthy, + Message: "OK", + }, + }, + }) + } + return r +} + +func TestResourceStatusAreOrdered(t *testing.T) { + scheme := runtime.NewScheme() + err := v1alpha1.AddToScheme(scheme) + require.NoError(t, err) + + err = v1alpha1.AddToScheme(scheme) + require.NoError(t, err) + for _, cc := range []struct { + name string + appSet v1alpha1.ApplicationSet + apps []v1alpha1.Application + expectedResources []v1alpha1.ResourceStatus + }{ + { + name: "Ensures AppSet is always ordered", + appSet: v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "argocd", + }, + Status: v1alpha1.ApplicationSetStatus{ + Resources: []v1alpha1.ResourceStatus{}, + }, + }, + apps: generateNHealthyApps(10), + expectedResources: generateNAppResourceStatuses(10), + }, + } { + t.Run(cc.name, func(t *testing.T) { + kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...) + argoDBMock := dbmocks.ArgoDB{} + argoObjs := []runtime.Object{} + + client := fake.NewClientBuilder().WithScheme(scheme).WithStatusSubresource(&cc.appSet).WithObjects(&cc.appSet).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(1), - Cache: &fakeCache{}, Generators: map[string]generators.Generator{}, ArgoDB: &argoDBMock, ArgoAppClientset: appclientset.NewSimpleClientset(argoObjs...), KubeClientset: kubeclientset, + Metrics: metrics, } 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(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps) + require.NoError(t, err, "expected no errors, but errors occurred") + + err = r.updateResourcesStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps) + require.NoError(t, err, "expected no errors, but errors occurred") - assert.NoError(t, err, "expected no errors, but errors occurred") assert.Equal(t, cc.expectedResources, cc.appSet.Status.Resources, "expected resources did not match actual") }) } @@ -6558,3 +6427,74 @@ func TestOwnsHandler(t *testing.T) { }) } } + +func TestMigrateStatus(t *testing.T) { + scheme := runtime.NewScheme() + err := v1alpha1.AddToScheme(scheme) + require.NoError(t, err) + + err = v1alpha1.AddToScheme(scheme) + require.NoError(t, err) + + for _, tc := range []struct { + name string + appset v1alpha1.ApplicationSet + expectedStatus v1alpha1.ApplicationSetStatus + }{ + { + name: "status without applicationstatus target revisions set will default to empty list", + appset: v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "test", + }, + Status: v1alpha1.ApplicationSetStatus{ + ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{ + {}, + }, + }, + }, + expectedStatus: v1alpha1.ApplicationSetStatus{ + ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{ + { + TargetRevisions: []string{}, + }, + }, + }, + }, + { + name: "status with applicationstatus target revisions set will do nothing", + appset: v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "test", + }, + Status: v1alpha1.ApplicationSetStatus{ + ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{ + { + TargetRevisions: []string{"Current"}, + }, + }, + }, + }, + expectedStatus: v1alpha1.ApplicationSetStatus{ + ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{ + { + TargetRevisions: []string{"Current"}, + }, + }, + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + client := fake.NewClientBuilder().WithScheme(scheme).WithStatusSubresource(&tc.appset).WithObjects(&tc.appset).Build() + r := ApplicationSetReconciler{ + Client: client, + } + + 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 04ee140d2cde7..66fdebca66a21 100644 --- a/applicationset/controllers/clustereventhandler.go +++ b/applicationset/controllers/clustereventhandler.go @@ -4,6 +4,8 @@ import ( "context" "fmt" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/types" @@ -24,29 +26,29 @@ type clusterSecretEventHandler struct { Client client.Client } -func (h *clusterSecretEventHandler) Create(ctx context.Context, e event.CreateEvent, q workqueue.RateLimitingInterface) { +func (h *clusterSecretEventHandler) Create(ctx context.Context, e event.CreateEvent, q workqueue.TypedRateLimitingInterface[reconcile.Request]) { h.queueRelatedAppGenerators(ctx, q, e.Object) } -func (h *clusterSecretEventHandler) Update(ctx context.Context, e event.UpdateEvent, q workqueue.RateLimitingInterface) { +func (h *clusterSecretEventHandler) Update(ctx context.Context, e event.UpdateEvent, q workqueue.TypedRateLimitingInterface[reconcile.Request]) { h.queueRelatedAppGenerators(ctx, q, e.ObjectNew) } -func (h *clusterSecretEventHandler) Delete(ctx context.Context, e event.DeleteEvent, q workqueue.RateLimitingInterface) { +func (h *clusterSecretEventHandler) Delete(ctx context.Context, e event.DeleteEvent, q workqueue.TypedRateLimitingInterface[reconcile.Request]) { h.queueRelatedAppGenerators(ctx, q, e.Object) } -func (h *clusterSecretEventHandler) Generic(ctx context.Context, e event.GenericEvent, q workqueue.RateLimitingInterface) { +func (h *clusterSecretEventHandler) Generic(ctx context.Context, e event.GenericEvent, q workqueue.TypedRateLimitingInterface[reconcile.Request]) { h.queueRelatedAppGenerators(ctx, q, e.Object) } // addRateLimitingInterface defines the Add method of workqueue.RateLimitingInterface, allow us to easily mock // it for testing purposes. -type addRateLimitingInterface interface { - Add(item interface{}) +type addRateLimitingInterface[T comparable] interface { + Add(item T) } -func (h *clusterSecretEventHandler) queueRelatedAppGenerators(ctx context.Context, q addRateLimitingInterface, object client.Object) { +func (h *clusterSecretEventHandler) queueRelatedAppGenerators(ctx context.Context, q addRateLimitingInterface[reconcile.Request], object client.Object) { // Check for label, lookup all ApplicationSets that might match the cluster, queue them all if object.GetLabels()[generators.ArgoCDSecretTypeLabel] != generators.ArgoCDSecretTypeCluster { return diff --git a/applicationset/controllers/clustereventhandler_test.go b/applicationset/controllers/clustereventhandler_test.go index cfec651434f35..1f73ab36746f2 100644 --- a/applicationset/controllers/clustereventhandler_test.go +++ b/applicationset/controllers/clustereventhandler_test.go @@ -6,6 +6,7 @@ import ( 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" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -22,10 +23,10 @@ import ( func TestClusterEventHandler(t *testing.T) { scheme := runtime.NewScheme() err := argov1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = argov1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) tests := []struct { name string @@ -550,24 +551,18 @@ func TestClusterEventHandler(t *testing.T) { handler.queueRelatedAppGenerators(context.Background(), &mockAddRateLimitingInterface, &test.secret) - assert.False(t, mockAddRateLimitingInterface.errorOccurred) assert.ElementsMatch(t, mockAddRateLimitingInterface.addedItems, test.expectedRequests) }) } } // Add checks the type, and adds it to the internal list of received additions -func (obj *mockAddRateLimitingInterface) Add(item interface{}) { - if req, ok := item.(ctrl.Request); ok { - obj.addedItems = append(obj.addedItems, req) - } else { - obj.errorOccurred = true - } +func (obj *mockAddRateLimitingInterface) Add(item reconcile.Request) { + obj.addedItems = append(obj.addedItems, item) } type mockAddRateLimitingInterface struct { - errorOccurred bool - addedItems []ctrl.Request + addedItems []reconcile.Request } func TestNestedGeneratorHasClusterGenerator_NestedClusterGenerator(t *testing.T) { @@ -577,7 +572,7 @@ func TestNestedGeneratorHasClusterGenerator_NestedClusterGenerator(t *testing.T) hasClusterGenerator, err := nestedGeneratorHasClusterGenerator(nested) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, hasClusterGenerator) } @@ -604,7 +599,7 @@ func TestNestedGeneratorHasClusterGenerator_NestedMergeGenerator(t *testing.T) { hasClusterGenerator, err := nestedGeneratorHasClusterGenerator(nested) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, hasClusterGenerator) } @@ -631,6 +626,6 @@ func TestNestedGeneratorHasClusterGenerator_NestedMergeGeneratorWithInvalidJSON( hasClusterGenerator, err := nestedGeneratorHasClusterGenerator(nested) - assert.Error(t, err) + require.Error(t, err) assert.False(t, hasClusterGenerator) } diff --git a/applicationset/controllers/requeue_after_test.go b/applicationset/controllers/requeue_after_test.go index 73075bd246cca..fd922f53566a5 100644 --- a/applicationset/controllers/requeue_after_test.go +++ b/applicationset/controllers/requeue_after_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -16,6 +17,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" "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" ) @@ -25,7 +27,7 @@ func TestRequeueAfter(t *testing.T) { ctx := context.Background() scheme := runtime.NewScheme() err := argov1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) gvrToListKind := map[schema.GroupVersionResource]string{{ Group: "mallard.io", Version: "v1", @@ -55,14 +57,14 @@ func TestRequeueAfter(t *testing.T) { }, } fakeDynClient := dynfake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), gvrToListKind, duckType) - + scmConfig := generators.NewSCMConfig("", []string{""}, true, nil) terminalGenerators := map[string]generators.Generator{ "List": generators.NewListGenerator(), "Clusters": generators.NewClusterGenerator(k8sClient, ctx, appClientset, "argocd"), - "Git": generators.NewGitGenerator(mockServer), - "SCMProvider": generators.NewSCMProviderGenerator(fake.NewClientBuilder().WithObjects(&corev1.Secret{}).Build(), generators.SCMAuthProviders{}, "", []string{""}, true), + "Git": generators.NewGitGenerator(mockServer, "namespace"), + "SCMProvider": generators.NewSCMProviderGenerator(fake.NewClientBuilder().WithObjects(&corev1.Secret{}).Build(), scmConfig), "ClusterDecisionResource": generators.NewDuckTypeGenerator(ctx, fakeDynClient, appClientset, "argocd"), - "PullRequest": generators.NewPullRequestGenerator(k8sClient, generators.SCMAuthProviders{}, "", []string{""}, true), + "PullRequest": generators.NewPullRequestGenerator(k8sClient, scmConfig), } nestedGenerators := map[string]generators.Generator{ @@ -88,11 +90,13 @@ func TestRequeueAfter(t *testing.T) { } client := fake.NewClientBuilder().WithScheme(scheme).Build() + metrics := appsetmetrics.NewFakeAppsetMetrics(client) r := ApplicationSetReconciler{ Client: client, Scheme: scheme, Recorder: record.NewFakeRecorder(0), Generators: topLevelGenerators, + Metrics: metrics, } type args struct { diff --git a/applicationset/controllers/templatePatch.go b/applicationset/controllers/template/patch.go similarity index 98% rename from applicationset/controllers/templatePatch.go rename to applicationset/controllers/template/patch.go index 39058ac187022..b9d1166f1f237 100644 --- a/applicationset/controllers/templatePatch.go +++ b/applicationset/controllers/template/patch.go @@ -1,4 +1,4 @@ -package controllers +package template import ( "encoding/json" diff --git a/applicationset/controllers/templatePatch_test.go b/applicationset/controllers/template/patch_test.go similarity index 99% rename from applicationset/controllers/templatePatch_test.go rename to applicationset/controllers/template/patch_test.go index c1a794077c8ee..456fe445994c8 100644 --- a/applicationset/controllers/templatePatch_test.go +++ b/applicationset/controllers/template/patch_test.go @@ -1,4 +1,4 @@ -package controllers +package template import ( "testing" diff --git a/applicationset/controllers/template/template.go b/applicationset/controllers/template/template.go new file mode 100644 index 0000000000000..bb4bc155d4e59 --- /dev/null +++ b/applicationset/controllers/template/template.go @@ -0,0 +1,99 @@ +package template + +import ( + "fmt" + + "sigs.k8s.io/controller-runtime/pkg/client" + + log "github.com/sirupsen/logrus" + + "github.com/argoproj/argo-cd/v2/applicationset/generators" + "github.com/argoproj/argo-cd/v2/applicationset/utils" + + 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) { + var res []argov1alpha1.Application + + var firstError error + var applicationSetReason argov1alpha1.ApplicationSetReasonType + + for _, requestedGenerator := range applicationSetInfo.Spec.Generators { + 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") + if firstError == nil { + firstError = err + applicationSetReason = argov1alpha1.ApplicationSetReasonApplicationParamsGenerationError + } + continue + } + + for _, a := range t { + tmplApplication := GetTempApplication(a.Template) + + for _, p := range a.Params { + app, err := renderer.RenderTemplateParams(tmplApplication, applicationSetInfo.Spec.SyncPolicy, p, applicationSetInfo.Spec.GoTemplate, applicationSetInfo.Spec.GoTemplateOptions) + if err != nil { + logCtx.WithError(err).WithField("params", a.Params).WithField("generator", requestedGenerator). + Error("error generating application from params") + + if firstError == nil { + firstError = err + applicationSetReason = argov1alpha1.ApplicationSetReasonRenderTemplateParamsError + } + continue + } + + if applicationSetInfo.Spec.TemplatePatch != nil { + patchedApplication, err := renderTemplatePatch(renderer, app, applicationSetInfo, p) + if err != nil { + log.WithError(err).WithField("params", a.Params).WithField("generator", requestedGenerator). + Error("error generating application from params") + + if firstError == nil { + firstError = err + applicationSetReason = argov1alpha1.ApplicationSetReasonRenderTemplateParamsError + } + continue + } + + app = patchedApplication + } + + // The app's namespace must be the same as the AppSet's namespace to preserve the appsets-in-any-namespace + // security boundary. + app.Namespace = applicationSetInfo.Namespace + res = append(res, *app) + } + } + + logCtx.WithField("generator", requestedGenerator).Infof("generated %d applications", len(res)) + logCtx.WithField("generator", requestedGenerator).Debugf("apps from generator: %+v", res) + } + + return res, applicationSetReason, firstError +} + +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) + } + + return applyTemplatePatch(app, replacedTemplate) +} + +func GetTempApplication(applicationSetTemplate argov1alpha1.ApplicationSetTemplate) *argov1alpha1.Application { + var tmplApplication argov1alpha1.Application + tmplApplication.Annotations = applicationSetTemplate.Annotations + tmplApplication.Labels = applicationSetTemplate.Labels + tmplApplication.Namespace = applicationSetTemplate.Namespace + tmplApplication.Name = applicationSetTemplate.Name + tmplApplication.Spec = applicationSetTemplate.Spec + tmplApplication.Finalizers = applicationSetTemplate.Finalizers + + return &tmplApplication +} diff --git a/applicationset/controllers/template/template_test.go b/applicationset/controllers/template/template_test.go new file mode 100644 index 0000000000000..c765e9c1c67a4 --- /dev/null +++ b/applicationset/controllers/template/template_test.go @@ -0,0 +1,350 @@ +package template + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + + "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" + "github.com/argoproj/argo-cd/v2/util/collections" +) + +func TestGenerateApplications(t *testing.T) { + scheme := runtime.NewScheme() + err := v1alpha1.AddToScheme(scheme) + require.NoError(t, err) + + err = v1alpha1.AddToScheme(scheme) + require.NoError(t, err) + + for _, c := range []struct { + name string + params []map[string]interface{} + template v1alpha1.ApplicationSetTemplate + generateParamsError error + rendererError error + expectErr bool + expectedReason v1alpha1.ApplicationSetReasonType + }{ + { + name: "Generate two applications", + params: []map[string]interface{}{{"name": "app1"}, {"name": "app2"}}, + template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ + Name: "name", + Namespace: "namespace", + Labels: map[string]string{"label_name": "label_value"}, + }, + Spec: v1alpha1.ApplicationSpec{}, + }, + expectedReason: "", + }, + { + name: "Handles error from the generator", + generateParamsError: fmt.Errorf("error"), + expectErr: true, + expectedReason: v1alpha1.ApplicationSetReasonApplicationParamsGenerationError, + }, + { + name: "Handles error from the render", + params: []map[string]interface{}{{"name": "app1"}, {"name": "app2"}}, + template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ + Name: "name", + Namespace: "namespace", + Labels: map[string]string{"label_name": "label_value"}, + }, + Spec: v1alpha1.ApplicationSpec{}, + }, + rendererError: fmt.Errorf("error"), + expectErr: true, + expectedReason: v1alpha1.ApplicationSetReasonRenderTemplateParamsError, + }, + } { + cc := c + app := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "namespace", + }, + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + } + + t.Run(cc.name, func(t *testing.T) { + generatorMock := genmock.Generator{} + generator := v1alpha1.ApplicationSetGenerator{ + List: &v1alpha1.ListGenerator{}, + } + + generatorMock.On("GenerateParams", &generator, mock.AnythingOfType("*v1alpha1.ApplicationSet"), mock.Anything). + Return(cc.params, cc.generateParamsError) + + generatorMock.On("GetTemplate", &generator). + Return(&v1alpha1.ApplicationSetTemplate{}) + + rendererMock := rendmock.Renderer{} + + var expectedApps []v1alpha1.Application + + if cc.generateParamsError == nil { + for _, p := range cc.params { + if cc.rendererError != nil { + rendererMock.On("RenderTemplateParams", GetTempApplication(cc.template), mock.AnythingOfType("*v1alpha1.ApplicationSetSyncPolicy"), p, false, []string(nil)). + Return(nil, cc.rendererError) + } else { + rendererMock.On("RenderTemplateParams", GetTempApplication(cc.template), mock.AnythingOfType("*v1alpha1.ApplicationSetSyncPolicy"), p, false, []string(nil)). + Return(&app, nil) + expectedApps = append(expectedApps, app) + } + } + } + + generators := map[string]generators.Generator{ + "List": &generatorMock, + } + renderer := &rendererMock + + got, reason, err := GenerateApplications(log.NewEntry(log.StandardLogger()), v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "namespace", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Generators: []v1alpha1.ApplicationSetGenerator{generator}, + Template: cc.template, + }, + }, + generators, + renderer, + nil, + ) + + if cc.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + assert.Equal(t, expectedApps, got) + assert.Equal(t, cc.expectedReason, reason) + generatorMock.AssertNumberOfCalls(t, "GenerateParams", 1) + + if cc.generateParamsError == nil { + rendererMock.AssertNumberOfCalls(t, "RenderTemplateParams", len(cc.params)) + } + }) + } +} + +func TestMergeTemplateApplications(t *testing.T) { + for _, c := range []struct { + name string + params []map[string]interface{} + template v1alpha1.ApplicationSetTemplate + overrideTemplate v1alpha1.ApplicationSetTemplate + expectedMerged v1alpha1.ApplicationSetTemplate + expectedApps []v1alpha1.Application + }{ + { + name: "Generate app", + params: []map[string]interface{}{{"name": "app1"}}, + template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ + Name: "name", + Namespace: "namespace", + Labels: map[string]string{"label_name": "label_value"}, + }, + Spec: v1alpha1.ApplicationSpec{}, + }, + overrideTemplate: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ + Name: "test", + Labels: map[string]string{"foo": "bar"}, + }, + Spec: v1alpha1.ApplicationSpec{}, + }, + expectedMerged: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ + Name: "test", + Namespace: "namespace", + Labels: map[string]string{"label_name": "label_value", "foo": "bar"}, + }, + Spec: v1alpha1.ApplicationSpec{}, + }, + expectedApps: []v1alpha1.Application{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "test", + Labels: map[string]string{"foo": "bar"}, + }, + Spec: v1alpha1.ApplicationSpec{}, + }, + }, + }, + } { + cc := c + + t.Run(cc.name, func(t *testing.T) { + generatorMock := genmock.Generator{} + generator := v1alpha1.ApplicationSetGenerator{ + List: &v1alpha1.ListGenerator{}, + } + + generatorMock.On("GenerateParams", &generator, mock.AnythingOfType("*v1alpha1.ApplicationSet"), mock.Anything). + Return(cc.params, nil) + + generatorMock.On("GetTemplate", &generator). + Return(&cc.overrideTemplate) + + rendererMock := rendmock.Renderer{} + + rendererMock.On("RenderTemplateParams", GetTempApplication(cc.expectedMerged), mock.AnythingOfType("*v1alpha1.ApplicationSetSyncPolicy"), cc.params[0], false, []string(nil)). + Return(&cc.expectedApps[0], nil) + + generators := map[string]generators.Generator{ + "List": &generatorMock, + } + renderer := &rendererMock + + got, _, _ := GenerateApplications(log.NewEntry(log.StandardLogger()), v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "namespace", + }, + Spec: v1alpha1.ApplicationSetSpec{ + Generators: []v1alpha1.ApplicationSetGenerator{generator}, + Template: cc.template, + }, + }, + generators, + renderer, + nil, + ) + + assert.Equal(t, cc.expectedApps, got) + }) + } +} + +// Test app generation from a go template application set using a pull request generator +func TestGenerateAppsUsingPullRequestGenerator(t *testing.T) { + for _, cases := range []struct { + name string + 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]interface{}{ + { + "number": "1", + "title": "title1", + "branch": "branch1", + "branch_slug": "branchSlug1", + "head_sha": "089d92cbf9ff857a39e6feccd32798ca700fb958", + "head_short_sha": "089d92cb", + "branch_slugify_default": "feat/a_really+long_pull_request_name_to_test_argo_slugification_and_branch_name_shortening_feature", + "branch_slugify_smarttruncate_disabled": "feat/areallylongpullrequestnametotestargoslugificationandbranchnameshorteningfeature", + "branch_slugify_smarttruncate_enabled": "feat/testwithsmarttruncateenabledramdomlonglistofcharacters", + "labels": []string{"label1"}, + }, + }, + template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ + Name: "AppSet-{{.branch}}-{{.number}}", + Labels: map[string]string{ + "app1": "{{index .labels 0}}", + "branch-test1": "AppSet-{{.branch_slugify_default | slugify }}", + "branch-test2": "AppSet-{{.branch_slugify_smarttruncate_disabled | slugify 49 false }}", + "branch-test3": "AppSet-{{.branch_slugify_smarttruncate_enabled | slugify 50 true }}", + }, + }, + Spec: v1alpha1.ApplicationSpec{ + Source: &v1alpha1.ApplicationSource{ + RepoURL: "https://testurl/testRepo", + TargetRevision: "{{.head_short_sha}}", + }, + Destination: v1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "AppSet-{{.branch_slug}}-{{.head_sha}}", + }, + }, + }, + expectedApp: []v1alpha1.Application{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "AppSet-branch1-1", + Labels: map[string]string{ + "app1": "label1", + "branch-test1": "AppSet-feat-a-really-long-pull-request-name-to-test-argo", + "branch-test2": "AppSet-feat-areallylongpullrequestnametotestargoslugific", + "branch-test3": "AppSet-feat", + }, + }, + Spec: v1alpha1.ApplicationSpec{ + Source: &v1alpha1.ApplicationSource{ + RepoURL: "https://testurl/testRepo", + TargetRevision: "089d92cb", + }, + Destination: v1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "AppSet-branchSlug1-089d92cbf9ff857a39e6feccd32798ca700fb958", + }, + }, + }, + }, + }, + } { + t.Run(cases.name, func(t *testing.T) { + generatorMock := genmock.Generator{} + generator := v1alpha1.ApplicationSetGenerator{ + PullRequest: &v1alpha1.PullRequestGenerator{}, + } + + generatorMock.On("GenerateParams", &generator, mock.AnythingOfType("*v1alpha1.ApplicationSet"), mock.Anything). + Return(cases.params, nil) + + generatorMock.On("GetTemplate", &generator). + Return(&cases.template, nil) + + generators := map[string]generators.Generator{ + "PullRequest": &generatorMock, + } + renderer := &utils.Render{} + + gotApp, _, _ := GenerateApplications(log.NewEntry(log.StandardLogger()), v1alpha1.ApplicationSet{ + Spec: v1alpha1.ApplicationSetSpec{ + GoTemplate: true, + Generators: []v1alpha1.ApplicationSetGenerator{{ + PullRequest: &v1alpha1.PullRequestGenerator{}, + }}, + Template: cases.template, + }, + }, + generators, + renderer, + nil, + ) + assert.EqualValues(t, cases.expectedApp[0].ObjectMeta.Name, gotApp[0].ObjectMeta.Name) + assert.EqualValues(t, cases.expectedApp[0].Spec.Source.TargetRevision, gotApp[0].Spec.Source.TargetRevision) + assert.EqualValues(t, cases.expectedApp[0].Spec.Destination.Namespace, gotApp[0].Spec.Destination.Namespace) + assert.True(t, collections.StringMapsEqual(cases.expectedApp[0].ObjectMeta.Labels, gotApp[0].ObjectMeta.Labels)) + }) + } +} diff --git a/applicationset/generators/cluster.go b/applicationset/generators/cluster.go index 87cf807df06e1..eafb3de1fabb6 100644 --- a/applicationset/generators/cluster.go +++ b/applicationset/generators/cluster.go @@ -85,7 +85,7 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap clusterSecrets, err := g.getSecretsByClusterName(appSetGenerator) if err != nil { - return nil, err + return nil, fmt.Errorf("error getting cluster secrets: %w", err) } res := []map[string]interface{}{} @@ -106,7 +106,7 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap err = appendTemplatedValues(appSetGenerator.Clusters.Values, params, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) if err != nil { - return nil, err + return nil, fmt.Errorf("error appending templated values for local cluster: %w", err) } res = append(res, params) @@ -146,7 +146,7 @@ func (g *ClusterGenerator) GenerateParams(appSetGenerator *argoappsetv1alpha1.Ap err = appendTemplatedValues(appSetGenerator.Clusters.Values, params, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) if err != nil { - return nil, err + return nil, fmt.Errorf("error appending templated values for cluster: %w", err) } res = append(res, params) @@ -164,7 +164,7 @@ func (g *ClusterGenerator) getSecretsByClusterName(appSetGenerator *argoappsetv1 selector := metav1.AddLabelToSelector(&appSetGenerator.Clusters.Selector, ArgoCDSecretTypeLabel, ArgoCDSecretTypeCluster) secretSelector, err := metav1.LabelSelectorAsSelector(selector) if err != nil { - return nil, err + return nil, fmt.Errorf("error converting label selector: %w", err) } if err := g.Client.List(context.Background(), clusterSecretList, client.MatchingLabelsSelector{Selector: secretSelector}); err != nil { diff --git a/applicationset/generators/cluster_test.go b/applicationset/generators/cluster_test.go index 50908e7f7b705..f319081c09218 100644 --- a/applicationset/generators/cluster_test.go +++ b/applicationset/generators/cluster_test.go @@ -17,6 +17,7 @@ import ( argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type possiblyErroringFakeCtrlRuntimeClient struct { @@ -225,7 +226,7 @@ func TestGenerateParams(t *testing.T) { values: nil, expected: nil, clientError: true, - expectedError: fmt.Errorf("could not list Secrets"), + expectedError: fmt.Errorf("error getting cluster secrets: could not list Secrets"), }, } @@ -262,9 +263,9 @@ func TestGenerateParams(t *testing.T) { }, &applicationSetInfo, nil) if testCase.expectedError != nil { - assert.EqualError(t, err, testCase.expectedError.Error()) + require.EqualError(t, err, testCase.expectedError.Error()) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.ElementsMatch(t, testCase.expected, got) } }) @@ -596,7 +597,7 @@ func TestGenerateParamsGoTemplate(t *testing.T) { values: nil, expected: nil, clientError: true, - expectedError: fmt.Errorf("could not list Secrets"), + expectedError: fmt.Errorf("error getting cluster secrets: could not list Secrets"), }, } @@ -635,9 +636,9 @@ func TestGenerateParamsGoTemplate(t *testing.T) { }, &applicationSetInfo, nil) if testCase.expectedError != nil { - assert.EqualError(t, err, testCase.expectedError.Error()) + require.EqualError(t, err, testCase.expectedError.Error()) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.ElementsMatch(t, testCase.expected, got) } }) diff --git a/applicationset/generators/duck_type.go b/applicationset/generators/duck_type.go index 7e0dfb3570d8c..d7ceafd31de3b 100644 --- a/applicationset/generators/duck_type.go +++ b/applicationset/generators/duck_type.go @@ -125,7 +125,7 @@ func (g *DuckTypeGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.A duckResources, err := g.dynClient.Resource(duckGVR).Namespace(g.namespace).List(g.ctx, listOptions) if err != nil { log.WithField("GVK", duckGVR).Warning("resources were not found") - return nil, err + return nil, fmt.Errorf("failed to get dynamic resources: %w", err) } if len(duckResources.Items) == 0 { @@ -218,7 +218,7 @@ func (g *DuckTypeGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.A res = append(res, params) } } else { - log.Warningf("clusterDecisionResource status." + statusListKey + " missing") + log.Warningf("clusterDecisionResource status.%s missing", statusListKey) return nil, nil } diff --git a/applicationset/generators/duck_type_test.go b/applicationset/generators/duck_type_test.go index ed82a5c9fe075..d2cfdbc59d6bc 100644 --- a/applicationset/generators/duck_type_test.go +++ b/applicationset/generators/duck_type_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -311,9 +312,9 @@ func TestGenerateParamsForDuckType(t *testing.T) { }, &applicationSetInfo, nil) if testCase.expectedError != nil { - assert.EqualError(t, err, testCase.expectedError.Error()) + require.EqualError(t, err, testCase.expectedError.Error()) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.ElementsMatch(t, testCase.expected, got) } }) @@ -609,9 +610,9 @@ func TestGenerateParamsForDuckTypeGoTemplate(t *testing.T) { }, &applicationSetInfo, nil) if testCase.expectedError != nil { - assert.EqualError(t, err, testCase.expectedError.Error()) + require.EqualError(t, err, testCase.expectedError.Error()) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.ElementsMatch(t, testCase.expected, got) } }) diff --git a/applicationset/generators/generator_spec_processor_test.go b/applicationset/generators/generator_spec_processor_test.go index 8f29aba4d698b..a02ea5e3312c1 100644 --- a/applicationset/generators/generator_spec_processor_test.go +++ b/applicationset/generators/generator_spec_processor_test.go @@ -90,7 +90,7 @@ func TestMatchValues(t *testing.T) { emptyTemplate(), &applicationSetInfo, nil, nil) - assert.NoError(t, err) + require.NoError(t, err) assert.ElementsMatch(t, testCase.expected, results[0].Params) }) } @@ -174,7 +174,7 @@ func TestMatchValuesGoTemplate(t *testing.T) { emptyTemplate(), &applicationSetInfo, nil, nil) - assert.NoError(t, err) + require.NoError(t, err) assert.ElementsMatch(t, testCase.expected, results[0].Params) }) } @@ -244,7 +244,7 @@ func TestTransForm(t *testing.T) { emptyTemplate(), &applicationSetInfo, nil, nil) - assert.NoError(t, err) + require.NoError(t, err) assert.ElementsMatch(t, testCase.expected, results[0].Params) }) } @@ -346,7 +346,7 @@ func getMockClusterGenerator() Generator { func getMockGitGenerator() Generator { argoCDServiceMock := mocks.Repos{} argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything).Return([]string{"app1", "app2", "app_3", "p1/app4"}, nil) - gitGenerator := NewGitGenerator(&argoCDServiceMock) + gitGenerator := NewGitGenerator(&argoCDServiceMock, "namespace") return gitGenerator } @@ -555,7 +555,7 @@ func TestInterpolateGeneratorError(t *testing.T) { t.Run(tt.name, func(t *testing.T) { got, err := InterpolateGenerator(tt.args.requestedGenerator, tt.args.params, tt.args.useGoTemplate, tt.args.goTemplateOptions) if tt.expectedErrStr != "" { - assert.EqualError(t, err, tt.expectedErrStr) + require.EqualError(t, err, tt.expectedErrStr) } else { require.NoError(t, err) } diff --git a/applicationset/generators/git.go b/applicationset/generators/git.go index a5fb2576f8f6a..74fe02044b473 100644 --- a/applicationset/generators/git.go +++ b/applicationset/generators/git.go @@ -24,13 +24,16 @@ import ( var _ Generator = (*GitGenerator)(nil) type GitGenerator struct { - repos services.Repos + repos services.Repos + namespace string } -func NewGitGenerator(repos services.Repos) Generator { +func NewGitGenerator(repos services.Repos, namespace string) Generator { g := &GitGenerator{ - repos: repos, + repos: repos, + namespace: namespace, } + return g } @@ -59,21 +62,25 @@ func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Applic noRevisionCache := appSet.RefreshRequired() - var project string - if strings.Contains(appSet.Spec.Template.Spec.Project, "{{") { - project = appSetGenerator.Git.Template.Spec.Project - } else { - project = appSet.Spec.Template.Spec.Project - } - - appProject := &argoprojiov1alpha1.AppProject{} - if err := client.Get(context.TODO(), types.NamespacedName{Name: appSet.Spec.Template.Spec.Project, Namespace: appSet.Namespace}, appProject); err != nil { - return nil, fmt.Errorf("error getting project %s: %w", project, err) + verifyCommit := false + + // 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 !strings.Contains(appSet.Spec.Template.Spec.Project, "{{") { + project := appSet.Spec.Template.Spec.Project + appProject := &argoprojiov1alpha1.AppProject{} + namespace := g.namespace + if namespace == "" { + namespace = appSet.Namespace + } + if err := client.Get(context.TODO(), types.NamespacedName{Name: project, Namespace: namespace}, appProject); err != nil { + return nil, fmt.Errorf("error getting project %s: %w", project, err) + } + // we need to verify the signature on the Git revision if GPG is enabled + verifyCommit = len(appProject.Spec.SignatureKeys) > 0 && gpg.IsGPGEnabled() } - // we need to verify the signature on the Git revision if GPG is enabled - verifyCommit := appProject.Spec.SignatureKeys != nil && len(appProject.Spec.SignatureKeys) > 0 && gpg.IsGPGEnabled() - var err error var res []map[string]interface{} if len(appSetGenerator.Git.Directories) != 0 { diff --git a/applicationset/generators/git_test.go b/applicationset/generators/git_test.go index 275406cd6fc1a..cd0c14d8443f0 100644 --- a/applicationset/generators/git_test.go +++ b/applicationset/generators/git_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client/fake" @@ -322,7 +323,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) - gitGenerator := NewGitGenerator(&argoCDServiceMock) + gitGenerator := NewGitGenerator(&argoCDServiceMock, "") applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", @@ -342,7 +343,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) appProject := argoprojiov1alpha1.AppProject{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() @@ -350,9 +351,9 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { got, err := gitGenerator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo, client) if testCaseCopy.expectedError != nil { - assert.EqualError(t, err, testCaseCopy.expectedError.Error()) + require.EqualError(t, err, testCaseCopy.expectedError.Error()) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testCaseCopy.expected, got) } @@ -623,7 +624,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) - gitGenerator := NewGitGenerator(&argoCDServiceMock) + gitGenerator := NewGitGenerator(&argoCDServiceMock, "") applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", @@ -643,7 +644,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) appProject := argoprojiov1alpha1.AppProject{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() @@ -651,9 +652,9 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { got, err := gitGenerator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo, client) if testCaseCopy.expectedError != nil { - assert.EqualError(t, err, testCaseCopy.expectedError.Error()) + require.EqualError(t, err, testCaseCopy.expectedError.Error()) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testCaseCopy.expected, got) } @@ -988,7 +989,7 @@ cluster: argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(testCaseCopy.repoFileContents, testCaseCopy.repoPathsError) - gitGenerator := NewGitGenerator(&argoCDServiceMock) + gitGenerator := NewGitGenerator(&argoCDServiceMock, "") applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", @@ -1007,7 +1008,7 @@ cluster: scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) appProject := argoprojiov1alpha1.AppProject{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() @@ -1016,9 +1017,9 @@ cluster: fmt.Println(got, err) if testCaseCopy.expectedError != nil { - assert.EqualError(t, err, testCaseCopy.expectedError.Error()) + require.EqualError(t, err, testCaseCopy.expectedError.Error()) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.ElementsMatch(t, testCaseCopy.expected, got) } @@ -1344,7 +1345,7 @@ cluster: argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(testCaseCopy.repoFileContents, testCaseCopy.repoPathsError) - gitGenerator := NewGitGenerator(&argoCDServiceMock) + gitGenerator := NewGitGenerator(&argoCDServiceMock, "") applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", @@ -1363,7 +1364,7 @@ cluster: scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) appProject := argoprojiov1alpha1.AppProject{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() @@ -1372,9 +1373,9 @@ cluster: fmt.Println(got, err) if testCaseCopy.expectedError != nil { - assert.EqualError(t, err, testCaseCopy.expectedError.Error()) + require.EqualError(t, err, testCaseCopy.expectedError.Error()) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.ElementsMatch(t, testCaseCopy.expected, got) } @@ -1382,3 +1383,114 @@ cluster: }) } } + +func TestGitGenerator_GenerateParams(t *testing.T) { + cases := []struct { + name string + directories []argoprojiov1alpha1.GitDirectoryGeneratorItem + pathParamPrefix string + repoApps []string + repoPathsError error + repoFileContents map[string][]byte + values map[string]string + expected []map[string]interface{} + expectedError error + appset argoprojiov1alpha1.ApplicationSet + callGetDirectories bool + }{ + { + name: "Signature Verification - ignores templated project field", + repoApps: []string{ + "app1", + }, + repoPathsError: nil, + appset: argoprojiov1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "set", + Namespace: "namespace", + }, + Spec: argoprojiov1alpha1.ApplicationSetSpec{ + Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{ + Git: &argoprojiov1alpha1.GitGenerator{ + RepoURL: "RepoURL", + Revision: "Revision", + Directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + PathParamPrefix: "", + Values: map[string]string{ + "foo": "bar", + }, + }, + }}, + Template: argoprojiov1alpha1.ApplicationSetTemplate{ + Spec: argoprojiov1alpha1.ApplicationSpec{ + Project: "{{.project}}", + }, + }, + }, + }, + callGetDirectories: true, + expected: []map[string]interface{}{{"path": "app1", "path.basename": "app1", "path.basenameNormalized": "app1", "path[0]": "app1", "values.foo": "bar"}}, + expectedError: nil, + }, + { + name: "Signature Verification - Checks for non-templated project field", + repoApps: []string{ + "app1", + }, + repoPathsError: nil, + appset: argoprojiov1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "set", + Namespace: "namespace", + }, + Spec: argoprojiov1alpha1.ApplicationSetSpec{ + Generators: []argoprojiov1alpha1.ApplicationSetGenerator{{ + Git: &argoprojiov1alpha1.GitGenerator{ + RepoURL: "RepoURL", + Revision: "Revision", + Directories: []argoprojiov1alpha1.GitDirectoryGeneratorItem{{Path: "*"}}, + PathParamPrefix: "", + Values: map[string]string{ + "foo": "bar", + }, + }, + }}, + Template: argoprojiov1alpha1.ApplicationSetTemplate{ + Spec: argoprojiov1alpha1.ApplicationSpec{ + Project: "project", + }, + }, + }, + }, + callGetDirectories: false, + 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 { + argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCase.repoApps, testCase.repoPathsError) + } + gitGenerator := NewGitGenerator(&argoCDServiceMock, "namespace") + + scheme := runtime.NewScheme() + err := v1alpha1.AddToScheme(scheme) + require.NoError(t, err) + appProject := argoprojiov1alpha1.AppProject{} + + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() + + got, err := gitGenerator.GenerateParams(&testCase.appset.Spec.Generators[0], &testCase.appset, client) + + if testCase.expectedError != nil { + require.EqualError(t, err, testCase.expectedError.Error()) + } else { + require.NoError(t, err) + assert.Equal(t, testCase.expected, got) + } + + argoCDServiceMock.AssertExpectations(t) + } +} diff --git a/applicationset/generators/list_test.go b/applicationset/generators/list_test.go index cf8f0bca54938..5a3b1d88dd4f4 100644 --- a/applicationset/generators/list_test.go +++ b/applicationset/generators/list_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -40,7 +41,7 @@ func TestGenerateListParams(t *testing.T) { }, }, &applicationSetInfo, nil) - assert.NoError(t, err) + require.NoError(t, err) assert.ElementsMatch(t, testCase.expected, got) } } @@ -77,7 +78,7 @@ func TestGenerateListParamsGoTemplate(t *testing.T) { }, }, &applicationSetInfo, nil) - assert.NoError(t, err) + require.NoError(t, err) assert.ElementsMatch(t, testCase.expected, got) } } diff --git a/applicationset/generators/matrix_test.go b/applicationset/generators/matrix_test.go index 86e7f236364ff..3a961bb0fe877 100644 --- a/applicationset/generators/matrix_test.go +++ b/applicationset/generators/matrix_test.go @@ -183,9 +183,9 @@ func TestMatrixGenerate(t *testing.T) { }, appSet, nil) if testCaseCopy.expectedErr != nil { - assert.ErrorIs(t, err, testCaseCopy.expectedErr) + require.ErrorIs(t, err, testCaseCopy.expectedErr) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testCaseCopy.expected, got) } }) @@ -396,9 +396,9 @@ func TestMatrixGenerateGoTemplate(t *testing.T) { }, appSet, nil) if testCaseCopy.expectedErr != nil { - assert.ErrorIs(t, err, testCaseCopy.expectedErr) + require.ErrorIs(t, err, testCaseCopy.expectedErr) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testCaseCopy.expected, got) } }) @@ -682,9 +682,9 @@ func TestInterpolatedMatrixGenerate(t *testing.T) { }, appSet, nil) if testCaseCopy.expectedErr != nil { - assert.ErrorIs(t, err, testCaseCopy.expectedErr) + require.ErrorIs(t, err, testCaseCopy.expectedErr) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testCaseCopy.expected, got) } }) @@ -867,9 +867,9 @@ func TestInterpolatedMatrixGenerateGoTemplate(t *testing.T) { }, appSet, nil) if testCaseCopy.expectedErr != nil { - assert.ErrorIs(t, err, testCaseCopy.expectedErr) + require.ErrorIs(t, err, testCaseCopy.expectedErr) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testCaseCopy.expected, got) } }) @@ -1028,9 +1028,9 @@ func TestMatrixGenerateListElementsYaml(t *testing.T) { }, appSet, nil) if testCaseCopy.expectedErr != nil { - assert.ErrorIs(t, err, testCaseCopy.expectedErr) + require.ErrorIs(t, err, testCaseCopy.expectedErr) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testCaseCopy.expected, got) } }) @@ -1073,7 +1073,7 @@ 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")).Return([]map[string]interface{}{ + 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(&argoprojiov1alpha1.ApplicationSetTemplate{}) @@ -1089,7 +1089,7 @@ func TestGitGenerator_GenerateParams_list_x_git_matrix_generator(t *testing.T) { 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) + gitGenerator := NewGitGenerator(repoServiceMock, "") matrixGenerator := NewMatrixGenerator(map[string]Generator{ "List": listGeneratorMock, @@ -1115,7 +1115,7 @@ func TestGitGenerator_GenerateParams_list_x_git_matrix_generator(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) appProject := argoprojiov1alpha1.AppProject{} client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appProject).Build() diff --git a/applicationset/generators/merge_test.go b/applicationset/generators/merge_test.go index eba356c081f72..005e5c2c32905 100644 --- a/applicationset/generators/merge_test.go +++ b/applicationset/generators/merge_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" @@ -180,15 +181,15 @@ func TestMergeGenerate(t *testing.T) { }, appSet, nil) if testCaseCopy.expectedErr != nil { - assert.EqualError(t, err, testCaseCopy.expectedErr.Error()) + require.EqualError(t, err, testCaseCopy.expectedErr.Error()) } else { expectedSet, err := listOfMapsToSet(testCaseCopy.expected) - assert.NoError(t, err) + require.NoError(t, err) actualSet, err := listOfMapsToSet(got) - assert.NoError(t, err) + require.NoError(t, err) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedSet, actualSet) } }) @@ -337,9 +338,9 @@ func TestParamSetsAreUniqueByMergeKeys(t *testing.T) { got, err := getParamSetsByMergeKey(testCaseCopy.mergeKeys, testCaseCopy.paramSets) if testCaseCopy.expectedErr != nil { - assert.EqualError(t, err, testCaseCopy.expectedErr.Error()) + require.EqualError(t, err, testCaseCopy.expectedErr.Error()) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testCaseCopy.expected, got) } }) diff --git a/applicationset/generators/mocks/Generator.go b/applicationset/generators/mocks/Generator.go new file mode 100644 index 0000000000000..dc6197f892866 --- /dev/null +++ b/applicationset/generators/mocks/Generator.go @@ -0,0 +1,100 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + client "sigs.k8s.io/controller-runtime/pkg/client" + + mock "github.com/stretchr/testify/mock" + + 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 { + mock.TestingT + Cleanup(func()) +}) *Generator { + mock := &Generator{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/applicationset/generators/plugin_test.go b/applicationset/generators/plugin_test.go index 0b3deb9e0ab04..55ebcfd5c7820 100644 --- a/applicationset/generators/plugin_test.go +++ b/applicationset/generators/plugin_test.go @@ -654,7 +654,7 @@ func TestPluginGenerateParams(t *testing.T) { w.Header().Set("Content-Type", "application/json") _, err := w.Write(testCase.content) if err != nil { - assert.NoError(t, fmt.Errorf("Error Write %w", err)) + require.NoError(t, fmt.Errorf("Error Write %w", err)) } }) @@ -687,9 +687,9 @@ func TestPluginGenerateParams(t *testing.T) { } if testCase.expectedError != nil { - assert.EqualError(t, err, testCase.expectedError.Error()) + require.EqualError(t, err, testCase.expectedError.Error()) } else { - assert.NoError(t, err) + require.NoError(t, err) expectedJson, err := json.Marshal(testCase.expected) require.NoError(t, err) gotJson, err := json.Marshal(got) diff --git a/applicationset/generators/pull_request.go b/applicationset/generators/pull_request.go index 54fcb73a2d77f..209e09950e581 100644 --- a/applicationset/generators/pull_request.go +++ b/applicationset/generators/pull_request.go @@ -6,12 +6,12 @@ import ( "strconv" "time" - corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/gosimple/slug" 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" ) @@ -24,19 +24,13 @@ const ( type PullRequestGenerator struct { client client.Client selectServiceProviderFunc func(context.Context, *argoprojiov1alpha1.PullRequestGenerator, *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) - auth SCMAuthProviders - scmRootCAPath string - allowedSCMProviders []string - enableSCMProviders bool + SCMConfig } -func NewPullRequestGenerator(client client.Client, auth SCMAuthProviders, scmRootCAPath string, allowedScmProviders []string, enableSCMProviders bool) Generator { +func NewPullRequestGenerator(client client.Client, scmConfig SCMConfig) Generator { g := &PullRequestGenerator{ - client: client, - auth: auth, - scmRootCAPath: scmRootCAPath, - allowedSCMProviders: allowedScmProviders, - enableSCMProviders: enableSCMProviders, + client: client, + SCMConfig: scmConfig, } g.selectServiceProviderFunc = g.selectServiceProvider return g @@ -103,6 +97,7 @@ func (g *PullRequestGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha paramMap := map[string]interface{}{ "number": strconv.Itoa(pull.Number), + "title": pull.Title, "branch": pull.Branch, "branch_slug": slug.Make(pull.Branch), "target_branch": pull.TargetBranch, @@ -110,6 +105,7 @@ func (g *PullRequestGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha "head_sha": pull.HeadSHA, "head_short_sha": pull.HeadSHA[:shortSHALength], "head_short_sha_7": pull.HeadSHA[:shortSHALength7], + "author": pull.Author, } // PR lables will only be supported for Go Template appsets, since fasttemplate will be deprecated. @@ -135,15 +131,23 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera } if generatorConfig.GitLab != nil { providerConfig := generatorConfig.GitLab - token, err := g.getSecretRef(ctx, providerConfig.TokenRef, applicationSetInfo.Namespace) + var caCerts []byte + var prErr error + if providerConfig.CARef != nil { + caCerts, prErr = utils.GetConfigMapData(ctx, g.client, providerConfig.CARef, applicationSetInfo.Namespace) + if prErr != nil { + return nil, fmt.Errorf("error fetching CA certificates from ConfigMap: %w", prErr) + } + } + token, err := utils.GetSecretRef(ctx, g.client, providerConfig.TokenRef, applicationSetInfo.Namespace) if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } - return pullrequest.NewGitLabService(ctx, token, providerConfig.API, providerConfig.Project, providerConfig.Labels, providerConfig.PullRequestState, g.scmRootCAPath, providerConfig.Insecure) + 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 - token, err := g.getSecretRef(ctx, providerConfig.TokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, providerConfig.TokenRef, applicationSetInfo.Namespace) if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } @@ -151,26 +155,40 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera } if generatorConfig.BitbucketServer != nil { providerConfig := generatorConfig.BitbucketServer - if providerConfig.BasicAuth != nil { - password, err := g.getSecretRef(ctx, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace) + var caCerts []byte + var prErr error + if providerConfig.CARef != nil { + caCerts, prErr = utils.GetConfigMapData(ctx, g.client, providerConfig.CARef, applicationSetInfo.Namespace) + if prErr != nil { + return nil, fmt.Errorf("error fetching CA certificates from ConfigMap: %w", prErr) + } + } + if providerConfig.BearerToken != nil { + appToken, err := utils.GetSecretRef(ctx, g.client, providerConfig.BearerToken.TokenRef, applicationSetInfo.Namespace) + if err != nil { + return nil, fmt.Errorf("error fetching Secret Bearer token: %w", err) + } + return pullrequest.NewBitbucketServiceBearerToken(ctx, providerConfig.API, appToken, providerConfig.Project, providerConfig.Repo, g.scmRootCAPath, providerConfig.Insecure, caCerts) + } else if providerConfig.BasicAuth != nil { + password, err := utils.GetSecretRef(ctx, g.client, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace) if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } - return pullrequest.NewBitbucketServiceBasicAuth(ctx, providerConfig.BasicAuth.Username, password, providerConfig.API, providerConfig.Project, providerConfig.Repo) + 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) + return pullrequest.NewBitbucketServiceNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.Repo, g.scmRootCAPath, providerConfig.Insecure, caCerts) } } if generatorConfig.Bitbucket != nil { providerConfig := generatorConfig.Bitbucket if providerConfig.BearerToken != nil { - appToken, err := g.getSecretRef(ctx, providerConfig.BearerToken.TokenRef, applicationSetInfo.Namespace) + appToken, err := utils.GetSecretRef(ctx, g.client, providerConfig.BearerToken.TokenRef, applicationSetInfo.Namespace) if err != nil { return nil, fmt.Errorf("error fetching Secret Bearer token: %w", err) } return pullrequest.NewBitbucketCloudServiceBearerToken(providerConfig.API, appToken, providerConfig.Owner, providerConfig.Repo) } else if providerConfig.BasicAuth != nil { - password, err := g.getSecretRef(ctx, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace) + password, err := utils.GetSecretRef(ctx, g.client, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace) if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } @@ -181,7 +199,7 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera } if generatorConfig.AzureDevOps != nil { providerConfig := generatorConfig.AzureDevOps - token, err := g.getSecretRef(ctx, providerConfig.TokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, providerConfig.TokenRef, applicationSetInfo.Namespace) if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } @@ -193,7 +211,7 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera func (g *PullRequestGenerator) github(ctx context.Context, cfg *argoprojiov1alpha1.PullRequestGeneratorGithub, applicationSetInfo *argoprojiov1alpha1.ApplicationSet) (pullrequest.PullRequestService, error) { // use an app if it was configured if cfg.AppSecretName != "" { - auth, err := g.auth.GitHubApps.GetAuthSecret(ctx, cfg.AppSecretName) + auth, err := g.GitHubApps.GetAuthSecret(ctx, cfg.AppSecretName) if err != nil { return nil, fmt.Errorf("error getting GitHub App secret: %w", err) } @@ -201,33 +219,9 @@ func (g *PullRequestGenerator) github(ctx context.Context, cfg *argoprojiov1alph } // always default to token, even if not set (public access) - token, err := g.getSecretRef(ctx, cfg.TokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, cfg.TokenRef, applicationSetInfo.Namespace) if err != nil { return nil, fmt.Errorf("error fetching Secret token: %w", err) } return pullrequest.NewGithubService(ctx, token, cfg.API, cfg.Owner, cfg.Repo, cfg.Labels) } - -// getSecretRef gets the value of the key for the specified Secret resource. -func (g *PullRequestGenerator) getSecretRef(ctx context.Context, ref *argoprojiov1alpha1.SecretRef, namespace string) (string, error) { - if ref == nil { - return "", nil - } - - secret := &corev1.Secret{} - err := g.client.Get( - ctx, - client.ObjectKey{ - Name: ref.SecretName, - Namespace: namespace, - }, - secret) - if err != nil { - return "", fmt.Errorf("error fetching secret %s/%s: %w", namespace, ref.SecretName, err) - } - tokenBytes, ok := secret.Data[ref.Key] - if !ok { - return "", fmt.Errorf("key %q in secret %s/%s not found", ref.Key, namespace, ref.SecretName) - } - return string(tokenBytes), nil -} diff --git a/applicationset/generators/pull_request_test.go b/applicationset/generators/pull_request_test.go index 7be1a2f8025dd..e02e7312b350f 100644 --- a/applicationset/generators/pull_request_test.go +++ b/applicationset/generators/pull_request_test.go @@ -6,9 +6,8 @@ import ( "testing" "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client/fake" pullrequest "github.com/argoproj/argo-cd/v2/applicationset/services/pull_request" argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" @@ -29,9 +28,11 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { []*pullrequest.PullRequest{ { Number: 1, + Title: "title1", Branch: "branch1", TargetBranch: "master", HeadSHA: "089d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "testName", }, }, nil, @@ -40,6 +41,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { expected: []map[string]interface{}{ { "number": "1", + "title": "title1", "branch": "branch1", "branch_slug": "branch1", "target_branch": "master", @@ -47,6 +49,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { "head_sha": "089d92cbf9ff857a39e6feccd32798ca700fb958", "head_short_sha": "089d92cb", "head_short_sha_7": "089d92c", + "author": "testName", }, }, expectedErr: nil, @@ -58,9 +61,11 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { []*pullrequest.PullRequest{ { Number: 2, + Title: "title2", Branch: "feat/areally+long_pull_request_name_to_test_argo_slugification_and_branch_name_shortening_feature", TargetBranch: "feat/anotherreally+long_pull_request_name_to_test_argo_slugification_and_branch_name_shortening_feature", HeadSHA: "9b34ff5bd418e57d58891eb0aa0728043ca1e8be", + Author: "testName", }, }, nil, @@ -69,6 +74,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { expected: []map[string]interface{}{ { "number": "2", + "title": "title2", "branch": "feat/areally+long_pull_request_name_to_test_argo_slugification_and_branch_name_shortening_feature", "branch_slug": "feat-areally-long-pull-request-name-to-test-argo", "target_branch": "feat/anotherreally+long_pull_request_name_to_test_argo_slugification_and_branch_name_shortening_feature", @@ -76,6 +82,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { "head_sha": "9b34ff5bd418e57d58891eb0aa0728043ca1e8be", "head_short_sha": "9b34ff5b", "head_short_sha_7": "9b34ff5", + "author": "testName", }, }, expectedErr: nil, @@ -87,9 +94,11 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { []*pullrequest.PullRequest{ { Number: 1, + Title: "title1", Branch: "a-very-short-sha", TargetBranch: "master", HeadSHA: "abcd", + Author: "testName", }, }, nil, @@ -98,6 +107,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { expected: []map[string]interface{}{ { "number": "1", + "title": "title1", "branch": "a-very-short-sha", "branch_slug": "a-very-short-sha", "target_branch": "master", @@ -105,6 +115,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { "head_sha": "abcd", "head_short_sha": "abcd", "head_short_sha_7": "abcd", + "author": "testName", }, }, expectedErr: nil, @@ -127,10 +138,12 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { []*pullrequest.PullRequest{ { Number: 1, + Title: "title1", Branch: "branch1", TargetBranch: "master", HeadSHA: "089d92cbf9ff857a39e6feccd32798ca700fb958", Labels: []string{"preview"}, + Author: "testName", }, }, nil, @@ -139,6 +152,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { expected: []map[string]interface{}{ { "number": "1", + "title": "title1", "branch": "branch1", "branch_slug": "branch1", "target_branch": "master", @@ -147,6 +161,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { "head_short_sha": "089d92cb", "head_short_sha_7": "089d92c", "labels": []string{"preview"}, + "author": "testName", }, }, expectedErr: nil, @@ -164,10 +179,12 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { []*pullrequest.PullRequest{ { Number: 1, + Title: "title1", Branch: "branch1", TargetBranch: "master", HeadSHA: "089d92cbf9ff857a39e6feccd32798ca700fb958", Labels: []string{"preview"}, + Author: "testName", }, }, nil, @@ -176,6 +193,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { expected: []map[string]interface{}{ { "number": "1", + "title": "title1", "branch": "branch1", "branch_slug": "branch1", "target_branch": "master", @@ -183,6 +201,7 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { "head_sha": "089d92cbf9ff857a39e6feccd32798ca700fb958", "head_short_sha": "089d92cb", "head_short_sha_7": "089d92c", + "author": "testName", }, }, expectedErr: nil, @@ -207,82 +226,16 @@ func TestPullRequestGithubGenerateParams(t *testing.T) { if c.expectedErr != nil { assert.Equal(t, c.expectedErr.Error(), gotErr.Error()) } else { - assert.NoError(t, gotErr) + require.NoError(t, gotErr) } assert.ElementsMatch(t, c.expected, got) } } -func TestPullRequestGetSecretRef(t *testing.T) { - secret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{Name: "test-secret", Namespace: "test"}, - Data: map[string][]byte{ - "my-token": []byte("secret"), - }, - } - gen := &PullRequestGenerator{client: fake.NewClientBuilder().WithObjects(secret).Build()} - ctx := context.Background() - - cases := []struct { - name, namespace, token string - ref *argoprojiov1alpha1.SecretRef - hasError bool - }{ - { - name: "valid ref", - ref: &argoprojiov1alpha1.SecretRef{SecretName: "test-secret", Key: "my-token"}, - namespace: "test", - token: "secret", - hasError: false, - }, - { - name: "nil ref", - ref: nil, - namespace: "test", - token: "", - hasError: false, - }, - { - name: "wrong name", - ref: &argoprojiov1alpha1.SecretRef{SecretName: "other", Key: "my-token"}, - namespace: "test", - token: "", - hasError: true, - }, - { - name: "wrong key", - ref: &argoprojiov1alpha1.SecretRef{SecretName: "test-secret", Key: "other-token"}, - namespace: "test", - token: "", - hasError: true, - }, - { - name: "wrong namespace", - ref: &argoprojiov1alpha1.SecretRef{SecretName: "test-secret", Key: "my-token"}, - namespace: "other", - token: "", - hasError: true, - }, - } - - for _, c := range cases { - t.Run(c.name, func(t *testing.T) { - token, err := gen.getSecretRef(ctx, c.ref, c.namespace) - if c.hasError { - assert.Error(t, err) - } else { - assert.NoError(t, err) - } - assert.Equal(t, c.token, token) - }) - } -} - func TestAllowedSCMProviderPullRequest(t *testing.T) { cases := []struct { name string providerConfig *argoprojiov1alpha1.PullRequestGenerator - expectedError error }{ { name: "Error Github", @@ -291,7 +244,6 @@ func TestAllowedSCMProviderPullRequest(t *testing.T) { API: "https://myservice.mynamespace.svc.cluster.local", }, }, - expectedError: &ErrDisallowedSCMProvider{}, }, { name: "Error Gitlab", @@ -300,7 +252,6 @@ func TestAllowedSCMProviderPullRequest(t *testing.T) { API: "https://myservice.mynamespace.svc.cluster.local", }, }, - expectedError: &ErrDisallowedSCMProvider{}, }, { name: "Error Gitea", @@ -309,7 +260,6 @@ func TestAllowedSCMProviderPullRequest(t *testing.T) { API: "https://myservice.mynamespace.svc.cluster.local", }, }, - expectedError: &ErrDisallowedSCMProvider{}, }, { name: "Error Bitbucket", @@ -318,7 +268,6 @@ func TestAllowedSCMProviderPullRequest(t *testing.T) { API: "https://myservice.mynamespace.svc.cluster.local", }, }, - expectedError: &ErrDisallowedSCMProvider{}, }, } @@ -328,13 +277,13 @@ func TestAllowedSCMProviderPullRequest(t *testing.T) { t.Run(testCaseCopy.name, func(t *testing.T) { t.Parallel() - pullRequestGenerator := NewPullRequestGenerator(nil, SCMAuthProviders{}, "", []string{ + pullRequestGenerator := NewPullRequestGenerator(nil, NewSCMConfig("", []string{ "github.myorg.com", "gitlab.myorg.com", "gitea.myorg.com", "bitbucket.myorg.com", "azuredevops.myorg.com", - }, true) + }, true, nil)) applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ @@ -349,14 +298,15 @@ func TestAllowedSCMProviderPullRequest(t *testing.T) { _, err := pullRequestGenerator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo, nil) - assert.Error(t, err, "Must return an error") - assert.ErrorAs(t, err, testCaseCopy.expectedError) + require.Error(t, err, "Must return an error") + var expectedError ErrDisallowedSCMProvider + assert.ErrorAs(t, err, &expectedError) }) } } func TestSCMProviderDisabled_PRGenerator(t *testing.T) { - generator := NewPullRequestGenerator(nil, SCMAuthProviders{}, "", []string{}, false) + generator := NewPullRequestGenerator(nil, NewSCMConfig("", []string{}, false, nil)) applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ diff --git a/applicationset/generators/scm_provider.go b/applicationset/generators/scm_provider.go index 0f90240fdb25c..85a2550ae21f9 100644 --- a/applicationset/generators/scm_provider.go +++ b/applicationset/generators/scm_provider.go @@ -7,7 +7,6 @@ import ( "strings" "time" - corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" log "github.com/sirupsen/logrus" @@ -29,29 +28,36 @@ type SCMProviderGenerator struct { client client.Client // Testing hooks. overrideProvider scm_provider.SCMProviderService - SCMAuthProviders + SCMConfig +} +type SCMConfig struct { scmRootCAPath string allowedSCMProviders []string enableSCMProviders bool + GitHubApps github_app_auth.Credentials } -type SCMAuthProviders struct { - GitHubApps github_app_auth.Credentials -} - -func NewSCMProviderGenerator(client client.Client, providers SCMAuthProviders, scmRootCAPath string, allowedSCMProviders []string, enableSCMProviders bool) Generator { - return &SCMProviderGenerator{ - client: client, - SCMAuthProviders: providers, +func NewSCMConfig(scmRootCAPath string, allowedSCMProviders []string, enableSCMProviders bool, gitHubApps github_app_auth.Credentials) SCMConfig { + return SCMConfig{ scmRootCAPath: scmRootCAPath, allowedSCMProviders: allowedSCMProviders, enableSCMProviders: enableSCMProviders, + GitHubApps: gitHubApps, + } +} + +func NewSCMProviderGenerator(client client.Client, scmConfig SCMConfig) Generator { + return &SCMProviderGenerator{ + client: client, + SCMConfig: scmConfig, } } // Testing generator func NewTestSCMProviderGenerator(overrideProvider scm_provider.SCMProviderService) Generator { - return &SCMProviderGenerator{overrideProvider: overrideProvider, enableSCMProviders: true} + return &SCMProviderGenerator{overrideProvider: overrideProvider, SCMConfig: SCMConfig{ + enableSCMProviders: true, + }} } func (g *SCMProviderGenerator) GetRequeueAfter(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator) time.Duration { @@ -139,16 +145,25 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha return nil, fmt.Errorf("scm provider: %w", err) } } else if providerConfig.Gitlab != nil { - token, err := g.getSecretRef(ctx, providerConfig.Gitlab.TokenRef, applicationSetInfo.Namespace) + providerConfig := providerConfig.Gitlab + var caCerts []byte + var scmError error + if providerConfig.CARef != nil { + caCerts, scmError = utils.GetConfigMapData(ctx, g.client, providerConfig.CARef, applicationSetInfo.Namespace) + if scmError != nil { + return nil, fmt.Errorf("error fetching CA certificates from ConfigMap: %w", scmError) + } + } + token, err := utils.GetSecretRef(ctx, g.client, providerConfig.TokenRef, applicationSetInfo.Namespace) if err != nil { return nil, fmt.Errorf("error fetching Gitlab token: %w", err) } - provider, err = scm_provider.NewGitlabProvider(ctx, providerConfig.Gitlab.Group, token, providerConfig.Gitlab.API, providerConfig.Gitlab.AllBranches, providerConfig.Gitlab.IncludeSubgroups, providerConfig.Gitlab.WillIncludeSharedProjects(), providerConfig.Gitlab.Insecure, g.scmRootCAPath, providerConfig.Gitlab.Topic) + 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) } } else if providerConfig.Gitea != nil { - token, err := g.getSecretRef(ctx, providerConfig.Gitea.TokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, providerConfig.Gitea.TokenRef, applicationSetInfo.Namespace) if err != nil { return nil, fmt.Errorf("error fetching Gitea token: %w", err) } @@ -158,21 +173,34 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha } } else if providerConfig.BitbucketServer != nil { providerConfig := providerConfig.BitbucketServer + var caCerts []byte var scmError error - if providerConfig.BasicAuth != nil { - password, err := g.getSecretRef(ctx, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace) + if providerConfig.CARef != nil { + caCerts, scmError = utils.GetConfigMapData(ctx, g.client, providerConfig.CARef, applicationSetInfo.Namespace) + if scmError != nil { + return nil, fmt.Errorf("error fetching CA certificates from ConfigMap: %w", scmError) + } + } + if providerConfig.BearerToken != nil { + appToken, err := utils.GetSecretRef(ctx, g.client, providerConfig.BearerToken.TokenRef, applicationSetInfo.Namespace) + if err != nil { + return nil, fmt.Errorf("error fetching Secret Bearer token: %w", err) + } + provider, scmError = scm_provider.NewBitbucketServerProviderBearerToken(ctx, appToken, providerConfig.API, providerConfig.Project, providerConfig.AllBranches, g.scmRootCAPath, providerConfig.Insecure, caCerts) + } else if providerConfig.BasicAuth != nil { + password, err := utils.GetSecretRef(ctx, g.client, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace) 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) + provider, scmError = scm_provider.NewBitbucketServerProviderBasicAuth(ctx, providerConfig.BasicAuth.Username, password, providerConfig.API, providerConfig.Project, providerConfig.AllBranches, g.scmRootCAPath, providerConfig.Insecure, caCerts) } else { - provider, scmError = scm_provider.NewBitbucketServerProviderNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.AllBranches) + 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) } } else if providerConfig.AzureDevOps != nil { - token, err := g.getSecretRef(ctx, providerConfig.AzureDevOps.AccessTokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, providerConfig.AzureDevOps.AccessTokenRef, applicationSetInfo.Namespace) if err != nil { return nil, fmt.Errorf("error fetching Azure Devops access token: %w", err) } @@ -181,7 +209,7 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha return nil, fmt.Errorf("error initializing Azure Devops service: %w", err) } } else if providerConfig.Bitbucket != nil { - appPassword, err := g.getSecretRef(ctx, providerConfig.Bitbucket.AppPasswordRef, applicationSetInfo.Namespace) + appPassword, err := utils.GetSecretRef(ctx, g.client, providerConfig.Bitbucket.AppPasswordRef, applicationSetInfo.Namespace) if err != nil { return nil, fmt.Errorf("error fetching Bitbucket cloud appPassword: %w", err) } @@ -240,29 +268,6 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha return paramsArray, nil } -func (g *SCMProviderGenerator) getSecretRef(ctx context.Context, ref *argoprojiov1alpha1.SecretRef, namespace string) (string, error) { - if ref == nil { - return "", nil - } - - secret := &corev1.Secret{} - err := g.client.Get( - ctx, - client.ObjectKey{ - Name: ref.SecretName, - Namespace: namespace, - }, - secret) - if err != nil { - return "", fmt.Errorf("error fetching secret %s/%s: %w", namespace, ref.SecretName, err) - } - tokenBytes, ok := secret.Data[ref.Key] - if !ok { - return "", fmt.Errorf("key %q in secret %s/%s not found", ref.Key, namespace, ref.SecretName) - } - return string(tokenBytes), nil -} - func (g *SCMProviderGenerator) githubProvider(ctx context.Context, github *argoprojiov1alpha1.SCMProviderGeneratorGithub, applicationSetInfo *argoprojiov1alpha1.ApplicationSet) (scm_provider.SCMProviderService, error) { if github.AppSecretName != "" { auth, err := g.GitHubApps.GetAuthSecret(ctx, github.AppSecretName) @@ -278,7 +283,7 @@ func (g *SCMProviderGenerator) githubProvider(ctx context.Context, github *argop ) } - token, err := g.getSecretRef(ctx, github.TokenRef, applicationSetInfo.Namespace) + token, err := utils.GetSecretRef(ctx, g.client, github.TokenRef, applicationSetInfo.Namespace) if err != nil { return nil, fmt.Errorf("error fetching Github token: %w", err) } diff --git a/applicationset/generators/scm_provider_test.go b/applicationset/generators/scm_provider_test.go index d2ce25f38b26a..a52f7e8159b86 100644 --- a/applicationset/generators/scm_provider_test.go +++ b/applicationset/generators/scm_provider_test.go @@ -1,83 +1,16 @@ package generators import ( - "context" "testing" "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/argoproj/argo-cd/v2/applicationset/services/scm_provider" argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) -func TestSCMProviderGetSecretRef(t *testing.T) { - secret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{Name: "test-secret", Namespace: "test"}, - Data: map[string][]byte{ - "my-token": []byte("secret"), - }, - } - gen := &SCMProviderGenerator{client: fake.NewClientBuilder().WithObjects(secret).Build()} - ctx := context.Background() - - cases := []struct { - name, namespace, token string - ref *argoprojiov1alpha1.SecretRef - hasError bool - }{ - { - name: "valid ref", - ref: &argoprojiov1alpha1.SecretRef{SecretName: "test-secret", Key: "my-token"}, - namespace: "test", - token: "secret", - hasError: false, - }, - { - name: "nil ref", - ref: nil, - namespace: "test", - token: "", - hasError: false, - }, - { - name: "wrong name", - ref: &argoprojiov1alpha1.SecretRef{SecretName: "other", Key: "my-token"}, - namespace: "test", - token: "", - hasError: true, - }, - { - name: "wrong key", - ref: &argoprojiov1alpha1.SecretRef{SecretName: "test-secret", Key: "other-token"}, - namespace: "test", - token: "", - hasError: true, - }, - { - name: "wrong namespace", - ref: &argoprojiov1alpha1.SecretRef{SecretName: "test-secret", Key: "my-token"}, - namespace: "other", - token: "", - hasError: true, - }, - } - - for _, c := range cases { - t.Run(c.name, func(t *testing.T) { - token, err := gen.getSecretRef(ctx, c.ref, c.namespace) - if c.hasError { - assert.Error(t, err) - } else { - assert.NoError(t, err) - } - assert.Equal(t, c.token, token) - }) - } -} - func TestSCMProviderGenerateParams(t *testing.T) { cases := []struct { name string @@ -173,7 +106,7 @@ func TestSCMProviderGenerateParams(t *testing.T) { mockProvider := &scm_provider.MockProvider{ Repos: testCaseCopy.repos, } - scmGenerator := &SCMProviderGenerator{overrideProvider: mockProvider, enableSCMProviders: true} + scmGenerator := &SCMProviderGenerator{overrideProvider: mockProvider, SCMConfig: SCMConfig{enableSCMProviders: true}} applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "set", @@ -192,7 +125,7 @@ func TestSCMProviderGenerateParams(t *testing.T) { if testCaseCopy.expectedError != nil { assert.EqualError(t, err, testCaseCopy.expectedError.Error()) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testCaseCopy.expected, got) } }) @@ -203,7 +136,6 @@ func TestAllowedSCMProvider(t *testing.T) { cases := []struct { name string providerConfig *argoprojiov1alpha1.SCMProviderGenerator - expectedError error }{ { name: "Error Github", @@ -212,7 +144,6 @@ func TestAllowedSCMProvider(t *testing.T) { API: "https://myservice.mynamespace.svc.cluster.local", }, }, - expectedError: &ErrDisallowedSCMProvider{}, }, { name: "Error Gitlab", @@ -221,7 +152,6 @@ func TestAllowedSCMProvider(t *testing.T) { API: "https://myservice.mynamespace.svc.cluster.local", }, }, - expectedError: &ErrDisallowedSCMProvider{}, }, { name: "Error Gitea", @@ -230,7 +160,6 @@ func TestAllowedSCMProvider(t *testing.T) { API: "https://myservice.mynamespace.svc.cluster.local", }, }, - expectedError: &ErrDisallowedSCMProvider{}, }, { name: "Error Bitbucket", @@ -239,7 +168,6 @@ func TestAllowedSCMProvider(t *testing.T) { API: "https://myservice.mynamespace.svc.cluster.local", }, }, - expectedError: &ErrDisallowedSCMProvider{}, }, { name: "Error AzureDevops", @@ -248,7 +176,6 @@ func TestAllowedSCMProvider(t *testing.T) { API: "https://myservice.mynamespace.svc.cluster.local", }, }, - expectedError: &ErrDisallowedSCMProvider{}, }, } @@ -259,14 +186,16 @@ func TestAllowedSCMProvider(t *testing.T) { t.Parallel() scmGenerator := &SCMProviderGenerator{ - allowedSCMProviders: []string{ - "github.myorg.com", - "gitlab.myorg.com", - "gitea.myorg.com", - "bitbucket.myorg.com", - "azuredevops.myorg.com", + SCMConfig: SCMConfig{ + allowedSCMProviders: []string{ + "github.myorg.com", + "gitlab.myorg.com", + "gitea.myorg.com", + "bitbucket.myorg.com", + "azuredevops.myorg.com", + }, + enableSCMProviders: true, }, - enableSCMProviders: true, } applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ @@ -282,14 +211,15 @@ func TestAllowedSCMProvider(t *testing.T) { _, err := scmGenerator.GenerateParams(&applicationSetInfo.Spec.Generators[0], &applicationSetInfo, nil) - assert.Error(t, err, "Must return an error") - assert.ErrorAs(t, err, testCaseCopy.expectedError) + require.Error(t, err, "Must return an error") + var expectedError ErrDisallowedSCMProvider + assert.ErrorAs(t, err, &expectedError) }) } } func TestSCMProviderDisabled_SCMGenerator(t *testing.T) { - generator := &SCMProviderGenerator{enableSCMProviders: false} + generator := &SCMProviderGenerator{SCMConfig: SCMConfig{enableSCMProviders: false}} applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ diff --git a/applicationset/generators/utils.go b/applicationset/generators/utils.go new file mode 100644 index 0000000000000..84bdda6101006 --- /dev/null +++ b/applicationset/generators/utils.go @@ -0,0 +1,49 @@ +package generators + +import ( + "context" + + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + "sigs.k8s.io/controller-runtime/pkg/client" + + "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(c, ctx, k8sClient, namespace), + "Git": NewGitGenerator(argoCDService, namespace), + "SCMProvider": NewSCMProviderGenerator(c, scmConfig), + "ClusterDecisionResource": NewDuckTypeGenerator(ctx, dynamicClient, k8sClient, namespace), + "PullRequest": NewPullRequestGenerator(c, scmConfig), + "Plugin": NewPluginGenerator(c, ctx, k8sClient, namespace), + } + + nestedGenerators := map[string]Generator{ + "List": terminalGenerators["List"], + "Clusters": terminalGenerators["Clusters"], + "Git": terminalGenerators["Git"], + "SCMProvider": terminalGenerators["SCMProvider"], + "ClusterDecisionResource": terminalGenerators["ClusterDecisionResource"], + "PullRequest": terminalGenerators["PullRequest"], + "Plugin": terminalGenerators["Plugin"], + "Matrix": NewMatrixGenerator(terminalGenerators), + "Merge": NewMergeGenerator(terminalGenerators), + } + + topLevelGenerators := map[string]Generator{ + "List": terminalGenerators["List"], + "Clusters": terminalGenerators["Clusters"], + "Git": terminalGenerators["Git"], + "SCMProvider": terminalGenerators["SCMProvider"], + "ClusterDecisionResource": terminalGenerators["ClusterDecisionResource"], + "PullRequest": terminalGenerators["PullRequest"], + "Plugin": terminalGenerators["Plugin"], + "Matrix": NewMatrixGenerator(nestedGenerators), + "Merge": NewMergeGenerator(nestedGenerators), + } + + return topLevelGenerators +} diff --git a/applicationset/generators/value_interpolation_test.go b/applicationset/generators/value_interpolation_test.go index adf39ccb7642b..5b490233d5d7e 100644 --- a/applicationset/generators/value_interpolation_test.go +++ b/applicationset/generators/value_interpolation_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestValueInterpolation(t *testing.T) { @@ -55,7 +56,7 @@ func TestValueInterpolation(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { err := appendTemplatedValues(testCase.values, testCase.params, false, nil) - assert.NoError(t, err) + require.NoError(t, err) assert.EqualValues(t, testCase.expected, testCase.params) }) } @@ -116,7 +117,7 @@ func TestValueInterpolationWithGoTemplating(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { err := appendTemplatedValues(testCase.values, testCase.params, true, nil) - assert.NoError(t, err) + require.NoError(t, err) assert.EqualValues(t, testCase.expected, testCase.params) }) } diff --git a/applicationset/metrics/fake.go b/applicationset/metrics/fake.go new file mode 100644 index 0000000000000..9c1d55d2f24d2 --- /dev/null +++ b/applicationset/metrics/fake.go @@ -0,0 +1,22 @@ +package metrics + +import ( + "github.com/prometheus/client_golang/prometheus" + ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" +) + +// Fake implementation for testing +func NewFakeAppsetMetrics(client ctrlclient.WithWatch) *ApplicationsetMetrics { + reconcileHistogram := prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "argocd_appset_reconcile", + Help: "Application reconciliation performance in seconds.", + // Buckets can be set later on after observing median time + }, + []string{"name", "namespace"}, + ) + + return &ApplicationsetMetrics{ + reconcileHistogram: reconcileHistogram, + } +} diff --git a/applicationset/metrics/metrics.go b/applicationset/metrics/metrics.go new file mode 100644 index 0000000000000..5b5c1cd82c4b3 --- /dev/null +++ b/applicationset/metrics/metrics.go @@ -0,0 +1,131 @@ +package metrics + +import ( + "time" + + "github.com/prometheus/client_golang/prometheus" + "k8s.io/apimachinery/pkg/labels" + "sigs.k8s.io/controller-runtime/pkg/metrics" + + 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 ( + descAppsetLabels *prometheus.Desc + descAppsetDefaultLabels = []string{"namespace", "name"} + descAppsetInfo = prometheus.NewDesc( + "argocd_appset_info", + "Information about applicationset", + append(descAppsetDefaultLabels, "resource_update_status"), + nil, + ) + + descAppsetGeneratedApps = prometheus.NewDesc( + "argocd_appset_owned_applications", + "Number of applications owned by the applicationset", + descAppsetDefaultLabels, + nil, + ) +) + +type ApplicationsetMetrics struct { + reconcileHistogram *prometheus.HistogramVec +} + +type appsetCollector struct { + lister applisters.ApplicationSetLister + // appsClientSet appclientset.Interface + labels []string + filter func(appset *argoappv1.ApplicationSet) bool +} + +func NewApplicationsetMetrics(appsetLister applisters.ApplicationSetLister, appsetLabels []string, appsetFilter func(appset *argoappv1.ApplicationSet) bool) ApplicationsetMetrics { + reconcileHistogram := prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "argocd_appset_reconcile", + Help: "Application reconciliation performance in seconds.", + // Buckets can be set later on after observing median time + }, + descAppsetDefaultLabels, + ) + + appsetCollector := newAppsetCollector(appsetLister, appsetLabels, appsetFilter) + + // Register collectors and metrics + metrics.Registry.MustRegister(reconcileHistogram) + metrics.Registry.MustRegister(appsetCollector) + + return ApplicationsetMetrics{ + reconcileHistogram: reconcileHistogram, + } +} + +func (m *ApplicationsetMetrics) ObserveReconcile(appset *argoappv1.ApplicationSet, duration time.Duration) { + m.reconcileHistogram.WithLabelValues(appset.Namespace, appset.Name).Observe(duration.Seconds()) +} + +func newAppsetCollector(lister applisters.ApplicationSetLister, labels []string, filter func(appset *argoappv1.ApplicationSet) bool) *appsetCollector { + descAppsetDefaultLabels = []string{"namespace", "name"} + + if len(labels) > 0 { + descAppsetLabels = prometheus.NewDesc( + "argocd_appset_labels", + "Applicationset labels translated to Prometheus labels", + append(descAppsetDefaultLabels, metricsutil.NormalizeLabels("label", labels)...), + nil, + ) + } + + return &appsetCollector{ + lister: lister, + labels: labels, + filter: filter, + } +} + +// Describe implements the prometheus.Collector interface +func (c *appsetCollector) Describe(ch chan<- *prometheus.Desc) { + ch <- descAppsetInfo + ch <- descAppsetGeneratedApps + + if len(c.labels) > 0 { + ch <- descAppsetLabels + } +} + +// Collect implements the prometheus.Collector interface +func (c *appsetCollector) Collect(ch chan<- prometheus.Metric) { + appsets, _ := c.lister.List(labels.NewSelector()) + + for _, appset := range appsets { + if c.filter(appset) { + collectAppset(appset, c.labels, ch) + } + } +} + +func collectAppset(appset *argoappv1.ApplicationSet, labelsToCollect []string, ch chan<- prometheus.Metric) { + labelValues := make([]string, 0) + commonLabelValues := []string{appset.Namespace, appset.Name} + + for _, label := range labelsToCollect { + labelValues = append(labelValues, appset.GetLabels()[label]) + } + + resourceUpdateStatus := "Unknown" + + for _, condition := range appset.Status.Conditions { + if condition.Type == argoappv1.ApplicationSetConditionResourcesUpToDate { + resourceUpdateStatus = condition.Reason + } + } + + if len(labelsToCollect) > 0 { + ch <- prometheus.MustNewConstMetric(descAppsetLabels, prometheus.GaugeValue, 1, append(commonLabelValues, labelValues...)...) + } + + ch <- prometheus.MustNewConstMetric(descAppsetInfo, prometheus.GaugeValue, 1, appset.Namespace, appset.Name, resourceUpdateStatus) + ch <- prometheus.MustNewConstMetric(descAppsetGeneratedApps, prometheus.GaugeValue, float64(len(appset.Status.Resources)), appset.Namespace, appset.Name) +} diff --git a/applicationset/metrics/metrics_test.go b/applicationset/metrics/metrics_test.go new file mode 100644 index 0000000000000..b9ed0ae6ec57a --- /dev/null +++ b/applicationset/metrics/metrics_test.go @@ -0,0 +1,256 @@ +package metrics + +import ( + "net/http" + "net/http/httptest" + "strings" + "testing" + "time" + + "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" + fake "sigs.k8s.io/controller-runtime/pkg/client/fake" + + 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 ( + applicationsetNamespaces = []string{"argocd", "test-namespace1"} + + filter = func(appset *argoappv1.ApplicationSet) bool { + return utils.IsNamespaceAllowed(applicationsetNamespaces, appset.Namespace) + } + + collectedLabels = []string{"included/test"} +) + +const fakeAppsetList = ` +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: test1 + namespace: argocd + labels: + included/test: test + not-included.label/test: test +spec: + generators: + - git: + directories: + - path: test/* + repoURL: https://github.com/test/test.git + revision: HEAD + template: + metadata: + name: '{{.path.basename}}' + spec: + destination: + namespace: '{{.path.basename}}' + server: https://kubernetes.default.svc + project: default + source: + path: '{{.path.path}}' + repoURL: https://github.com/test/test.git + targetRevision: HEAD +status: + resources: + - group: argoproj.io + health: + status: Missing + kind: Application + name: test-app1 + namespace: argocd + status: OutOfSync + version: v1alpha1 + - group: argoproj.io + health: + status: Missing + kind: Application + name: test-app2 + namespace: argocd + status: OutOfSync + version: v1alpha1 + conditions: + - lastTransitionTime: "2024-01-01T00:00:00Z" + message: Successfully generated parameters for all Applications + reason: ApplicationSetUpToDate + status: "False" + type: ErrorOccurred + - lastTransitionTime: "2024-01-01T00:00:00Z" + message: Successfully generated parameters for all Applications + reason: ParametersGenerated + status: "True" + type: ParametersGenerated + - lastTransitionTime: "2024-01-01T00:00:00Z" + message: ApplicationSet up to date + reason: ApplicationSetUpToDate + status: "True" + type: ResourcesUpToDate +--- +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: test2 + namespace: argocd + labels: + not-included.label/test: test +spec: + generators: + - git: + directories: + - path: test/* + repoURL: https://github.com/test/test.git + revision: HEAD + template: + metadata: + name: '{{.path.basename}}' + spec: + destination: + namespace: '{{.path.basename}}' + server: https://kubernetes.default.svc + project: default + source: + path: '{{.path.path}}' + repoURL: https://github.com/test/test.git + targetRevision: HEAD +--- +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: should-be-filtered-out + namespace: not-allowed +spec: + generators: + - git: + directories: + - path: test/* + repoURL: https://github.com/test/test.git + revision: HEAD + template: + metadata: + name: '{{.path.basename}}' + spec: + destination: + namespace: '{{.path.basename}}' + server: https://kubernetes.default.svc + project: default + source: + path: '{{.path.path}}' + repoURL: https://github.com/test/test.git + targetRevision: HEAD +` + +func newFakeAppsets(fakeAppsetYAML string) []argoappv1.ApplicationSet { + var results []argoappv1.ApplicationSet + + appsetRawYamls := strings.Split(fakeAppsetYAML, "---") + + for _, appsetRawYaml := range appsetRawYamls { + var appset argoappv1.ApplicationSet + err := yaml.Unmarshal([]byte(appsetRawYaml), &appset) + if err != nil { + panic(err) + } + + results = append(results, appset) + } + + return results +} + +func TestApplicationsetCollector(t *testing.T) { + appsetList := newFakeAppsets(fakeAppsetList) + client := initializeClient(appsetList) + metrics.Registry = prometheus.NewRegistry() + + appsetCollector := newAppsetCollector(utils.NewAppsetLister(client), collectedLabels, filter) + + metrics.Registry.MustRegister(appsetCollector) + req, err := http.NewRequest("GET", "/metrics", nil) + require.NoError(t, err) + rr := httptest.NewRecorder() + handler := promhttp.HandlerFor(metrics.Registry, promhttp.HandlerOpts{}) + handler.ServeHTTP(rr, req) + + assert.Equal(t, http.StatusOK, rr.Code) + // Test correct appset_info and owned applications + assert.Contains(t, rr.Body.String(), ` +argocd_appset_info{name="test1",namespace="argocd",resource_update_status="ApplicationSetUpToDate"} 1 +`) + assert.Contains(t, rr.Body.String(), ` +argocd_appset_owned_applications{name="test1",namespace="argocd"} 2 +`) + // Test labels collection - should not include labels not included in the list of collected labels and include the ones that do. + assert.Contains(t, rr.Body.String(), ` +argocd_appset_labels{label_included_test="test",name="test1",namespace="argocd"} 1 +`) + assert.NotContains(t, rr.Body.String(), normalizeLabel("not-included.label/test")) + // If collected label is not present on the applicationset the value should be empty + assert.Contains(t, rr.Body.String(), ` +argocd_appset_labels{label_included_test="",name="test2",namespace="argocd"} 1 +`) + // If ResourcesUpToDate condition is not present on the applicationset the status should be reported as 'Unknown' + assert.Contains(t, rr.Body.String(), ` +argocd_appset_info{name="test2",namespace="argocd",resource_update_status="Unknown"} 1 +`) + // If there are no resources on the applicationset the owned application gague should return 0 + assert.Contains(t, rr.Body.String(), ` +argocd_appset_owned_applications{name="test2",namespace="argocd"} 0 +`) + // Test that filter is working + assert.NotContains(t, rr.Body.String(), `name="should-be-filtered-out"`) +} + +func TestObserveReconcile(t *testing.T) { + appsetList := newFakeAppsets(fakeAppsetList) + client := initializeClient(appsetList) + metrics.Registry = prometheus.NewRegistry() + + appsetMetrics := NewApplicationsetMetrics(utils.NewAppsetLister(client), collectedLabels, filter) + + req, err := http.NewRequest("GET", "/metrics", nil) + require.NoError(t, err) + rr := httptest.NewRecorder() + handler := promhttp.HandlerFor(metrics.Registry, promhttp.HandlerOpts{}) + appsetMetrics.ObserveReconcile(&appsetList[0], 5*time.Second) + handler.ServeHTTP(rr, req) + assert.Contains(t, rr.Body.String(), ` +argocd_appset_reconcile_sum{name="test1",namespace="argocd"} 5 +`) + // If there are no resources on the applicationset the owned application gague should return 0 + assert.Contains(t, rr.Body.String(), ` +argocd_appset_reconcile_count{name="test1",namespace="argocd"} 1 +`) +} + +func initializeClient(appsets []argoappv1.ApplicationSet) ctrlclient.WithWatch { + scheme := runtime.NewScheme() + err := argoappv1.AddToScheme(scheme) + if err != nil { + panic(err) + } + + var clientObjects []ctrlclient.Object + + for _, appset := range appsets { + clientObjects = append(clientObjects, appset.DeepCopy()) + } + + return fake.NewClientBuilder().WithScheme(scheme).WithObjects(clientObjects...).Build() +} + +func normalizeLabel(label string) string { + return metricsutil.NormalizeLabels("label", []string{label})[0] +} diff --git a/applicationset/services/internal/github_app/client.go b/applicationset/services/internal/github_app/client.go index bad6e828aa5c6..742b2bc001383 100644 --- a/applicationset/services/internal/github_app/client.go +++ b/applicationset/services/internal/github_app/client.go @@ -5,7 +5,7 @@ import ( "net/http" "github.com/bradleyfalzon/ghinstallation/v2" - "github.com/google/go-github/v35/github" + "github.com/google/go-github/v63/github" "github.com/argoproj/argo-cd/v2/applicationset/services/github_app_auth" ) @@ -26,7 +26,7 @@ func Client(g github_app_auth.Authentication, url string) (*github.Client, error } else { rt.BaseURL = url httpClient := http.Client{Transport: rt} - client, err = github.NewEnterpriseClient(url, url, &httpClient) + client, err = github.NewClient(&httpClient).WithEnterpriseURLs(url, url) if err != nil { return nil, fmt.Errorf("failed to create github enterprise client: %w", err) } diff --git a/applicationset/services/mocks/Repos.go b/applicationset/services/mocks/Repos.go index 7daf3cccc7aab..2bc9be358c379 100644 --- a/applicationset/services/mocks/Repos.go +++ b/applicationset/services/mocks/Repos.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.40.2. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks diff --git a/applicationset/services/pull_request/azure_devops.go b/applicationset/services/pull_request/azure_devops.go index 8e83d01221a44..1d263212cdea1 100644 --- a/applicationset/services/pull_request/azure_devops.go +++ b/applicationset/services/pull_request/azure_devops.go @@ -82,6 +82,7 @@ func (a *AzureDevOpsService) List(ctx context.Context) ([]*PullRequest, error) { pr.Repository.Name == nil || pr.PullRequestId == nil || pr.SourceRefName == nil || + pr.TargetRefName == nil || pr.LastMergeSourceCommit == nil || pr.LastMergeSourceCommit.CommitId == nil { continue @@ -94,10 +95,13 @@ func (a *AzureDevOpsService) List(ctx context.Context) ([]*PullRequest, error) { if *pr.Repository.Name == a.repo { pullRequests = append(pullRequests, &PullRequest{ - Number: *pr.PullRequestId, - Branch: strings.Replace(*pr.SourceRefName, "refs/heads/", "", 1), - HeadSHA: *pr.LastMergeSourceCommit.CommitId, - Labels: azureDevOpsLabels, + Number: *pr.PullRequestId, + Title: *pr.Title, + Branch: strings.Replace(*pr.SourceRefName, "refs/heads/", "", 1), + TargetBranch: strings.Replace(*pr.TargetRefName, "refs/heads/", "", 1), + HeadSHA: *pr.LastMergeSourceCommit.CommitId, + Labels: azureDevOpsLabels, + Author: strings.Split(*pr.CreatedBy.UniqueName, "@")[0], // Get the part before the @ in the email-address }) } } diff --git a/applicationset/services/pull_request/azure_devops_test.go b/applicationset/services/pull_request/azure_devops_test.go index d32eac0b8a330..24453c93a2195 100644 --- a/applicationset/services/pull_request/azure_devops_test.go +++ b/applicationset/services/pull_request/azure_devops_test.go @@ -4,10 +4,13 @@ import ( "context" "testing" + "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/v2/applicationset/services/scm_provider/azure_devops/git/mocks" ) @@ -28,6 +31,10 @@ func createLabelsPtr(x []core.WebApiTagDefinition) *[]core.WebApiTagDefinition { return &x } +func createUniqueNamePtr(x string) *string { + return &x +} + type AzureClientFactoryMock struct { mock *mock.Mock } @@ -55,13 +62,17 @@ func TestListPullRequest(t *testing.T) { teamProject := "myorg_project" repoName := "myorg_project_repo" pr_id := 123 + pr_title := "feat(123)" pr_head_sha := "cd4973d9d14a08ffe6b641a89a68891d6aac8056" ctx := context.Background() + uniqueName := "testName" pullRequestMock := []git.GitPullRequest{ { PullRequestId: createIntPtr(pr_id), + Title: createStringPtr(pr_title), SourceRefName: createStringPtr("refs/heads/feature-branch"), + TargetRefName: createStringPtr("refs/heads/main"), LastMergeSourceCommit: &git.GitCommitRef{ CommitId: createStringPtr(pr_head_sha), }, @@ -69,6 +80,9 @@ func TestListPullRequest(t *testing.T) { Repository: &git.GitRepository{ Name: createStringPtr(repoName), }, + CreatedBy: &webapi.IdentityRef{ + UniqueName: createUniqueNamePtr(uniqueName + "@example.com"), + }, }, } @@ -90,11 +104,14 @@ func TestListPullRequest(t *testing.T) { } list, err := provider.List(ctx) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, list, 1) assert.Equal(t, "feature-branch", list[0].Branch) + assert.Equal(t, "main", list[0].TargetBranch) assert.Equal(t, pr_head_sha, list[0].HeadSHA) + assert.Equal(t, "feat(123)", list[0].Title) assert.Equal(t, pr_id, list[0].Number) + assert.Equal(t, uniqueName, list[0].Author) } func TestConvertLabes(t *testing.T) { diff --git a/applicationset/services/pull_request/bitbucket_cloud.go b/applicationset/services/pull_request/bitbucket_cloud.go index 88efafe15bee1..48083dcb407e3 100644 --- a/applicationset/services/pull_request/bitbucket_cloud.go +++ b/applicationset/services/pull_request/bitbucket_cloud.go @@ -17,7 +17,9 @@ type BitbucketCloudService struct { type BitbucketCloudPullRequest struct { ID int `json:"id"` + Title string `json:"title"` Source BitbucketCloudPullRequestSource `json:"source"` + Author string `json:"author"` } type BitbucketCloudPullRequestSource struct { @@ -129,8 +131,10 @@ func (b *BitbucketCloudService) List(_ context.Context) ([]*PullRequest, error) for _, pull := range pulls { pullRequests = append(pullRequests, &PullRequest{ Number: pull.ID, + Title: pull.Title, Branch: pull.Source.Branch.Name, HeadSHA: pull.Source.Commit.Hash, + Author: pull.Author, }) } diff --git a/applicationset/services/pull_request/bitbucket_cloud_test.go b/applicationset/services/pull_request/bitbucket_cloud_test.go index 8756aee5f1652..8d5f7d80ca144 100644 --- a/applicationset/services/pull_request/bitbucket_cloud_test.go +++ b/applicationset/services/pull_request/bitbucket_cloud_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) @@ -26,6 +27,7 @@ func defaultHandlerCloud(t *testing.T) func(http.ResponseWriter, *http.Request) "values": [ { "id": 101, + "title": "feat(foo-bar)", "source": { "branch": { "name": "feature/foo-bar" @@ -34,7 +36,8 @@ func defaultHandlerCloud(t *testing.T) func(http.ResponseWriter, *http.Request) "type": "commit", "hash": "1a8dd249c04a" } - } + }, + "author": "testName" } ] }`) @@ -51,26 +54,26 @@ func TestParseUrlEmptyUrl(t *testing.T) { url, err := parseUrl("") bitbucketUrl, _ := url.Parse("https://api.bitbucket.org/2.0") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, bitbucketUrl, url) } func TestInvalidBaseUrlBasicAuthCloud(t *testing.T) { _, err := NewBitbucketCloudServiceBasicAuth("http:// example.org", "user", "password", "OWNER", "REPO") - assert.Error(t, err) + require.Error(t, err) } func TestInvalidBaseUrlBearerTokenCloud(t *testing.T) { _, err := NewBitbucketCloudServiceBearerToken("http:// example.org", "TOKEN", "OWNER", "REPO") - assert.Error(t, err) + require.Error(t, err) } func TestInvalidBaseUrlNoAuthCloud(t *testing.T) { _, err := NewBitbucketCloudServiceNoAuth("http:// example.org", "OWNER", "REPO") - assert.Error(t, err) + require.Error(t, err) } func TestListPullRequestBearerTokenCloud(t *testing.T) { @@ -80,13 +83,15 @@ func TestListPullRequestBearerTokenCloud(t *testing.T) { })) defer ts.Close() svc, err := NewBitbucketCloudServiceBearerToken(ts.URL, "TOKEN", "OWNER", "REPO") - assert.NoError(t, err) + require.NoError(t, err) pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, 101, pullRequests[0].Number) + assert.Equal(t, "feat(foo-bar)", pullRequests[0].Title) assert.Equal(t, "feature/foo-bar", pullRequests[0].Branch) assert.Equal(t, "1a8dd249c04a", pullRequests[0].HeadSHA) + assert.Equal(t, "testName", pullRequests[0].Author) } func TestListPullRequestNoAuthCloud(t *testing.T) { @@ -96,13 +101,15 @@ func TestListPullRequestNoAuthCloud(t *testing.T) { })) defer ts.Close() svc, err := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") - assert.NoError(t, err) + require.NoError(t, err) pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, 101, pullRequests[0].Number) + assert.Equal(t, "feat(foo-bar)", pullRequests[0].Title) assert.Equal(t, "feature/foo-bar", pullRequests[0].Branch) assert.Equal(t, "1a8dd249c04a", pullRequests[0].HeadSHA) + assert.Equal(t, "testName", pullRequests[0].Author) } func TestListPullRequestBasicAuthCloud(t *testing.T) { @@ -112,13 +119,15 @@ func TestListPullRequestBasicAuthCloud(t *testing.T) { })) defer ts.Close() svc, err := NewBitbucketCloudServiceBasicAuth(ts.URL, "user", "password", "OWNER", "REPO") - assert.NoError(t, err) + require.NoError(t, err) pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, 101, pullRequests[0].Number) + assert.Equal(t, "feat(foo-bar)", pullRequests[0].Title) assert.Equal(t, "feature/foo-bar", pullRequests[0].Branch) assert.Equal(t, "1a8dd249c04a", pullRequests[0].HeadSHA) + assert.Equal(t, "testName", pullRequests[0].Author) } func TestListPullRequestPaginationCloud(t *testing.T) { @@ -135,6 +144,7 @@ func TestListPullRequestPaginationCloud(t *testing.T) { "values": [ { "id": 101, + "title": "feat(101)", "source": { "branch": { "name": "feature-101" @@ -143,10 +153,12 @@ func TestListPullRequestPaginationCloud(t *testing.T) { "type": "commit", "hash": "1a8dd249c04a" } - } + }, + "author": "testName" }, { "id": 102, + "title": "feat(102)", "source": { "branch": { "name": "feature-102" @@ -155,7 +167,8 @@ func TestListPullRequestPaginationCloud(t *testing.T) { "type": "commit", "hash": "4cf807e67a6d" } - } + }, + "author": "testName" } ] }`, r.Host)) @@ -168,6 +181,7 @@ func TestListPullRequestPaginationCloud(t *testing.T) { "values": [ { "id": 103, + "title": "feat(103)", "source": { "branch": { "name": "feature-103" @@ -176,7 +190,8 @@ func TestListPullRequestPaginationCloud(t *testing.T) { "type": "commit", "hash": "6344d9623e3b" } - } + }, + "author": "testName" } ] }`, r.Host)) @@ -189,24 +204,30 @@ func TestListPullRequestPaginationCloud(t *testing.T) { })) defer ts.Close() svc, err := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") - assert.NoError(t, err) + require.NoError(t, err) pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, pullRequests, 3) assert.Equal(t, PullRequest{ 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: "4cf807e67a6d", + Author: "testName", }, *pullRequests[1]) assert.Equal(t, PullRequest{ Number: 103, + Title: "feat(103)", Branch: "feature-103", HeadSHA: "6344d9623e3b", + Author: "testName", }, *pullRequests[2]) } @@ -217,7 +238,7 @@ func TestListResponseErrorCloud(t *testing.T) { defer ts.Close() svc, _ := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") _, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.Error(t, err) + require.Error(t, err) } func TestListResponseMalformedCloud(t *testing.T) { @@ -241,7 +262,7 @@ func TestListResponseMalformedCloud(t *testing.T) { defer ts.Close() svc, _ := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") _, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.Error(t, err) + require.Error(t, err) } func TestListResponseMalformedValuesCloud(t *testing.T) { @@ -265,7 +286,7 @@ func TestListResponseMalformedValuesCloud(t *testing.T) { defer ts.Close() svc, _ := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") _, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.Error(t, err) + require.Error(t, err) } func TestListResponseEmptyCloud(t *testing.T) { @@ -288,9 +309,9 @@ func TestListResponseEmptyCloud(t *testing.T) { })) defer ts.Close() svc, err := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") - assert.NoError(t, err) + require.NoError(t, err) pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Empty(t, pullRequests) } @@ -308,6 +329,7 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { "values": [ { "id": 101, + "title": "feat(101)", "source": { "branch": { "name": "feature-101" @@ -316,10 +338,12 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { "type": "commit", "hash": "1a8dd249c04a" } - } + }, + "author": "testName" }, { "id": 200, + "title": "feat(200)", "source": { "branch": { "name": "feature-200" @@ -328,7 +352,8 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { "type": "commit", "hash": "4cf807e67a6d" } - } + }, + "author": "testName" } ] }`, r.Host)) @@ -341,6 +366,7 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { "values": [ { "id": 102, + "title": "feat(102)", "source": { "branch": { "name": "feature-102" @@ -349,7 +375,8 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { "type": "commit", "hash": "6344d9623e3b" } - } + }, + "author": "testName" } ] }`, r.Host)) @@ -363,48 +390,54 @@ func TestListPullRequestBranchMatchCloud(t *testing.T) { defer ts.Close() regexp := `feature-1[\d]{2}` svc, err := NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") - assert.NoError(t, err) + require.NoError(t, err) pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{ { BranchMatch: ®exp, }, }) - assert.NoError(t, err) + 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", }, *pullRequests[0]) assert.Equal(t, PullRequest{ Number: 102, + Title: "feat(102)", Branch: "feature-102", HeadSHA: "6344d9623e3b", + Author: "testName", }, *pullRequests[1]) regexp = `.*2$` svc, err = NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") - assert.NoError(t, err) + require.NoError(t, err) pullRequests, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{ { BranchMatch: ®exp, }, }) - assert.NoError(t, err) + 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", }, *pullRequests[0]) regexp = `[\d{2}` svc, err = NewBitbucketCloudServiceNoAuth(ts.URL, "OWNER", "REPO") - assert.NoError(t, err) + require.NoError(t, err) _, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{ { BranchMatch: ®exp, }, }) - assert.Error(t, err) + require.Error(t, err) } diff --git a/applicationset/services/pull_request/bitbucket_server.go b/applicationset/services/pull_request/bitbucket_server.go index 22c78f5323418..1f2be70edb428 100644 --- a/applicationset/services/pull_request/bitbucket_server.go +++ b/applicationset/services/pull_request/bitbucket_server.go @@ -3,6 +3,7 @@ package pull_request import ( "context" "fmt" + "net/http" bitbucketv1 "github.com/gfleury/go-bitbucket-v1" log "github.com/sirupsen/logrus" @@ -20,7 +21,7 @@ type BitbucketService struct { var _ PullRequestService = (*BitbucketService)(nil) -func NewBitbucketServiceBasicAuth(ctx context.Context, username, password, url, projectKey, repositorySlug string) (PullRequestService, error) { +func NewBitbucketServiceBasicAuth(ctx context.Context, username, password, url, projectKey, repositorySlug string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) { bitbucketConfig := bitbucketv1.NewConfiguration(url) // Avoid the XSRF check bitbucketConfig.AddDefaultHeader("x-atlassian-token", "no-check") @@ -30,15 +31,29 @@ func NewBitbucketServiceBasicAuth(ctx context.Context, username, password, url, UserName: username, Password: password, }) - return newBitbucketService(ctx, bitbucketConfig, projectKey, repositorySlug) + return newBitbucketService(ctx, bitbucketConfig, projectKey, repositorySlug, scmRootCAPath, insecure, caCerts) } -func NewBitbucketServiceNoAuth(ctx context.Context, url, projectKey, repositorySlug string) (PullRequestService, error) { - return newBitbucketService(ctx, bitbucketv1.NewConfiguration(url), projectKey, repositorySlug) +func NewBitbucketServiceBearerToken(ctx context.Context, bearerToken, url, projectKey, repositorySlug string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) { + bitbucketConfig := bitbucketv1.NewConfiguration(url) + // Avoid the XSRF check + bitbucketConfig.AddDefaultHeader("x-atlassian-token", "no-check") + bitbucketConfig.AddDefaultHeader("x-requested-with", "XMLHttpRequest") + + ctx = context.WithValue(ctx, bitbucketv1.ContextAccessToken, bearerToken) + return newBitbucketService(ctx, bitbucketConfig, projectKey, repositorySlug, scmRootCAPath, insecure, caCerts) +} + +func NewBitbucketServiceNoAuth(ctx context.Context, url, projectKey, repositorySlug string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) { + return newBitbucketService(ctx, bitbucketv1.NewConfiguration(url), projectKey, repositorySlug, scmRootCAPath, insecure, caCerts) } -func newBitbucketService(ctx context.Context, bitbucketConfig *bitbucketv1.Configuration, projectKey, repositorySlug string) (PullRequestService, error) { +func newBitbucketService(ctx context.Context, bitbucketConfig *bitbucketv1.Configuration, projectKey, repositorySlug string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) { bitbucketConfig.BasePath = utils.NormalizeBitbucketBasePath(bitbucketConfig.BasePath) + tlsConfig := utils.GetTlsConfig(scmRootCAPath, insecure, caCerts) + bitbucketConfig.HTTPClient = &http.Client{Transport: &http.Transport{ + TLSClientConfig: tlsConfig, + }} bitbucketClient := bitbucketv1.NewAPIClient(ctx, bitbucketConfig) return &BitbucketService{ @@ -68,10 +83,12 @@ func (b *BitbucketService) List(_ context.Context) ([]*PullRequest, error) { for _, pull := range pulls { pullRequests = append(pullRequests, &PullRequest{ Number: pull.ID, + Title: pull.Title, Branch: pull.FromRef.DisplayID, // ID: refs/heads/main DisplayID: main TargetBranch: pull.ToRef.DisplayID, HeadSHA: pull.FromRef.LatestCommit, // This is not defined in the official docs, but works in practice Labels: []string{}, // Not supported by library + Author: pull.Author.User.Name, }) } diff --git a/applicationset/services/pull_request/bitbucket_server_test.go b/applicationset/services/pull_request/bitbucket_server_test.go index e50c286528d5b..3c9fe1ddd504e 100644 --- a/applicationset/services/pull_request/bitbucket_server_test.go +++ b/applicationset/services/pull_request/bitbucket_server_test.go @@ -2,12 +2,15 @@ package pull_request import ( "context" + "crypto/x509" + "encoding/pem" "io" "net/http" "net/http/httptest" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) @@ -25,6 +28,7 @@ func defaultHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { "values": [ { "id": 101, + "title": "feat(ABC) : 123", "toRef": { "latestCommit": "5b766e3564a3453808f3cd3dd3f2e5fad8ef0e7a", "displayId": "master", @@ -34,6 +38,11 @@ func defaultHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { "id": "refs/heads/feature-ABC-123", "displayId": "feature-ABC-123", "latestCommit": "cb3cf2e4d1517c83e720d2585b9402dbef71f992" + }, + "author": { + "user": { + "name": "testName" + } } } ], @@ -54,15 +63,17 @@ func TestListPullRequestNoAuth(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO") - assert.NoError(t, err) + svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) + require.NoError(t, err) pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, 101, pullRequests[0].Number) + assert.Equal(t, "feat(ABC) : 123", pullRequests[0].Title) assert.Equal(t, "feature-ABC-123", pullRequests[0].Branch) assert.Equal(t, "master", pullRequests[0].TargetBranch) assert.Equal(t, "cb3cf2e4d1517c83e720d2585b9402dbef71f992", pullRequests[0].HeadSHA) + assert.Equal(t, "testName", pullRequests[0].Author) } func TestListPullRequestPagination(t *testing.T) { @@ -78,6 +89,7 @@ func TestListPullRequestPagination(t *testing.T) { "values": [ { "id": 101, + "title": "feat(101)", "toRef": { "latestCommit": "5b766e3564a3453808f3cd3dd3f2e5fad8ef0e7a", "displayId": "master", @@ -87,10 +99,16 @@ func TestListPullRequestPagination(t *testing.T) { "id": "refs/heads/feature-101", "displayId": "feature-101", "latestCommit": "ab3cf2e4d1517c83e720d2585b9402dbef71f992" + }, + "author": { + "user": { + "name": "testName" + } } }, { "id": 102, + "title": "feat(102)", "toRef": { "latestCommit": "5b766e3564a3453808f3cd3dd3f2e5fad8ef0e7a", "displayId": "branch", @@ -100,6 +118,11 @@ func TestListPullRequestPagination(t *testing.T) { "id": "refs/heads/feature-102", "displayId": "feature-102", "latestCommit": "bb3cf2e4d1517c83e720d2585b9402dbef71f992" + }, + "author": { + "user": { + "name": "testName" + } } } ], @@ -113,6 +136,7 @@ func TestListPullRequestPagination(t *testing.T) { "values": [ { "id": 200, + "title": "feat(200)", "toRef": { "latestCommit": "5b766e3564a3453808f3cd3dd3f2e5fad8ef0e7a", "displayId": "master", @@ -122,6 +146,11 @@ func TestListPullRequestPagination(t *testing.T) { "id": "refs/heads/feature-200", "displayId": "feature-200", "latestCommit": "cb3cf2e4d1517c83e720d2585b9402dbef71f992" + }, + "author": { + "user": { + "name": "testName" + } } } ], @@ -135,31 +164,37 @@ func TestListPullRequestPagination(t *testing.T) { } })) defer ts.Close() - svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO") - assert.NoError(t, err) + svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) + require.NoError(t, err) pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, pullRequests, 3) assert.Equal(t, PullRequest{ Number: 101, + Title: "feat(101)", Branch: "feature-101", TargetBranch: "master", HeadSHA: "ab3cf2e4d1517c83e720d2585b9402dbef71f992", Labels: []string{}, + Author: "testName", }, *pullRequests[0]) assert.Equal(t, PullRequest{ Number: 102, + Title: "feat(102)", Branch: "feature-102", TargetBranch: "branch", HeadSHA: "bb3cf2e4d1517c83e720d2585b9402dbef71f992", Labels: []string{}, + Author: "testName", }, *pullRequests[1]) assert.Equal(t, PullRequest{ Number: 200, + Title: "feat(200)", Branch: "feature-200", TargetBranch: "master", HeadSHA: "cb3cf2e4d1517c83e720d2585b9402dbef71f992", Labels: []string{}, + Author: "testName", }, *pullRequests[2]) } @@ -171,24 +206,109 @@ func TestListPullRequestBasicAuth(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - svc, err := NewBitbucketServiceBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", "REPO") - assert.NoError(t, err) + svc, err := NewBitbucketServiceBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", "REPO", "", false, nil) + require.NoError(t, err) + pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + require.NoError(t, err) + assert.Len(t, pullRequests, 1) + assert.Equal(t, 101, pullRequests[0].Number) + assert.Equal(t, "feature-ABC-123", pullRequests[0].Branch) + assert.Equal(t, "cb3cf2e4d1517c83e720d2585b9402dbef71f992", pullRequests[0].HeadSHA) +} + +func TestListPullRequestBearerAuth(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "Bearer tolkien", r.Header.Get("Authorization")) + assert.Equal(t, "no-check", r.Header.Get("X-Atlassian-Token")) + defaultHandler(t)(w, r) + })) + defer ts.Close() + svc, err := NewBitbucketServiceBearerToken(context.Background(), "tolkien", ts.URL, "PROJECT", "REPO", "", false, nil) + require.NoError(t, err) pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, 101, pullRequests[0].Number) + assert.Equal(t, "feat(ABC) : 123", pullRequests[0].Title) assert.Equal(t, "feature-ABC-123", pullRequests[0].Branch) assert.Equal(t, "cb3cf2e4d1517c83e720d2585b9402dbef71f992", pullRequests[0].HeadSHA) } +func TestListPullRequestTLS(t *testing.T) { + tests := []struct { + name string + tlsInsecure bool + passCerts bool + requireErr bool + }{ + { + name: "TLS Insecure: true, No Certs", + tlsInsecure: true, + passCerts: false, + requireErr: false, + }, + { + name: "TLS Insecure: true, With Certs", + tlsInsecure: true, + passCerts: true, + requireErr: false, + }, + { + name: "TLS Insecure: false, With Certs", + tlsInsecure: false, + passCerts: true, + requireErr: false, + }, + { + name: "TLS Insecure: false, No Certs", + tlsInsecure: false, + passCerts: false, + requireErr: true, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defaultHandler(t)(w, r) + })) + defer ts.Close() + + var certs []byte + if test.passCerts == true { + for _, cert := range ts.TLS.Certificates { + for _, c := range cert.Certificate { + parsedCert, err := x509.ParseCertificate(c) + require.NoError(t, err, "Failed to parse certificate") + certs = append(certs, pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: parsedCert.Raw, + })...) + } + } + } + + svc, err := NewBitbucketServiceBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", "REPO", "", test.tlsInsecure, certs) + require.NoError(t, err) + _, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) + if test.requireErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + func TestListResponseError(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) })) defer ts.Close() - svc, _ := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO") + svc, _ := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) _, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.Error(t, err) + require.Error(t, err) } func TestListResponseMalformed(t *testing.T) { @@ -211,9 +331,9 @@ func TestListResponseMalformed(t *testing.T) { } })) defer ts.Close() - svc, _ := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO") + svc, _ := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) _, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.Error(t, err) + require.Error(t, err) } func TestListResponseEmpty(t *testing.T) { @@ -236,10 +356,10 @@ func TestListResponseEmpty(t *testing.T) { } })) defer ts.Close() - svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO") - assert.NoError(t, err) + svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) + require.NoError(t, err) pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Empty(t, pullRequests) } @@ -256,6 +376,7 @@ func TestListPullRequestBranchMatch(t *testing.T) { "values": [ { "id": 101, + "title": "feat(101)", "toRef": { "latestCommit": "5b766e3564a3453808f3cd3dd3f2e5fad8ef0e7a", "displayId": "master", @@ -265,10 +386,16 @@ func TestListPullRequestBranchMatch(t *testing.T) { "id": "refs/heads/feature-101", "displayId": "feature-101", "latestCommit": "ab3cf2e4d1517c83e720d2585b9402dbef71f992" + }, + "author": { + "user": { + "name": "testName" + } } }, { "id": 102, + "title": "feat(102)", "toRef": { "latestCommit": "5b766e3564a3453808f3cd3dd3f2e5fad8ef0e7a", "displayId": "branch", @@ -278,6 +405,11 @@ func TestListPullRequestBranchMatch(t *testing.T) { "id": "refs/heads/feature-102", "displayId": "feature-102", "latestCommit": "bb3cf2e4d1517c83e720d2585b9402dbef71f992" + }, + "author": { + "user": { + "name": "testName" + } } } ], @@ -291,6 +423,7 @@ func TestListPullRequestBranchMatch(t *testing.T) { "values": [ { "id": 200, + "title": "feat(200)", "toRef": { "latestCommit": "5b766e3564a3453808f3cd3dd3f2e5fad8ef0e7a", "displayId": "master", @@ -300,6 +433,11 @@ func TestListPullRequestBranchMatch(t *testing.T) { "id": "refs/heads/feature-200", "displayId": "feature-200", "latestCommit": "cb3cf2e4d1517c83e720d2585b9402dbef71f992" + }, + "author": { + "user": { + "name": "testName" + } } } ], @@ -314,55 +452,61 @@ func TestListPullRequestBranchMatch(t *testing.T) { })) defer ts.Close() regexp := `feature-1[\d]{2}` - svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO") - assert.NoError(t, err) + svc, err := NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) + require.NoError(t, err) pullRequests, err := ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{ { BranchMatch: ®exp, }, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, pullRequests, 2) assert.Equal(t, PullRequest{ Number: 101, + Title: "feat(101)", Branch: "feature-101", TargetBranch: "master", HeadSHA: "ab3cf2e4d1517c83e720d2585b9402dbef71f992", Labels: []string{}, + Author: "testName", }, *pullRequests[0]) assert.Equal(t, PullRequest{ Number: 102, + Title: "feat(102)", Branch: "feature-102", TargetBranch: "branch", HeadSHA: "bb3cf2e4d1517c83e720d2585b9402dbef71f992", Labels: []string{}, + Author: "testName", }, *pullRequests[1]) regexp = `.*2$` - svc, err = NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO") - assert.NoError(t, err) + svc, err = NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) + require.NoError(t, err) pullRequests, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{ { BranchMatch: ®exp, }, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, PullRequest{ Number: 102, + Title: "feat(102)", Branch: "feature-102", TargetBranch: "branch", HeadSHA: "bb3cf2e4d1517c83e720d2585b9402dbef71f992", Labels: []string{}, + Author: "testName", }, *pullRequests[0]) regexp = `[\d{2}` - svc, err = NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO") - assert.NoError(t, err) + svc, err = NewBitbucketServiceNoAuth(context.Background(), ts.URL, "PROJECT", "REPO", "", false, nil) + require.NoError(t, err) _, err = ListPullRequests(context.Background(), svc, []v1alpha1.PullRequestGeneratorFilter{ { BranchMatch: ®exp, }, }) - assert.Error(t, err) + require.Error(t, err) } diff --git a/applicationset/services/pull_request/gitea.go b/applicationset/services/pull_request/gitea.go index ff385ff281c6d..5f32e4dc307cf 100644 --- a/applicationset/services/pull_request/gitea.go +++ b/applicationset/services/pull_request/gitea.go @@ -57,10 +57,12 @@ func (g *GiteaService) List(ctx context.Context) ([]*PullRequest, error) { for _, pr := range prs { list = append(list, &PullRequest{ Number: int(pr.Index), + Title: pr.Title, Branch: pr.Head.Ref, TargetBranch: pr.Base.Ref, HeadSHA: pr.Head.Sha, Labels: getGiteaPRLabelNames(pr.Labels), + Author: pr.Poster.UserName, }) } return list, nil diff --git a/applicationset/services/pull_request/gitea_test.go b/applicationset/services/pull_request/gitea_test.go index 5a5eb4262c616..fbb0fb15aa4ce 100644 --- a/applicationset/services/pull_request/gitea_test.go +++ b/applicationset/services/pull_request/gitea_test.go @@ -10,6 +10,7 @@ import ( "code.gitea.io/sdk/gitea" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func giteaMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { @@ -250,14 +251,16 @@ func TestGiteaList(t *testing.T) { giteaMockHandler(t)(w, r) })) host, err := NewGiteaService(context.Background(), "", ts.URL, "test-argocd", "pr-test", false) - assert.NoError(t, err) + require.NoError(t, err) prs, err := host.List(context.Background()) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, prs, 1) assert.Equal(t, 1, prs[0].Number) + assert.Equal(t, "add an empty file", prs[0].Title) assert.Equal(t, "test", prs[0].Branch) assert.Equal(t, "main", prs[0].TargetBranch) assert.Equal(t, "7bbaf62d92ddfafd9cc8b340c619abaec32bc09f", prs[0].HeadSHA) + assert.Equal(t, "graytshirt", prs[0].Author) } func TestGetGiteaPRLabelNames(t *testing.T) { diff --git a/applicationset/services/pull_request/github.go b/applicationset/services/pull_request/github.go index 7c801e7370f53..b63f2a9de6a8e 100644 --- a/applicationset/services/pull_request/github.go +++ b/applicationset/services/pull_request/github.go @@ -5,7 +5,7 @@ import ( "fmt" "os" - "github.com/google/go-github/v35/github" + "github.com/google/go-github/v63/github" "golang.org/x/oauth2" ) @@ -35,7 +35,7 @@ func NewGithubService(ctx context.Context, token, url, owner, repo string, label client = github.NewClient(httpClient) } else { var err error - client, err = github.NewEnterpriseClient(url, url, httpClient) + client, err = github.NewClient(httpClient).WithEnterpriseURLs(url, url) if err != nil { return nil, err } @@ -66,10 +66,12 @@ func (g *GithubService) List(ctx context.Context) ([]*PullRequest, error) { } pullRequests = append(pullRequests, &PullRequest{ Number: *pull.Number, + Title: *pull.Title, Branch: *pull.Head.Ref, TargetBranch: *pull.Base.Ref, HeadSHA: *pull.Head.SHA, Labels: getGithubPRLabelNames(pull.Labels), + Author: *pull.User.Login, }) } if resp.NextPage == 0 { diff --git a/applicationset/services/pull_request/github_test.go b/applicationset/services/pull_request/github_test.go index c47031acb7e31..30b908f9fb1b6 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/v35/github" + "github.com/google/go-github/v63/github" "github.com/stretchr/testify/assert" ) diff --git a/applicationset/services/pull_request/gitlab.go b/applicationset/services/pull_request/gitlab.go index 7f88c4a230706..c4e49881a4393 100644 --- a/applicationset/services/pull_request/gitlab.go +++ b/applicationset/services/pull_request/gitlab.go @@ -21,7 +21,7 @@ type GitLabService struct { var _ PullRequestService = (*GitLabService)(nil) -func NewGitLabService(ctx context.Context, token, url, project string, labels []string, pullRequestState string, scmRootCAPath string, insecure bool) (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 @@ -34,7 +34,7 @@ func NewGitLabService(ctx context.Context, token, url, project string, labels [] } tr := http.DefaultTransport.(*http.Transport).Clone() - tr.TLSClientConfig = utils.GetTlsConfig(scmRootCAPath, insecure) + tr.TLSClientConfig = utils.GetTlsConfig(scmRootCAPath, insecure, caCerts) retryClient := retryablehttp.NewClient() retryClient.HTTPClient.Transport = tr @@ -56,11 +56,11 @@ func NewGitLabService(ctx context.Context, token, url, project string, labels [] func (g *GitLabService) List(ctx context.Context) ([]*PullRequest, error) { // Filter the merge requests on labels, if they are specified. - var labels *gitlab.Labels + var labels *gitlab.LabelOptions if len(g.labels) > 0 { - labels = (*gitlab.Labels)(&g.labels) + var labelsList gitlab.LabelOptions = g.labels + labels = &labelsList } - opts := &gitlab.ListProjectMergeRequestsOptions{ ListOptions: gitlab.ListOptions{ PerPage: 100, @@ -81,10 +81,12 @@ func (g *GitLabService) List(ctx context.Context) ([]*PullRequest, error) { for _, mr := range mrs { pullRequests = append(pullRequests, &PullRequest{ Number: mr.IID, + Title: mr.Title, Branch: mr.SourceBranch, TargetBranch: mr.TargetBranch, HeadSHA: mr.SHA, Labels: mr.Labels, + Author: mr.Author.Username, }) } if resp.NextPage == 0 { diff --git a/applicationset/services/pull_request/gitlab_test.go b/applicationset/services/pull_request/gitlab_test.go index 2d327068224cd..f9e845595e224 100644 --- a/applicationset/services/pull_request/gitlab_test.go +++ b/applicationset/services/pull_request/gitlab_test.go @@ -2,6 +2,8 @@ package pull_request import ( "context" + "crypto/x509" + "encoding/pem" "io" "net/http" "net/http/httptest" @@ -9,6 +11,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func writeMRListResponse(t *testing.T, w io.Writer) { @@ -34,11 +37,11 @@ func TestGitLabServiceCustomBaseURL(t *testing.T) { writeMRListResponse(t, w) }) - svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", nil, "", "", false) - assert.NoError(t, err) + svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", nil, "", "", false, nil) + require.NoError(t, err) _, err = svc.List(context.Background()) - assert.NoError(t, err) + require.NoError(t, err) } func TestGitLabServiceToken(t *testing.T) { @@ -53,11 +56,11 @@ func TestGitLabServiceToken(t *testing.T) { writeMRListResponse(t, w) }) - svc, err := NewGitLabService(context.Background(), "token-123", server.URL, "278964", nil, "", "", false) - assert.NoError(t, err) + svc, err := NewGitLabService(context.Background(), "token-123", server.URL, "278964", nil, "", "", false, nil) + require.NoError(t, err) _, err = svc.List(context.Background()) - assert.NoError(t, err) + require.NoError(t, err) } func TestList(t *testing.T) { @@ -72,16 +75,18 @@ func TestList(t *testing.T) { writeMRListResponse(t, w) }) - svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", []string{}, "", "", false) - assert.NoError(t, err) + svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", []string{}, "", "", false, nil) + require.NoError(t, err) prs, err := svc.List(context.Background()) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, prs, 1) assert.Equal(t, 15442, prs[0].Number) + assert.Equal(t, "Draft: Use structured logging for DB load balancer", prs[0].Title) assert.Equal(t, "use-structured-logging-for-db-load-balancer", prs[0].Branch) assert.Equal(t, "master", prs[0].TargetBranch) assert.Equal(t, "2fc4e8b972ff3208ec63b6143e34ad67ff343ad7", prs[0].HeadSHA) + assert.Equal(t, "hfyngvason", prs[0].Author) } func TestListWithLabels(t *testing.T) { @@ -96,11 +101,11 @@ func TestListWithLabels(t *testing.T) { writeMRListResponse(t, w) }) - svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", []string{"feature", "ready"}, "", "", false) - assert.NoError(t, err) + svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", []string{"feature", "ready"}, "", "", false, nil) + require.NoError(t, err) _, err = svc.List(context.Background()) - assert.NoError(t, err) + require.NoError(t, err) } func TestListWithState(t *testing.T) { @@ -115,9 +120,77 @@ func TestListWithState(t *testing.T) { writeMRListResponse(t, w) }) - svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", []string{}, "opened", "", false) - assert.NoError(t, err) + svc, err := NewGitLabService(context.Background(), "", server.URL, "278964", []string{}, "opened", "", false, nil) + require.NoError(t, err) _, err = svc.List(context.Background()) - assert.NoError(t, err) + require.NoError(t, err) +} + +func TestListWithStateTLS(t *testing.T) { + tests := []struct { + name string + tlsInsecure bool + passCerts bool + requireErr bool + }{ + { + name: "TLS Insecure: true, No Certs", + tlsInsecure: true, + passCerts: false, + requireErr: false, + }, + { + name: "TLS Insecure: true, With Certs", + tlsInsecure: true, + passCerts: true, + requireErr: false, + }, + { + name: "TLS Insecure: false, With Certs", + tlsInsecure: false, + passCerts: true, + requireErr: false, + }, + { + name: "TLS Insecure: false, No Certs", + tlsInsecure: false, + passCerts: false, + requireErr: true, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + writeMRListResponse(t, w) + })) + defer ts.Close() + + var certs []byte + if test.passCerts == true { + for _, cert := range ts.TLS.Certificates { + for _, c := range cert.Certificate { + parsedCert, err := x509.ParseCertificate(c) + require.NoError(t, err, "Failed to parse certificate") + certs = append(certs, pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: parsedCert.Raw, + })...) + } + } + } + + svc, err := NewGitLabService(context.Background(), "", ts.URL, "278964", []string{}, "opened", "", test.tlsInsecure, certs) + require.NoError(t, err) + + _, err = svc.List(context.Background()) + if test.requireErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } } diff --git a/applicationset/services/pull_request/interface.go b/applicationset/services/pull_request/interface.go index 0015cfe5eafa6..07637b3f95973 100644 --- a/applicationset/services/pull_request/interface.go +++ b/applicationset/services/pull_request/interface.go @@ -8,6 +8,8 @@ import ( type PullRequest struct { // Number is a number that will be the ID of the pull request. Number int + // Title of the pull request. + Title string // Branch is the name of the branch from which the pull request originated. Branch string // TargetBranch is the name of the target branch of the pull request. @@ -16,6 +18,8 @@ type PullRequest struct { HeadSHA string // Labels of the pull request. Labels []string + // Author is the author of the pull request. + Author string } type PullRequestService interface { diff --git a/applicationset/services/pull_request/utils_test.go b/applicationset/services/pull_request/utils_test.go index 5e4f4be5d4070..1c74ae4b66b01 100644 --- a/applicationset/services/pull_request/utils_test.go +++ b/applicationset/services/pull_request/utils_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) @@ -19,9 +20,11 @@ func TestFilterBranchMatchBadRegexp(t *testing.T) { []*PullRequest{ { Number: 1, + Title: "PR branch1", Branch: "branch1", TargetBranch: "master", HeadSHA: "089d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name1", }, }, nil, @@ -32,7 +35,7 @@ func TestFilterBranchMatchBadRegexp(t *testing.T) { }, } _, err := ListPullRequests(context.Background(), provider, filters) - assert.Error(t, err) + require.Error(t, err) } func TestFilterBranchMatch(t *testing.T) { @@ -41,27 +44,35 @@ func TestFilterBranchMatch(t *testing.T) { []*PullRequest{ { Number: 1, + Title: "PR one", Branch: "one", TargetBranch: "master", HeadSHA: "189d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name1", }, { Number: 2, + Title: "PR two", Branch: "two", TargetBranch: "master", HeadSHA: "289d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name2", }, { Number: 3, + Title: "PR three", Branch: "three", TargetBranch: "master", HeadSHA: "389d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name3", }, { Number: 4, + Title: "PR four", Branch: "four", TargetBranch: "master", HeadSHA: "489d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name4", }, }, nil, @@ -72,7 +83,7 @@ func TestFilterBranchMatch(t *testing.T) { }, } pullRequests, err := ListPullRequests(context.Background(), provider, filters) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, "two", pullRequests[0].Branch) } @@ -83,27 +94,35 @@ func TestFilterTargetBranchMatch(t *testing.T) { []*PullRequest{ { Number: 1, + Title: "PR one", Branch: "one", TargetBranch: "master", HeadSHA: "189d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name1", }, { Number: 2, + Title: "PR two", Branch: "two", TargetBranch: "branch1", HeadSHA: "289d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name2", }, { Number: 3, + Title: "PR three", Branch: "three", TargetBranch: "branch2", HeadSHA: "389d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name3", }, { Number: 4, + Title: "PR four", Branch: "four", TargetBranch: "branch3", HeadSHA: "489d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name4", }, }, nil, @@ -114,7 +133,7 @@ func TestFilterTargetBranchMatch(t *testing.T) { }, } pullRequests, err := ListPullRequests(context.Background(), provider, filters) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, pullRequests, 1) assert.Equal(t, "two", pullRequests[0].Branch) } @@ -125,27 +144,35 @@ func TestMultiFilterOr(t *testing.T) { []*PullRequest{ { Number: 1, + Title: "PR one", Branch: "one", TargetBranch: "master", HeadSHA: "189d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name1", }, { Number: 2, + Title: "PR two", Branch: "two", TargetBranch: "master", HeadSHA: "289d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name2", }, { Number: 3, + Title: "PR three", Branch: "three", TargetBranch: "master", HeadSHA: "389d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name3", }, { Number: 4, + Title: "PR four", Branch: "four", TargetBranch: "master", HeadSHA: "489d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name4", }, }, nil, @@ -159,7 +186,7 @@ func TestMultiFilterOr(t *testing.T) { }, } pullRequests, err := ListPullRequests(context.Background(), provider, filters) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, pullRequests, 3) assert.Equal(t, "two", pullRequests[0].Branch) assert.Equal(t, "three", pullRequests[1].Branch) @@ -172,27 +199,35 @@ func TestMultiFilterOrWithTargetBranchFilter(t *testing.T) { []*PullRequest{ { Number: 1, + Title: "PR one", Branch: "one", TargetBranch: "master", HeadSHA: "189d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name1", }, { Number: 2, + Title: "PR two", Branch: "two", TargetBranch: "branch1", HeadSHA: "289d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name2", }, { Number: 3, + Title: "PR three", Branch: "three", TargetBranch: "branch2", HeadSHA: "389d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name3", }, { Number: 4, + Title: "PR four", Branch: "four", TargetBranch: "branch3", HeadSHA: "489d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name4", }, }, nil, @@ -208,7 +243,7 @@ func TestMultiFilterOrWithTargetBranchFilter(t *testing.T) { }, } pullRequests, err := ListPullRequests(context.Background(), provider, filters) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, pullRequests, 2) assert.Equal(t, "two", pullRequests[0].Branch) assert.Equal(t, "four", pullRequests[1].Branch) @@ -220,22 +255,26 @@ func TestNoFilters(t *testing.T) { []*PullRequest{ { Number: 1, + Title: "PR one", Branch: "one", TargetBranch: "master", HeadSHA: "189d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name1", }, { Number: 2, + Title: "PR two", Branch: "two", TargetBranch: "master", HeadSHA: "289d92cbf9ff857a39e6feccd32798ca700fb958", + Author: "name2", }, }, nil, ) filters := []argoprojiov1alpha1.PullRequestGeneratorFilter{} repos, err := ListPullRequests(context.Background(), provider, filters) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 2) assert.Equal(t, "one", repos[0].Branch) assert.Equal(t, "two", repos[1].Branch) diff --git a/applicationset/services/repo_service.go b/applicationset/services/repo_service.go index 1baad1f97ff2b..f415a9a6d1d7c 100644 --- a/applicationset/services/repo_service.go +++ b/applicationset/services/repo_service.go @@ -18,8 +18,6 @@ type argoCDService struct { newFileGlobbingEnabled bool } -//go:generate go run github.com/vektra/mockery/v2@v2.40.2 --name=Repos - type Repos interface { // GetFiles returns content of files (not directories) within the target repo GetFiles(ctx context.Context, repoURL string, revision string, pattern string, noRevisionCache, verifyCommit bool) (map[string][]byte, error) diff --git a/applicationset/services/repo_service_test.go b/applicationset/services/repo_service_test.go index 7660502130ce5..c621c317a9f4f 100644 --- a/applicationset/services/repo_service_test.go +++ b/applicationset/services/repo_service_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" repo_mocks "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" @@ -190,6 +191,6 @@ func TestNewArgoCDService(t *testing.T) { service, err := NewArgoCDService(func(ctx context.Context, url, project string) (*v1alpha1.Repository, error) { return &v1alpha1.Repository{}, nil }, false, &repo_mocks.Clientset{}, false) - assert.NoError(t, err, err) + require.NoError(t, err) assert.NotNil(t, service) } diff --git a/applicationset/services/scm_provider/aws_codecommit/mocks/AWSCodeCommitClient.go b/applicationset/services/scm_provider/aws_codecommit/mocks/AWSCodeCommitClient.go index b9d6f6a5d5956..0595bc425a8fc 100644 --- a/applicationset/services/scm_provider/aws_codecommit/mocks/AWSCodeCommitClient.go +++ b/applicationset/services/scm_provider/aws_codecommit/mocks/AWSCodeCommitClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.26.1. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks @@ -17,14 +17,6 @@ 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 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)) @@ -36,6 +28,10 @@ func (_m *AWSCodeCommitClient) GetFolderWithContext(_a0 context.Context, _a1 *co _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 { @@ -58,43 +54,6 @@ func (_m *AWSCodeCommitClient) GetFolderWithContext(_a0 context.Context, _a1 *co 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 -// - _a0 context.Context -// - _a1 *codecommit.GetFolderInput -// - _a2 ...request.Option -func (_e *AWSCodeCommitClient_Expecter) GetFolderWithContext(_a0 interface{}, _a1 interface{}, _a2 ...interface{}) *AWSCodeCommitClient_GetFolderWithContext_Call { - return &AWSCodeCommitClient_GetFolderWithContext_Call{Call: _e.mock.On("GetFolderWithContext", - append([]interface{}{_a0, _a1}, _a2...)...)} -} - -func (_c *AWSCodeCommitClient_GetFolderWithContext_Call) Run(run func(_a0 context.Context, _a1 *codecommit.GetFolderInput, _a2 ...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].(context.Context), args[1].(*codecommit.GetFolderInput), variadicArgs...) - }) - return _c -} - -func (_c *AWSCodeCommitClient_GetFolderWithContext_Call) Return(_a0 *codecommit.GetFolderOutput, _a1 error) *AWSCodeCommitClient_GetFolderWithContext_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *AWSCodeCommitClient_GetFolderWithContext_Call) RunAndReturn(run func(context.Context, *codecommit.GetFolderInput, ...request.Option) (*codecommit.GetFolderOutput, error)) *AWSCodeCommitClient_GetFolderWithContext_Call { - _c.Call.Return(run) - return _c -} - // 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)) @@ -106,6 +65,10 @@ func (_m *AWSCodeCommitClient) GetRepositoryWithContext(_a0 context.Context, _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 { @@ -128,43 +91,6 @@ func (_m *AWSCodeCommitClient) GetRepositoryWithContext(_a0 context.Context, _a1 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 -// - _a0 context.Context -// - _a1 *codecommit.GetRepositoryInput -// - _a2 ...request.Option -func (_e *AWSCodeCommitClient_Expecter) GetRepositoryWithContext(_a0 interface{}, _a1 interface{}, _a2 ...interface{}) *AWSCodeCommitClient_GetRepositoryWithContext_Call { - return &AWSCodeCommitClient_GetRepositoryWithContext_Call{Call: _e.mock.On("GetRepositoryWithContext", - append([]interface{}{_a0, _a1}, _a2...)...)} -} - -func (_c *AWSCodeCommitClient_GetRepositoryWithContext_Call) Run(run func(_a0 context.Context, _a1 *codecommit.GetRepositoryInput, _a2 ...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].(context.Context), args[1].(*codecommit.GetRepositoryInput), variadicArgs...) - }) - return _c -} - -func (_c *AWSCodeCommitClient_GetRepositoryWithContext_Call) Return(_a0 *codecommit.GetRepositoryOutput, _a1 error) *AWSCodeCommitClient_GetRepositoryWithContext_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *AWSCodeCommitClient_GetRepositoryWithContext_Call) RunAndReturn(run func(context.Context, *codecommit.GetRepositoryInput, ...request.Option) (*codecommit.GetRepositoryOutput, error)) *AWSCodeCommitClient_GetRepositoryWithContext_Call { - _c.Call.Return(run) - return _c -} - // 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)) @@ -176,6 +102,10 @@ func (_m *AWSCodeCommitClient) ListBranchesWithContext(_a0 context.Context, _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 { @@ -198,43 +128,6 @@ func (_m *AWSCodeCommitClient) ListBranchesWithContext(_a0 context.Context, _a1 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 -// - _a0 context.Context -// - _a1 *codecommit.ListBranchesInput -// - _a2 ...request.Option -func (_e *AWSCodeCommitClient_Expecter) ListBranchesWithContext(_a0 interface{}, _a1 interface{}, _a2 ...interface{}) *AWSCodeCommitClient_ListBranchesWithContext_Call { - return &AWSCodeCommitClient_ListBranchesWithContext_Call{Call: _e.mock.On("ListBranchesWithContext", - append([]interface{}{_a0, _a1}, _a2...)...)} -} - -func (_c *AWSCodeCommitClient_ListBranchesWithContext_Call) Run(run func(_a0 context.Context, _a1 *codecommit.ListBranchesInput, _a2 ...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].(context.Context), args[1].(*codecommit.ListBranchesInput), variadicArgs...) - }) - return _c -} - -func (_c *AWSCodeCommitClient_ListBranchesWithContext_Call) Return(_a0 *codecommit.ListBranchesOutput, _a1 error) *AWSCodeCommitClient_ListBranchesWithContext_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *AWSCodeCommitClient_ListBranchesWithContext_Call) RunAndReturn(run func(context.Context, *codecommit.ListBranchesInput, ...request.Option) (*codecommit.ListBranchesOutput, error)) *AWSCodeCommitClient_ListBranchesWithContext_Call { - _c.Call.Return(run) - return _c -} - // 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)) @@ -246,6 +139,10 @@ func (_m *AWSCodeCommitClient) ListRepositoriesWithContext(_a0 context.Context, _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 { @@ -268,50 +165,12 @@ func (_m *AWSCodeCommitClient) ListRepositoriesWithContext(_a0 context.Context, 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 -// - _a0 context.Context -// - _a1 *codecommit.ListRepositoriesInput -// - _a2 ...request.Option -func (_e *AWSCodeCommitClient_Expecter) ListRepositoriesWithContext(_a0 interface{}, _a1 interface{}, _a2 ...interface{}) *AWSCodeCommitClient_ListRepositoriesWithContext_Call { - return &AWSCodeCommitClient_ListRepositoriesWithContext_Call{Call: _e.mock.On("ListRepositoriesWithContext", - append([]interface{}{_a0, _a1}, _a2...)...)} -} - -func (_c *AWSCodeCommitClient_ListRepositoriesWithContext_Call) Run(run func(_a0 context.Context, _a1 *codecommit.ListRepositoriesInput, _a2 ...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].(context.Context), args[1].(*codecommit.ListRepositoriesInput), variadicArgs...) - }) - return _c -} - -func (_c *AWSCodeCommitClient_ListRepositoriesWithContext_Call) Return(_a0 *codecommit.ListRepositoriesOutput, _a1 error) *AWSCodeCommitClient_ListRepositoriesWithContext_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *AWSCodeCommitClient_ListRepositoriesWithContext_Call) RunAndReturn(run func(context.Context, *codecommit.ListRepositoriesInput, ...request.Option) (*codecommit.ListRepositoriesOutput, error)) *AWSCodeCommitClient_ListRepositoriesWithContext_Call { - _c.Call.Return(run) - return _c -} - -type mockConstructorTestingTNewAWSCodeCommitClient interface { +// 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 { mock.TestingT Cleanup(func()) -} - -// 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. -func NewAWSCodeCommitClient(t mockConstructorTestingTNewAWSCodeCommitClient) *AWSCodeCommitClient { +}) *AWSCodeCommitClient { mock := &AWSCodeCommitClient{} mock.Mock.Test(t) diff --git a/applicationset/services/scm_provider/aws_codecommit/mocks/AWSTaggingClient.go b/applicationset/services/scm_provider/aws_codecommit/mocks/AWSTaggingClient.go index 9acd8979b7818..a029d785cc2fb 100644 --- a/applicationset/services/scm_provider/aws_codecommit/mocks/AWSTaggingClient.go +++ b/applicationset/services/scm_provider/aws_codecommit/mocks/AWSTaggingClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.26.1. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks @@ -16,14 +16,6 @@ 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 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)) @@ -35,6 +27,10 @@ func (_m *AWSTaggingClient) GetResourcesWithContext(_a0 context.Context, _a1 *re _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 { @@ -57,50 +53,12 @@ func (_m *AWSTaggingClient) GetResourcesWithContext(_a0 context.Context, _a1 *re 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 -// - _a0 context.Context -// - _a1 *resourcegroupstaggingapi.GetResourcesInput -// - _a2 ...request.Option -func (_e *AWSTaggingClient_Expecter) GetResourcesWithContext(_a0 interface{}, _a1 interface{}, _a2 ...interface{}) *AWSTaggingClient_GetResourcesWithContext_Call { - return &AWSTaggingClient_GetResourcesWithContext_Call{Call: _e.mock.On("GetResourcesWithContext", - append([]interface{}{_a0, _a1}, _a2...)...)} -} - -func (_c *AWSTaggingClient_GetResourcesWithContext_Call) Run(run func(_a0 context.Context, _a1 *resourcegroupstaggingapi.GetResourcesInput, _a2 ...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].(context.Context), args[1].(*resourcegroupstaggingapi.GetResourcesInput), variadicArgs...) - }) - return _c -} - -func (_c *AWSTaggingClient_GetResourcesWithContext_Call) Return(_a0 *resourcegroupstaggingapi.GetResourcesOutput, _a1 error) *AWSTaggingClient_GetResourcesWithContext_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *AWSTaggingClient_GetResourcesWithContext_Call) RunAndReturn(run func(context.Context, *resourcegroupstaggingapi.GetResourcesInput, ...request.Option) (*resourcegroupstaggingapi.GetResourcesOutput, error)) *AWSTaggingClient_GetResourcesWithContext_Call { - _c.Call.Return(run) - return _c -} - -type mockConstructorTestingTNewAWSTaggingClient interface { +// 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 { mock.TestingT Cleanup(func()) -} - -// 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. -func NewAWSTaggingClient(t mockConstructorTestingTNewAWSTaggingClient) *AWSTaggingClient { +}) *AWSTaggingClient { mock := &AWSTaggingClient{} mock.Mock.Test(t) diff --git a/applicationset/services/scm_provider/aws_codecommit_test.go b/applicationset/services/scm_provider/aws_codecommit_test.go index 42ef52a8369e3..00d8240973848 100644 --- a/applicationset/services/scm_provider/aws_codecommit_test.go +++ b/applicationset/services/scm_provider/aws_codecommit_test.go @@ -178,8 +178,8 @@ func TestAWSCodeCommitListRepos(t *testing.T) { if repo.getRepositoryNilMetadata { repoMetadata = nil } - codeCommitClient.EXPECT(). - GetRepositoryWithContext(ctx, &codecommit.GetRepositoryInput{RepositoryName: aws.String(repo.name)}). + codeCommitClient. + On("GetRepositoryWithContext", ctx, &codecommit.GetRepositoryInput{RepositoryName: aws.String(repo.name)}). Return(&codecommit.GetRepositoryOutput{RepositoryMetadata: repoMetadata}, repo.getRepositoryError) codecommitRepoNameIdPairs = append(codecommitRepoNameIdPairs, &codecommit.RepositoryNameIdPair{ RepositoryId: aws.String(repo.id), @@ -194,14 +194,14 @@ func TestAWSCodeCommitListRepos(t *testing.T) { } if testCase.expectListAtCodeCommit { - codeCommitClient.EXPECT(). - ListRepositoriesWithContext(ctx, &codecommit.ListRepositoriesInput{}). + codeCommitClient. + On("ListRepositoriesWithContext", ctx, &codecommit.ListRepositoriesInput{}). Return(&codecommit.ListRepositoriesOutput{ Repositories: codecommitRepoNameIdPairs, }, testCase.listRepositoryError) } else { - taggingClient.EXPECT(). - GetResourcesWithContext(ctx, mock.MatchedBy(equalIgnoringTagFilterOrder(&resourcegroupstaggingapi.GetResourcesInput{ + taggingClient. + On("GetResourcesWithContext", ctx, mock.MatchedBy(equalIgnoringTagFilterOrder(&resourcegroupstaggingapi.GetResourcesInput{ TagFilters: testCase.expectTagFilters, ResourceTypeFilters: aws.StringSlice([]string{resourceTypeCodeCommitRepository}), }))). @@ -351,8 +351,8 @@ func TestAWSCodeCommitRepoHasPath(t *testing.T) { taggingClient := mocks.NewAWSTaggingClient(t) ctx := context.Background() if testCase.expectedGetFolderPath != "" { - codeCommitClient.EXPECT(). - GetFolderWithContext(ctx, &codecommit.GetFolderInput{ + codeCommitClient. + On("GetFolderWithContext", ctx, &codecommit.GetFolderInput{ CommitSpecifier: aws.String(branch), FolderPath: aws.String(testCase.expectedGetFolderPath), RepositoryName: aws.String(repoName), @@ -424,14 +424,14 @@ func TestAWSCodeCommitGetBranches(t *testing.T) { taggingClient := mocks.NewAWSTaggingClient(t) ctx := context.Background() if testCase.allBranches { - codeCommitClient.EXPECT(). - ListBranchesWithContext(ctx, &codecommit.ListBranchesInput{ + codeCommitClient. + On("ListBranchesWithContext", ctx, &codecommit.ListBranchesInput{ RepositoryName: aws.String(name), }). Return(&codecommit.ListBranchesOutput{Branches: aws.StringSlice(testCase.branches)}, testCase.apiError) } else { - codeCommitClient.EXPECT(). - GetRepositoryWithContext(ctx, &codecommit.GetRepositoryInput{RepositoryName: aws.String(name)}). + codeCommitClient. + On("GetRepositoryWithContext", ctx, &codecommit.GetRepositoryInput{RepositoryName: aws.String(name)}). Return(&codecommit.GetRepositoryOutput{RepositoryMetadata: &codecommit.RepositoryMetadata{ AccountId: aws.String(organization), DefaultBranch: aws.String(defaultBranch), 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 902859672cd0e..c3cf024d882fe 100644 --- a/applicationset/services/scm_provider/azure_devops/git/mocks/Client.go +++ b/applicationset/services/scm_provider/azure_devops/git/mocks/Client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.40.2. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks diff --git a/applicationset/services/scm_provider/azure_devops_test.go b/applicationset/services/scm_provider/azure_devops_test.go index aa9e48582c5a2..d718802ad3295 100644 --- a/applicationset/services/scm_provider/azure_devops_test.go +++ b/applicationset/services/scm_provider/azure_devops_test.go @@ -8,6 +8,7 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" "k8s.io/utils/ptr" "github.com/microsoft/azure-devops-go-api/azuredevops" @@ -16,8 +17,6 @@ import ( azureMock "github.com/argoproj/argo-cd/v2/applicationset/services/scm_provider/azure_devops/git/mocks" ) -//go:generate go run github.com/vektra/mockery/v2@v2.40.2 --srcpkg=github.com/microsoft/azure-devops-go-api/azuredevops/git --name=Client --output=azure_devops/git/mocks --outpkg=mocks - func s(input string) *string { return ptr.To(input) } @@ -92,14 +91,14 @@ func TestAzureDevopsRepoHasPath(t *testing.T) { hasPath, err := provider.RepoHasPath(ctx, repo, path) if testCase.clientError != nil { - assert.ErrorContains(t, err, testCase.clientError.Error()) + require.ErrorContains(t, err, testCase.clientError.Error()) gitClientMock.AssertNotCalled(t, "GetItem", ctx, azureGit.GetItemArgs{Project: &teamProject, Path: &path, VersionDescriptor: &azureGit.GitVersionDescriptor{Version: &branchName}, RepositoryId: repoId}) return } if testCase.returnError { - assert.ErrorContains(t, err, testCase.errorMessage) + require.ErrorContains(t, err, testCase.errorMessage) } assert.Equal(t, testCase.pathFound, hasPath) @@ -156,9 +155,9 @@ func TestGetDefaultBranchOnDisabledRepo(t *testing.T) { branches, err := provider.GetBranches(ctx, repo) if testCase.shouldReturnError { - assert.Error(t, err) + require.Error(t, err) } else { - assert.NoError(t, err) + require.NoError(t, err) } assert.Empty(t, branches) @@ -215,9 +214,9 @@ func TestGetAllBranchesOnDisabledRepo(t *testing.T) { branches, err := provider.GetBranches(ctx, repo) if testCase.shouldReturnError { - assert.Error(t, err) + require.Error(t, err) } else { - assert.NoError(t, err) + require.NoError(t, err) } assert.Empty(t, branches) @@ -251,7 +250,7 @@ func TestAzureDevOpsGetDefaultBranchStripsRefsName(t *testing.T) { provider := AzureDevOpsProvider{organization: organization, teamProject: teamProject, clientFactory: clientFactoryMock, allBranches: false} branches, err := provider.GetBranches(ctx, repo) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, branches, 1) assert.Equal(t, strippedBranchName, branches[0].Branch) @@ -308,7 +307,7 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) { branches, err := provider.GetBranches(ctx, repo) if testCase.clientError != nil { - assert.ErrorContains(t, err, testCase.clientError.Error()) + require.ErrorContains(t, err, testCase.clientError.Error()) gitClientMock.AssertNotCalled(t, "GetBranch", ctx, azureGit.GetBranchArgs{RepositoryId: &repoName, Project: &teamProject, Name: &defaultBranch}) return @@ -316,7 +315,7 @@ func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) { if testCase.getBranchesApiError != nil { assert.Empty(t, branches) - assert.ErrorContains(t, err, testCase.getBranchesApiError.Error()) + require.ErrorContains(t, err, testCase.getBranchesApiError.Error()) } else { if testCase.expectedBranch != nil { assert.NotEmpty(t, branches) @@ -392,20 +391,20 @@ func TestAzureDevopsGetBranches(t *testing.T) { branches, err := provider.GetBranches(ctx, repo) if testCase.expectedProcessingErrorMsg != "" { - assert.ErrorContains(t, err, testCase.expectedProcessingErrorMsg) + require.ErrorContains(t, err, testCase.expectedProcessingErrorMsg) assert.Nil(t, branches) return } if testCase.clientError != nil { - assert.ErrorContains(t, err, testCase.clientError.Error()) + require.ErrorContains(t, err, testCase.clientError.Error()) gitClientMock.AssertNotCalled(t, "GetBranches", ctx, azureGit.GetBranchesArgs{RepositoryId: &repoName, Project: &teamProject}) return } if testCase.getBranchesApiError != nil { assert.Empty(t, branches) - assert.ErrorContains(t, err, testCase.getBranchesApiError.Error()) + require.ErrorContains(t, err, testCase.getBranchesApiError.Error()) } else { if len(*testCase.expectedBranches) > 0 { assert.NotEmpty(t, branches) @@ -488,7 +487,7 @@ func TestGetAzureDevopsRepositories(t *testing.T) { repositories, err := provider.ListRepos(ctx, "https") if testCase.getRepositoriesError != nil { - assert.Error(t, err, "Expected an error from test case %v", testCase.name) + require.Error(t, err, "Expected an error from test case %v", testCase.name) } if testCase.expectedNumberOfRepos == 0 { diff --git a/applicationset/services/scm_provider/bitbucket_cloud.go b/applicationset/services/scm_provider/bitbucket_cloud.go index da8f3fea54c54..4468aee687f7d 100644 --- a/applicationset/services/scm_provider/bitbucket_cloud.go +++ b/applicationset/services/scm_provider/bitbucket_cloud.go @@ -46,7 +46,7 @@ func (c *ExtendedClient) GetContents(repo *Repository, path string) (bool, error return true, nil } - return false, fmt.Errorf(resp.Status) + return false, fmt.Errorf("%s", resp.Status) } var _ SCMProviderService = &BitBucketCloudProvider{} diff --git a/applicationset/services/scm_provider/bitbucket_cloud_test.go b/applicationset/services/scm_provider/bitbucket_cloud_test.go index dc7732e9f6850..d4127dbbf4002 100644 --- a/applicationset/services/scm_provider/bitbucket_cloud_test.go +++ b/applicationset/services/scm_provider/bitbucket_cloud_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) @@ -18,7 +19,7 @@ func TestBitbucketHasRepo(t *testing.T) { res.WriteHeader(http.StatusNotFound) _, err := res.Write([]byte("")) if err != nil { - assert.NoError(t, fmt.Errorf("Error in mock response %w", err)) + require.NoError(t, fmt.Errorf("Error in mock response %w", err)) } } if req.URL.Path == "/repositories/test-owner/testmike/src/dc1edb6c7d650d8ba67719ddf7b662ad8f8fb798/.gitignore" { @@ -55,7 +56,7 @@ func TestBitbucketHasRepo(t *testing.T) { "size": 624 }`)) if err != nil { - assert.NoError(t, fmt.Errorf("Error in mock response %w", err)) + require.NoError(t, fmt.Errorf("Error in mock response %w", err)) } } })) @@ -95,7 +96,7 @@ func TestBitbucketHasRepo(t *testing.T) { } hasPath, err := provider.RepoHasPath(context.Background(), repo, c.path) if err != nil { - assert.Error(t, fmt.Errorf("Error in test %w", err)) + require.Error(t, fmt.Errorf("Error in test %w", err)) } if c.status != http.StatusOK { assert.False(t, hasPath) @@ -208,7 +209,7 @@ func TestBitbucketListRepos(t *testing.T) { "size": 1 }`)) if err != nil { - assert.NoError(t, fmt.Errorf("Error in mock response %w", err)) + require.NoError(t, fmt.Errorf("Error in mock response %w", err)) } } if req.URL.Path == "/repositories/test-owner/testmike/refs/branches/main" { @@ -303,7 +304,7 @@ func TestBitbucketListRepos(t *testing.T) { } }`)) if err != nil { - assert.NoError(t, fmt.Errorf("Error in mock response %w", err)) + require.NoError(t, fmt.Errorf("Error in mock response %w", err)) } } if req.URL.Path == "/repositories/test-owner" { @@ -442,7 +443,7 @@ func TestBitbucketListRepos(t *testing.T) { "size": 1 }`)) if err != nil { - assert.NoError(t, fmt.Errorf("Error in mock response %w", err)) + require.NoError(t, fmt.Errorf("Error in mock response %w", err)) } } })) @@ -489,9 +490,9 @@ func TestBitbucketListRepos(t *testing.T) { provider, _ := NewBitBucketCloudProvider(context.Background(), c.owner, "user", "password", c.allBranches) rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto) if c.hasError { - assert.Error(t, err) + require.Error(t, err) } else { - assert.NoError(t, err) + require.NoError(t, err) repos := []*Repository{} branches := []string{} for _, r := range rawRepos { diff --git a/applicationset/services/scm_provider/bitbucket_server.go b/applicationset/services/scm_provider/bitbucket_server.go index d1b66c89a66c3..4f723a547059f 100644 --- a/applicationset/services/scm_provider/bitbucket_server.go +++ b/applicationset/services/scm_provider/bitbucket_server.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "net/http" bitbucketv1 "github.com/gfleury/go-bitbucket-v1" log "github.com/sirupsen/logrus" @@ -20,7 +21,7 @@ type BitbucketServerProvider struct { var _ SCMProviderService = &BitbucketServerProvider{} -func NewBitbucketServerProviderBasicAuth(ctx context.Context, username, password, url, projectKey string, allBranches bool) (*BitbucketServerProvider, error) { +func NewBitbucketServerProviderBasicAuth(ctx context.Context, username, password, url, projectKey string, allBranches bool, scmRootCAPath string, insecure bool, caCerts []byte) (*BitbucketServerProvider, error) { bitbucketConfig := bitbucketv1.NewConfiguration(url) // Avoid the XSRF check bitbucketConfig.AddDefaultHeader("x-atlassian-token", "no-check") @@ -30,15 +31,29 @@ func NewBitbucketServerProviderBasicAuth(ctx context.Context, username, password UserName: username, Password: password, }) - return newBitbucketServerProvider(ctx, bitbucketConfig, projectKey, allBranches) + return newBitbucketServerProvider(ctx, bitbucketConfig, projectKey, allBranches, scmRootCAPath, insecure, caCerts) } -func NewBitbucketServerProviderNoAuth(ctx context.Context, url, projectKey string, allBranches bool) (*BitbucketServerProvider, error) { - return newBitbucketServerProvider(ctx, bitbucketv1.NewConfiguration(url), projectKey, allBranches) +func NewBitbucketServerProviderBearerToken(ctx context.Context, bearerToken, url, projectKey string, allBranches bool, scmRootCAPath string, insecure bool, caCerts []byte) (*BitbucketServerProvider, error) { + bitbucketConfig := bitbucketv1.NewConfiguration(url) + // Avoid the XSRF check + bitbucketConfig.AddDefaultHeader("x-atlassian-token", "no-check") + bitbucketConfig.AddDefaultHeader("x-requested-with", "XMLHttpRequest") + + ctx = context.WithValue(ctx, bitbucketv1.ContextAccessToken, bearerToken) + return newBitbucketServerProvider(ctx, bitbucketConfig, projectKey, allBranches, scmRootCAPath, insecure, caCerts) +} + +func NewBitbucketServerProviderNoAuth(ctx context.Context, url, projectKey string, allBranches bool, scmRootCAPath string, insecure bool, caCerts []byte) (*BitbucketServerProvider, error) { + return newBitbucketServerProvider(ctx, bitbucketv1.NewConfiguration(url), projectKey, allBranches, scmRootCAPath, insecure, caCerts) } -func newBitbucketServerProvider(ctx context.Context, bitbucketConfig *bitbucketv1.Configuration, projectKey string, allBranches bool) (*BitbucketServerProvider, error) { +func newBitbucketServerProvider(ctx context.Context, bitbucketConfig *bitbucketv1.Configuration, projectKey string, allBranches bool, scmRootCAPath string, insecure bool, caCerts []byte) (*BitbucketServerProvider, error) { bitbucketConfig.BasePath = utils.NormalizeBitbucketBasePath(bitbucketConfig.BasePath) + tlsConfig := utils.GetTlsConfig(scmRootCAPath, insecure, caCerts) + bitbucketConfig.HTTPClient = &http.Client{Transport: &http.Transport{ + TLSClientConfig: tlsConfig, + }} bitbucketClient := bitbucketv1.NewAPIClient(ctx, bitbucketConfig) return &BitbucketServerProvider{ diff --git a/applicationset/services/scm_provider/bitbucket_server_test.go b/applicationset/services/scm_provider/bitbucket_server_test.go index e1990b8d116a2..1d399f8751cbc 100644 --- a/applicationset/services/scm_provider/bitbucket_server_test.go +++ b/applicationset/services/scm_provider/bitbucket_server_test.go @@ -2,12 +2,15 @@ package scm_provider import ( "context" + "crypto/x509" + "encoding/pem" "io" "net/http" "net/http/httptest" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func defaultHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { @@ -79,7 +82,7 @@ func defaultHandler(t *testing.T) func(http.ResponseWriter, *http.Request) { } func verifyDefaultRepo(t *testing.T, err error, repos []*Repository) { - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 1) assert.Equal(t, Repository{ Organization: "PROJECT", @@ -98,8 +101,8 @@ func TestListReposNoAuth(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true) - assert.NoError(t, err) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil) + require.NoError(t, err) repos, err := provider.ListRepos(context.Background(), "ssh") verifyDefaultRepo(t, err, repos) } @@ -190,10 +193,10 @@ func TestListReposPagination(t *testing.T) { } })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true) - assert.NoError(t, err) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil) + require.NoError(t, err) repos, err := provider.ListRepos(context.Background(), "ssh") - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 2) assert.Equal(t, Repository{ Organization: "PROJECT", @@ -267,8 +270,8 @@ func TestGetBranchesBranchPagination(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true) - assert.NoError(t, err) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil) + require.NoError(t, err) repos, err := provider.GetBranches(context.Background(), &Repository{ Organization: "PROJECT", Repository: "REPO", @@ -276,7 +279,7 @@ func TestGetBranchesBranchPagination(t *testing.T) { Labels: []string{}, RepositoryId: 1, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 2) assert.Equal(t, Repository{ Organization: "PROJECT", @@ -320,8 +323,8 @@ func TestGetBranchesDefaultOnly(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false) - assert.NoError(t, err) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) + require.NoError(t, err) repos, err := provider.GetBranches(context.Background(), &Repository{ Organization: "PROJECT", Repository: "REPO", @@ -329,7 +332,7 @@ func TestGetBranchesDefaultOnly(t *testing.T) { Labels: []string{}, RepositoryId: 1, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 1) assert.Equal(t, Repository{ Organization: "PROJECT", @@ -352,8 +355,8 @@ func TestGetBranchesMissingDefault(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false) - assert.NoError(t, err) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) + require.NoError(t, err) repos, err := provider.GetBranches(context.Background(), &Repository{ Organization: "PROJECT", Repository: "REPO", @@ -361,7 +364,7 @@ func TestGetBranchesMissingDefault(t *testing.T) { Labels: []string{}, RepositoryId: 1, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Empty(t, repos) } @@ -374,8 +377,8 @@ func TestGetBranchesEmptyRepo(t *testing.T) { } })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false) - assert.NoError(t, err) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) + require.NoError(t, err) repos, err := provider.GetBranches(context.Background(), &Repository{ Organization: "PROJECT", Repository: "REPO", @@ -384,7 +387,7 @@ func TestGetBranchesEmptyRepo(t *testing.T) { RepositoryId: 1, }) assert.Empty(t, repos) - assert.NoError(t, err) + require.NoError(t, err) } func TestGetBranchesErrorDefaultBranch(t *testing.T) { @@ -397,8 +400,8 @@ func TestGetBranchesErrorDefaultBranch(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false) - assert.NoError(t, err) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) + require.NoError(t, err) _, err = provider.GetBranches(context.Background(), &Repository{ Organization: "PROJECT", Repository: "REPO", @@ -406,7 +409,74 @@ func TestGetBranchesErrorDefaultBranch(t *testing.T) { Labels: []string{}, RepositoryId: 1, }) - assert.Error(t, err) + require.Error(t, err) +} + +func TestListReposTLS(t *testing.T) { + tests := []struct { + name string + tlsInsecure bool + passCerts bool + requireErr bool + }{ + { + name: "TLS Insecure: true, No Certs", + tlsInsecure: true, + passCerts: false, + requireErr: false, + }, + { + name: "TLS Insecure: true, With Certs", + tlsInsecure: true, + passCerts: true, + requireErr: false, + }, + { + name: "TLS Insecure: false, With Certs", + tlsInsecure: false, + passCerts: true, + requireErr: false, + }, + { + name: "TLS Insecure: false, No Certs", + tlsInsecure: false, + passCerts: false, + requireErr: true, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defaultHandler(t)(w, r) + })) + defer ts.Close() + + var certs []byte + if test.passCerts == true { + for _, cert := range ts.TLS.Certificates { + for _, c := range cert.Certificate { + parsedCert, err := x509.ParseCertificate(c) + require.NoError(t, err, "Failed to parse certificate") + certs = append(certs, pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: parsedCert.Raw, + })...) + } + } + } + + provider, err := NewBitbucketServerProviderBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", true, "", test.tlsInsecure, certs) + require.NoError(t, err) + _, err = provider.ListRepos(context.Background(), "ssh") + if test.requireErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } } func TestListReposBasicAuth(t *testing.T) { @@ -416,8 +486,21 @@ func TestListReposBasicAuth(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", true) - assert.NoError(t, err) + provider, err := NewBitbucketServerProviderBasicAuth(context.Background(), "user", "password", ts.URL, "PROJECT", true, "", false, nil) + require.NoError(t, err) + repos, err := provider.ListRepos(context.Background(), "ssh") + verifyDefaultRepo(t, err, repos) +} + +func TestListReposBearerAuth(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "Bearer tolkien", r.Header.Get("Authorization")) + assert.Equal(t, "no-check", r.Header.Get("X-Atlassian-Token")) + defaultHandler(t)(w, r) + })) + defer ts.Close() + provider, err := NewBitbucketServerProviderBearerToken(context.Background(), "tolkien", ts.URL, "PROJECT", true, "", false, nil) + require.NoError(t, err) repos, err := provider.ListRepos(context.Background(), "ssh") verifyDefaultRepo(t, err, repos) } @@ -443,10 +526,10 @@ func TestListReposDefaultBranch(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false) - assert.NoError(t, err) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) + require.NoError(t, err) repos, err := provider.ListRepos(context.Background(), "ssh") - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 1) assert.Equal(t, Repository{ Organization: "PROJECT", @@ -469,10 +552,10 @@ func TestListReposMissingDefaultBranch(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false) - assert.NoError(t, err) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) + require.NoError(t, err) repos, err := provider.ListRepos(context.Background(), "ssh") - assert.NoError(t, err) + require.NoError(t, err) assert.Empty(t, repos) } @@ -486,10 +569,10 @@ func TestListReposErrorDefaultBranch(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false) - assert.NoError(t, err) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", false, "", false, nil) + require.NoError(t, err) _, err = provider.ListRepos(context.Background(), "ssh") - assert.Error(t, err) + require.Error(t, err) } func TestListReposCloneProtocol(t *testing.T) { @@ -498,10 +581,10 @@ func TestListReposCloneProtocol(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true) - assert.NoError(t, err) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil) + require.NoError(t, err) repos, err := provider.ListRepos(context.Background(), "https") - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 1) assert.Equal(t, Repository{ Organization: "PROJECT", @@ -520,10 +603,10 @@ func TestListReposUnknownProtocol(t *testing.T) { defaultHandler(t)(w, r) })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true) - assert.NoError(t, err) + provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true, "", false, nil) + require.NoError(t, err) _, errProtocol := provider.ListRepos(context.Background(), "http") - assert.Error(t, errProtocol) + require.Error(t, errProtocol) } func TestBitbucketServerHasPath(t *testing.T) { @@ -558,37 +641,37 @@ func TestBitbucketServerHasPath(t *testing.T) { } })) defer ts.Close() - provider, err := NewBitbucketServerProviderNoAuth(context.Background(), ts.URL, "PROJECT", true) - assert.NoError(t, err) + 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(context.Background(), repo, "pkg") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, ok) ok, err = provider.RepoHasPath(context.Background(), repo, "pkg/") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, ok) ok, err = provider.RepoHasPath(context.Background(), repo, "anotherpkg/file.txt") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, ok) ok, err = provider.RepoHasPath(context.Background(), repo, "anotherpkg/missing.txt") - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, ok) ok, err = provider.RepoHasPath(context.Background(), repo, "notathing") - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, ok) ok, err = provider.RepoHasPath(context.Background(), repo, "return-redirect") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, ok) _, err = provider.RepoHasPath(context.Background(), repo, "unauthorized-response") - assert.Error(t, err) + require.Error(t, err) } diff --git a/applicationset/services/scm_provider/gitea_test.go b/applicationset/services/scm_provider/gitea_test.go index fedbe22d986c4..231913761014b 100644 --- a/applicationset/services/scm_provider/gitea_test.go +++ b/applicationset/services/scm_provider/gitea_test.go @@ -306,9 +306,9 @@ func TestGiteaListRepos(t *testing.T) { provider, _ := NewGiteaProvider(context.Background(), "test-argocd", "", ts.URL, c.allBranches, false) rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto) if c.hasError { - assert.Error(t, err) + require.Error(t, err) } else { - assert.NoError(t, err) + require.NoError(t, err) // Just check that this one project shows up. Not a great test but better thing nothing? repos := []*Repository{} branches := []string{} @@ -342,19 +342,19 @@ func TestGiteaHasPath(t *testing.T) { t.Run("file exists", func(t *testing.T) { ok, err := host.RepoHasPath(context.Background(), repo, "README.md") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, ok) }) t.Run("directory exists", func(t *testing.T) { ok, err := host.RepoHasPath(context.Background(), repo, "gitea") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, ok) }) t.Run("does not exists", func(t *testing.T) { ok, err := host.RepoHasPath(context.Background(), repo, "notathing") - assert.NoError(t, err) + 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 1a6edae5837e9..9d7457c47b990 100644 --- a/applicationset/services/scm_provider/github.go +++ b/applicationset/services/scm_provider/github.go @@ -2,12 +2,11 @@ package scm_provider import ( "context" - "errors" "fmt" "net/http" "os" - "github.com/google/go-github/v35/github" + "github.com/google/go-github/v63/github" "golang.org/x/oauth2" ) @@ -36,7 +35,7 @@ func NewGithubProvider(ctx context.Context, organization string, token string, u client = github.NewClient(httpClient) } else { var err error - client, err = github.NewEnterpriseClient(url, url, httpClient) + client, err = github.NewClient(httpClient).WithEnterpriseURLs(url, url) if err != nil { return nil, err } @@ -120,14 +119,11 @@ func (g *GithubProvider) RepoHasPath(ctx context.Context, repo *Repository, path func (g *GithubProvider) listBranches(ctx context.Context, repo *Repository) ([]github.Branch, error) { // If we don't specifically want to query for all branches, just use the default branch and call it a day. if !g.allBranches { - defaultBranch, _, err := g.client.Repositories.GetBranch(ctx, repo.Organization, repo.Repository, repo.Branch) + defaultBranch, resp, err := g.client.Repositories.GetBranch(ctx, repo.Organization, repo.Repository, repo.Branch, 0) if err != nil { - var githubErrorResponse *github.ErrorResponse - if errors.As(err, &githubErrorResponse) { - if githubErrorResponse.Response.StatusCode == http.StatusNotFound { - // Default branch doesn't exist, so the repo is empty. - return []github.Branch{}, nil - } + if resp.StatusCode == http.StatusNotFound { + // Default branch doesn't exist, so the repo is empty. + return []github.Branch{}, nil } return nil, err } diff --git a/applicationset/services/scm_provider/github_test.go b/applicationset/services/scm_provider/github_test.go index b9f576617135c..03b59c801721a 100644 --- a/applicationset/services/scm_provider/github_test.go +++ b/applicationset/services/scm_provider/github_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) @@ -244,9 +245,9 @@ func TestGithubListRepos(t *testing.T) { provider, _ := NewGithubProvider(context.Background(), "argoproj", "", ts.URL, c.allBranches) rawRepos, err := ListRepos(context.Background(), provider, c.filters, c.proto) if c.hasError { - assert.Error(t, err) + require.Error(t, err) } else { - assert.NoError(t, err) + require.NoError(t, err) // Just check that this one project shows up. Not a great test but better thing nothing? repos := []*Repository{} branches := []string{} @@ -278,11 +279,11 @@ func TestGithubHasPath(t *testing.T) { Branch: "master", } ok, err := host.RepoHasPath(context.Background(), repo, "pkg/") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, ok) ok, err = host.RepoHasPath(context.Background(), repo, "notathing/") - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, ok) } @@ -299,7 +300,7 @@ func TestGithubGetBranches(t *testing.T) { } repos, err := host.GetBranches(context.Background(), repo) if err != nil { - assert.NoError(t, err) + require.NoError(t, err) } else { assert.Equal(t, "master", repos[0].Branch) } @@ -310,13 +311,13 @@ func TestGithubGetBranches(t *testing.T) { Branch: "main", } _, err = host.GetBranches(context.Background(), repo2) - assert.NoError(t, err) + require.NoError(t, err) // Get all branches host.allBranches = true repos, err = host.GetBranches(context.Background(), repo) if err != nil { - assert.NoError(t, err) + require.NoError(t, err) } else { // considering master branch to exist. assert.Len(t, repos, 1) diff --git a/applicationset/services/scm_provider/gitlab.go b/applicationset/services/scm_provider/gitlab.go index 974be7bc21e16..0acc1898bf382 100644 --- a/applicationset/services/scm_provider/gitlab.go +++ b/applicationset/services/scm_provider/gitlab.go @@ -24,7 +24,7 @@ type GitlabProvider struct { var _ SCMProviderService = &GitlabProvider{} -func NewGitlabProvider(ctx context.Context, organization string, token string, url string, allBranches, includeSubgroups, includeSharedProjects, insecure bool, scmRootCAPath, topic string) (*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") @@ -32,7 +32,7 @@ func NewGitlabProvider(ctx context.Context, organization string, token string, u var client *gitlab.Client tr := http.DefaultTransport.(*http.Transport).Clone() - tr.TLSClientConfig = utils.GetTlsConfig(scmRootCAPath, insecure) + tr.TLSClientConfig = utils.GetTlsConfig(scmRootCAPath, insecure, caCerts) retryClient := retryablehttp.NewClient() retryClient.HTTPClient.Transport = tr diff --git a/applicationset/services/scm_provider/gitlab_test.go b/applicationset/services/scm_provider/gitlab_test.go index 0e8403b1663a6..12f2b8b377a2a 100644 --- a/applicationset/services/scm_provider/gitlab_test.go +++ b/applicationset/services/scm_provider/gitlab_test.go @@ -2,6 +2,8 @@ package scm_provider import ( "context" + "crypto/x509" + "encoding/pem" "fmt" "io" "net/http" @@ -9,6 +11,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) @@ -1120,12 +1123,12 @@ func TestGitlabListRepos(t *testing.T) { })) for _, c := range cases { t.Run(c.name, func(t *testing.T) { - provider, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, c.allBranches, c.includeSubgroups, c.includeSharedProjects, c.insecure, "", c.topic) + 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 { - assert.Error(t, err) + require.Error(t, err) } else { - assert.NoError(t, err) + require.NoError(t, err) // Just check that this one project shows up. Not a great test but better than nothing? repos := []*Repository{} uniqueRepos := map[string]int{} @@ -1159,7 +1162,7 @@ func TestGitlabHasPath(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { gitlabMockHandler(t)(w, r) })) - host, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, false, true, true, false, "", "") + host, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, false, true, true, false, "", "", nil) repo := &Repository{ Organization: "test-argocd-proton", Repository: "argocd", @@ -1195,7 +1198,7 @@ func TestGitlabHasPath(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { ok, err := host.RepoHasPath(context.Background(), repo, c.path) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, c.exists, ok) }) } @@ -1205,7 +1208,7 @@ func TestGitlabGetBranches(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { gitlabMockHandler(t)(w, r) })) - host, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, false, true, true, false, "", "") + host, _ := NewGitlabProvider(context.Background(), "test-argocd-proton", "", ts.URL, false, true, true, false, "", "", nil) repo := &Repository{ RepositoryId: 27084533, @@ -1213,7 +1216,7 @@ func TestGitlabGetBranches(t *testing.T) { } t.Run("branch exists", func(t *testing.T) { repos, err := host.GetBranches(context.Background(), repo) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "master", repos[0].Branch) }) @@ -1223,6 +1226,77 @@ func TestGitlabGetBranches(t *testing.T) { } t.Run("unknown branch", func(t *testing.T) { _, err := host.GetBranches(context.Background(), repo2) - assert.NoError(t, err) + require.NoError(t, err) }) } + +func TestGetBranchesTLS(t *testing.T) { + tests := []struct { + name string + tlsInsecure bool + passCerts bool + requireErr bool + }{ + { + name: "TLS Insecure: true, No Certs", + tlsInsecure: true, + passCerts: false, + requireErr: false, + }, + { + name: "TLS Insecure: true, With Certs", + tlsInsecure: true, + passCerts: true, + requireErr: false, + }, + { + name: "TLS Insecure: false, With Certs", + tlsInsecure: false, + passCerts: true, + requireErr: false, + }, + { + name: "TLS Insecure: false, No Certs", + tlsInsecure: false, + passCerts: false, + requireErr: true, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + gitlabMockHandler(t)(w, r) + })) + defer ts.Close() + + var certs []byte + if test.passCerts == true { + for _, cert := range ts.TLS.Certificates { + for _, c := range cert.Certificate { + parsedCert, err := x509.ParseCertificate(c) + require.NoError(t, err, "Failed to parse certificate") + certs = append(certs, pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: parsedCert.Raw, + })...) + } + } + } + + 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(context.Background(), repo) + if test.requireErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/applicationset/services/scm_provider/utils_test.go b/applicationset/services/scm_provider/utils_test.go index 452148a34b633..83c6c4fc23d9e 100644 --- a/applicationset/services/scm_provider/utils_test.go +++ b/applicationset/services/scm_provider/utils_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" ) @@ -37,7 +38,7 @@ func TestFilterRepoMatch(t *testing.T) { }, } repos, err := ListRepos(context.Background(), provider, filters, "") - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 2) assert.Equal(t, "one", repos[0].Repository) assert.Equal(t, "three", repos[1].Repository) @@ -66,7 +67,7 @@ func TestFilterLabelMatch(t *testing.T) { }, } repos, err := ListRepos(context.Background(), provider, filters, "") - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 2) assert.Equal(t, "one", repos[0].Repository) assert.Equal(t, "two", repos[1].Repository) @@ -92,7 +93,7 @@ func TestFilterPathExists(t *testing.T) { }, } repos, err := ListRepos(context.Background(), provider, filters, "") - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 1) assert.Equal(t, "two", repos[0].Repository) } @@ -117,7 +118,7 @@ func TestFilterPathDoesntExists(t *testing.T) { }, } repos, err := ListRepos(context.Background(), provider, filters, "") - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 2) } @@ -135,7 +136,7 @@ func TestFilterRepoMatchBadRegexp(t *testing.T) { }, } _, err := ListRepos(context.Background(), provider, filters, "") - assert.Error(t, err) + require.Error(t, err) } func TestFilterLabelMatchBadRegexp(t *testing.T) { @@ -152,7 +153,7 @@ func TestFilterLabelMatchBadRegexp(t *testing.T) { }, } _, err := ListRepos(context.Background(), provider, filters, "") - assert.Error(t, err) + require.Error(t, err) } func TestFilterBranchMatch(t *testing.T) { @@ -186,7 +187,7 @@ func TestFilterBranchMatch(t *testing.T) { }, } repos, err := ListRepos(context.Background(), provider, filters, "") - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 2) assert.Equal(t, "one", repos[0].Repository) assert.Equal(t, "two", repos[0].Branch) @@ -218,7 +219,7 @@ func TestMultiFilterAnd(t *testing.T) { }, } repos, err := ListRepos(context.Background(), provider, filters, "") - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 1) assert.Equal(t, "two", repos[0].Repository) } @@ -249,7 +250,7 @@ func TestMultiFilterOr(t *testing.T) { }, } repos, err := ListRepos(context.Background(), provider, filters, "") - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 3) assert.Equal(t, "one", repos[0].Repository) assert.Equal(t, "two", repos[1].Repository) @@ -275,7 +276,7 @@ func TestNoFilters(t *testing.T) { } filters := []argoprojiov1alpha1.SCMProviderGeneratorFilter{} repos, err := ListRepos(context.Background(), provider, filters, "") - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 3) assert.Equal(t, "one", repos[0].Repository) assert.Equal(t, "two", repos[1].Repository) diff --git a/applicationset/status/resource_status.go b/applicationset/status/resource_status.go new file mode 100644 index 0000000000000..4e9db5ff560e9 --- /dev/null +++ b/applicationset/status/resource_status.go @@ -0,0 +1,57 @@ +package status + +import ( + 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() + // 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 = &appCopy.Status.Health + + statusMap[app.Name] = status + } + cleanupDeletedApplicationStatuses(statusMap, appMap) + + return statusMap +} + +func GetResourceStatusMap(appset *argov1alpha1.ApplicationSet) map[string]argov1alpha1.ResourceStatus { + statusMap := map[string]argov1alpha1.ResourceStatus{} + for _, status := range appset.Status.Resources { + statusMap[status.Name] = status + } + return statusMap +} + +func cleanupDeletedApplicationStatuses(statusMap map[string]argov1alpha1.ResourceStatus, apps map[string]argov1alpha1.Application) { + for name := range statusMap { + if _, ok := apps[name]; !ok { + delete(statusMap, name) + } + } +} diff --git a/applicationset/utils/applicationset_lister.go b/applicationset/utils/applicationset_lister.go new file mode 100644 index 0000000000000..5e9d65936333a --- /dev/null +++ b/applicationset/utils/applicationset_lister.go @@ -0,0 +1,63 @@ +package utils + +import ( + "context" + + "k8s.io/apimachinery/pkg/labels" + ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" + + . "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 +type AppsetLister struct { + Client ctrlclient.Client +} + +func NewAppsetLister(client ctrlclient.Client) ApplicationSetLister { + return &AppsetLister{Client: client} +} + +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) ApplicationSetNamespaceLister { + return &appsetNamespaceLister{ + Client: l.Client, + Namespace: namespace, + } +} + +// Implements ApplicationSetNamespaceLister +type appsetNamespaceLister struct { + Client ctrlclient.Client + Namespace string +} + +func (n *appsetNamespaceLister) List(selector labels.Selector) (ret []*ApplicationSet, err error) { + return clientListAppsets(n.Client, ctrlclient.ListOptions{Namespace: n.Namespace}) +} + +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 []*ApplicationSet, err error) { + var appsetlist ApplicationSetList + var results []*ApplicationSet + + err = client.List(context.TODO(), &appsetlist, &listOptions) + + if err == nil { + for _, appset := range appsetlist.Items { + results = append(results, appset.DeepCopy()) + } + } + + return results, err +} diff --git a/applicationset/utils/clusterUtils.go b/applicationset/utils/clusterUtils.go index a56be51fdb7a2..8c44dc1246be5 100644 --- a/applicationset/utils/clusterUtils.go +++ b/applicationset/utils/clusterUtils.go @@ -132,9 +132,12 @@ 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(), @@ -143,6 +146,7 @@ func getLocalCluster(clientset kubernetes.Interface) *appv1.Cluster { }) 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 index 63d9b3887175d..9e8694359b6bd 100644 --- a/applicationset/utils/clusterUtils_test.go +++ b/applicationset/utils/clusterUtils_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -33,7 +34,7 @@ func Test_secretToCluster(t *testing.T) { }, } cluster, err := secretToCluster(secret) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, argoappv1.Cluster{ Name: "test", Server: "http://mycluster", @@ -56,7 +57,7 @@ func Test_secretToCluster_NoConfig(t *testing.T) { }, } cluster, err := secretToCluster(secret) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, argoappv1.Cluster{ Name: "test", Server: "http://mycluster", @@ -92,7 +93,7 @@ func TestValidateDestination(t *testing.T) { } appCond := ValidateDestination(context.Background(), &dest, nil, fakeNamespace) - assert.NoError(t, appCond) + require.NoError(t, appCond) assert.False(t, dest.IsServerInferred()) }) @@ -107,7 +108,7 @@ func TestValidateDestination(t *testing.T) { kubeclientset := fake.NewSimpleClientset(objects...) appCond := ValidateDestination(context.Background(), &dest, kubeclientset, fakeNamespace) - assert.NoError(t, appCond) + require.NoError(t, appCond) assert.Equal(t, "https://127.0.0.1:6443", dest.Server) assert.True(t, dest.IsServerInferred()) }) diff --git a/applicationset/utils/kubernetes.go b/applicationset/utils/kubernetes.go new file mode 100644 index 0000000000000..f9e90bf1d9f81 --- /dev/null +++ b/applicationset/utils/kubernetes.go @@ -0,0 +1,54 @@ +package utils + +import ( + "context" + "fmt" + + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +// getSecretRef gets the value of the key for the specified Secret resource. +func GetSecretRef(ctx context.Context, k8sClient client.Client, ref *argoprojiov1alpha1.SecretRef, namespace string) (string, error) { + if ref == nil { + return "", nil + } + + secret := &corev1.Secret{} + err := k8sClient.Get( + ctx, + client.ObjectKey{ + Name: ref.SecretName, + Namespace: namespace, + }, + secret) + if err != nil { + return "", fmt.Errorf("error fetching secret %s/%s: %w", namespace, ref.SecretName, err) + } + tokenBytes, ok := secret.Data[ref.Key] + if !ok { + return "", fmt.Errorf("key %q in secret %s/%s not found", ref.Key, namespace, ref.SecretName) + } + return string(tokenBytes), nil +} + +func GetConfigMapData(ctx context.Context, k8sClient client.Client, ref *argoprojiov1alpha1.ConfigMapKeyRef, namespace string) ([]byte, error) { + if ref == nil { + return nil, nil + } + + configMap := &corev1.ConfigMap{} + err := k8sClient.Get(ctx, client.ObjectKey{Name: ref.ConfigMapName, Namespace: namespace}, configMap) + if err != nil { + return nil, err + } + + data, ok := configMap.Data[ref.Key] + if !ok { + return nil, fmt.Errorf("key %s not found in ConfigMap %s", ref.Key, configMap.Name) + } + + return []byte(data), nil +} diff --git a/applicationset/utils/kubernetes_test.go b/applicationset/utils/kubernetes_test.go new file mode 100644 index 0000000000000..bddda0c473073 --- /dev/null +++ b/applicationset/utils/kubernetes_test.go @@ -0,0 +1,146 @@ +package utils + +import ( + "context" + "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" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + + argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +func TestGetSecretRef(t *testing.T) { + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{Name: "test-secret", Namespace: "test"}, + Data: map[string][]byte{ + "my-token": []byte("secret"), + }, + } + client := fake.NewClientBuilder().WithObjects(secret).Build() + ctx := context.Background() + + cases := []struct { + name, namespace, token string + ref *argoprojiov1alpha1.SecretRef + hasError bool + }{ + { + name: "valid ref", + ref: &argoprojiov1alpha1.SecretRef{SecretName: "test-secret", Key: "my-token"}, + namespace: "test", + token: "secret", + hasError: false, + }, + { + name: "nil ref", + ref: nil, + namespace: "test", + token: "", + hasError: false, + }, + { + name: "wrong name", + ref: &argoprojiov1alpha1.SecretRef{SecretName: "other", Key: "my-token"}, + namespace: "test", + token: "", + hasError: true, + }, + { + name: "wrong key", + ref: &argoprojiov1alpha1.SecretRef{SecretName: "test-secret", Key: "other-token"}, + namespace: "test", + token: "", + hasError: true, + }, + { + name: "wrong namespace", + ref: &argoprojiov1alpha1.SecretRef{SecretName: "test-secret", Key: "my-token"}, + namespace: "other", + token: "", + hasError: true, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + token, err := GetSecretRef(ctx, client, c.ref, c.namespace) + if c.hasError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + assert.Equal(t, c.token, token) + }) + } +} + +func TestGetConfigMapData(t *testing.T) { + configMap := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{Name: "test-configmap", Namespace: "test"}, + Data: map[string]string{ + "my-data": "configmap-data", + }, + } + client := fake.NewClientBuilder().WithObjects(configMap).Build() + ctx := context.Background() + + cases := []struct { + name, namespace, data string + ref *argoprojiov1alpha1.ConfigMapKeyRef + hasError bool + }{ + { + name: "valid ref", + ref: &argoprojiov1alpha1.ConfigMapKeyRef{ConfigMapName: "test-configmap", Key: "my-data"}, + namespace: "test", + data: "configmap-data", + hasError: false, + }, + { + name: "nil ref", + ref: nil, + namespace: "test", + data: "", + hasError: false, + }, + { + name: "wrong name", + ref: &argoprojiov1alpha1.ConfigMapKeyRef{ConfigMapName: "other", Key: "my-data"}, + namespace: "test", + data: "", + hasError: true, + }, + { + name: "wrong key", + ref: &argoprojiov1alpha1.ConfigMapKeyRef{ConfigMapName: "test-configmap", Key: "other-data"}, + namespace: "test", + data: "", + hasError: true, + }, + { + name: "wrong namespace", + ref: &argoprojiov1alpha1.ConfigMapKeyRef{ConfigMapName: "test-configmap", Key: "my-data"}, + namespace: "other", + data: "", + hasError: true, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + data, err := GetConfigMapData(ctx, client, c.ref, c.namespace) + if c.hasError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + if !c.hasError { + assert.Equal(t, c.data, string(data)) + } + }) + } +} diff --git a/applicationset/utils/map_test.go b/applicationset/utils/map_test.go index 6fd4ae906baa1..c12216e0e1ac6 100644 --- a/applicationset/utils/map_test.go +++ b/applicationset/utils/map_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestCombineStringMaps(t *testing.T) { @@ -49,7 +50,7 @@ func TestCombineStringMaps(t *testing.T) { if testCaseCopy.expectedErr != nil { assert.EqualError(t, err, testCaseCopy.expectedErr.Error()) } else { - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testCaseCopy.expected, got) } }) diff --git a/applicationset/utils/mocks/Renderer.go b/applicationset/utils/mocks/Renderer.go new file mode 100644 index 0000000000000..3b108f74e7864 --- /dev/null +++ b/applicationset/utils/mocks/Renderer.go @@ -0,0 +1,86 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + 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 { + mock.TestingT + Cleanup(func()) +}) *Renderer { + mock := &Renderer{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/applicationset/utils/utils.go b/applicationset/utils/utils.go index dfcc11cbdd35a..4122dee28a657 100644 --- a/applicationset/utils/utils.go +++ b/applicationset/utils/utils.go @@ -23,6 +23,7 @@ import ( log "github.com/sirupsen/logrus" 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 @@ -46,6 +47,10 @@ type Renderer interface { type Render struct{} +func IsNamespaceAllowed(namespaces []string, namespace string) bool { + return glob.MatchStringInList(namespaces, namespace, glob.REGEXP) +} + func copyValueIntoUnexported(destination, value reflect.Value) { reflect.NewAt(destination.Type(), unsafe.Pointer(destination.UnsafeAddr())). Elem(). @@ -268,7 +273,7 @@ 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) && - (replacedTmpl.ObjectMeta.Finalizers == nil || len(replacedTmpl.ObjectMeta.Finalizers) == 0) { + len(replacedTmpl.ObjectMeta.Finalizers) == 0 { replacedTmpl.ObjectMeta.Finalizers = []string{"resources-finalizer.argocd.argoproj.io"} } @@ -483,7 +488,7 @@ func SlugifyName(args ...interface{}) string { return urlSlug } -func getTlsConfigWithCACert(scmRootCAPath string) *tls.Config { +func getTlsConfigWithCACert(scmRootCAPath string, caCerts []byte) *tls.Config { tlsConfig := &tls.Config{} if scmRootCAPath != "" { @@ -497,8 +502,12 @@ func getTlsConfigWithCACert(scmRootCAPath string) *tls.Config { log.Errorf("error reading certificate from file '%s', proceeding without custom rootCA : %s", scmRootCAPath, err) return tlsConfig } + caCerts = append(caCerts, rootCA...) + } + + if len(caCerts) > 0 { certPool := x509.NewCertPool() - ok := certPool.AppendCertsFromPEM([]byte(rootCA)) + ok := certPool.AppendCertsFromPEM(caCerts) if !ok { log.Errorf("failed to append certificates from PEM: proceeding without custom rootCA") } else { @@ -508,8 +517,8 @@ func getTlsConfigWithCACert(scmRootCAPath string) *tls.Config { return tlsConfig } -func GetTlsConfig(scmRootCAPath string, insecure bool) *tls.Config { - tlsConfig := getTlsConfigWithCACert(scmRootCAPath) +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 e029a4e909c4f..8d19a2cffa260 100644 --- a/applicationset/utils/utils_test.go +++ b/applicationset/utils/utils_test.go @@ -188,7 +188,7 @@ func TestRenderTemplateParams(t *testing.T) { 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) - assert.NoError(t, err) + require.NoError(t, err) } }) } @@ -237,13 +237,13 @@ func TestRenderHelmValuesObjectJson(t *testing.T) { render := Render{} newApplication, err := render.RenderTemplateParams(application, nil, params, true, []string{}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, newApplication) var unmarshaled interface{} err = json.Unmarshal(newApplication.Spec.Source.Helm.ValuesObject.Raw, &unmarshaled) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "Hello world", unmarshaled.(map[string]interface{})["some"].(map[string]interface{})["string"]) } @@ -287,13 +287,13 @@ func TestRenderHelmValuesObjectYaml(t *testing.T) { render := Render{} newApplication, err := render.RenderTemplateParams(application, nil, params, true, []string{}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, newApplication) var unmarshaled interface{} err = json.Unmarshal(newApplication.Spec.Source.Helm.ValuesObject.Raw, &unmarshaled) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "Hello world", unmarshaled.(map[string]interface{})["some"].(map[string]interface{})["string"]) } @@ -621,10 +621,10 @@ func TestRenderTemplateParamsGoTemplate(t *testing.T) { // Retrieve the value of the target field from the newApplication, then verify that // the target field has been templated into the expected value if test.errorMessage != "" { - assert.Error(t, err) + require.Error(t, err) assert.Equal(t, test.errorMessage, err.Error()) } else { - assert.NoError(t, err) + 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.ObjectMeta.Annotations["annotation-key"]) @@ -666,7 +666,7 @@ func TestRenderGeneratorParams_does_not_panic(t *testing.T) { }, } _, err := render.RenderGeneratorParams(generator, params, true, []string{}) - assert.NoError(t, err) + require.NoError(t, err) } func TestRenderTemplateKeys(t *testing.T) { @@ -716,7 +716,7 @@ func Test_Render_Replace_no_panic_on_missing_closing_brace(t *testing.T) { r := &Render{} assert.NotPanics(t, func() { _, err := r.Replace("{{properly.closed}} {{improperly.closed}", nil, false, []string{}) - assert.Error(t, err) + require.Error(t, err) }) } @@ -812,7 +812,7 @@ func TestRenderTemplateParamsFinalizers(t *testing.T) { render := Render{} res, err := render.RenderTemplateParams(application, c.syncPolicy, params, true, nil) - assert.NoError(t, err) + require.NoError(t, err) assert.ElementsMatch(t, res.Finalizers, c.expectedFinalizers) }) @@ -822,9 +822,9 @@ func TestRenderTemplateParamsFinalizers(t *testing.T) { func TestCheckInvalidGenerators(t *testing.T) { scheme := runtime.NewScheme() err := argoappsv1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = argoappsv1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) for _, c := range []struct { testName string @@ -925,9 +925,9 @@ func TestCheckInvalidGenerators(t *testing.T) { func TestInvalidGenerators(t *testing.T) { scheme := runtime.NewScheme() err := argoappsv1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = argoappsv1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) for _, c := range []struct { testName string @@ -1260,11 +1260,8 @@ func TestSlugify(t *testing.T) { } func TestGetTLSConfig(t *testing.T) { - // certParsed, err := tls.X509KeyPair(test.Cert, test.PrivateKey) - // require.NoError(t, err) - temppath := t.TempDir() - cert := ` + certFromFile := ` -----BEGIN CERTIFICATE----- MIIFvTCCA6WgAwIBAgIUGrTmW3qc39zqnE08e3qNDhUkeWswDQYJKoZIhvcNAQEL BQAwbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv @@ -1298,50 +1295,96 @@ NoB2rjufaB0GQi1azdboMvdGSOxhSCAR8otWT5yDrywCqVnEvjw0oxKmuRduNe2/ r2AaraPFgrprnxUibP4L7jxdr+iiw5bWN9/B81PodrS7n5TNtnfnpZD6X6rThqOP xO7Tr5lAo74vNUkF2EHNaI28/RGnJPm2TIxZqy4rNH6L -----END CERTIFICATE----- +` + + certFromCM := ` +-----BEGIN CERTIFICATE----- +MIIDOTCCAiGgAwIBAgIQSRJrEpBGFc7tNb1fb5pKFzANBgkqhkiG9w0BAQsFADAS +MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw +MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEA6Gba5tHV1dAKouAaXO3/ebDUU4rvwCUg/CNaJ2PT5xLD4N1Vcb8r +bFSW2HXKq+MPfVdwIKR/1DczEoAGf/JWQTW7EgzlXrCd3rlajEX2D73faWJekD0U +aUgz5vtrTXZ90BQL7WvRICd7FlEZ6FPOcPlumiyNmzUqtwGhO+9ad1W5BqJaRI6P +YfouNkwR6Na4TzSj5BrqUfP0FwDizKSJ0XXmh8g8G9mtwxOSN3Ru1QFc61Xyeluk +POGKBV/q6RBNklTNe0gI8usUMlYyoC7ytppNMW7X2vodAelSu25jgx2anj9fDVZu +h7AXF5+4nJS4AAt0n1lNY7nGSsdZas8PbQIDAQABo4GIMIGFMA4GA1UdDwEB/wQE +AwICpDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBStsdjh3/JCXXYlQryOrL4Sh7BW5TAuBgNVHREEJzAlggtleGFtcGxlLmNv +bYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAQEAxWGI +5NhpF3nwwy/4yB4i/CwwSpLrWUa70NyhvprUBC50PxiXav1TeDzwzLx/o5HyNwsv +cxv3HdkLW59i/0SlJSrNnWdfZ19oTcS+6PtLoVyISgtyN6DpkKpdG1cOkW3Cy2P2 ++tK/tKHRP1Y/Ra0RiDpOAmqn0gCOFGz8+lqDIor/T7MTpibL3IxqWfPrvfVRHL3B +grw/ZQTTIVjjh4JBSW3WyWgNo/ikC1lrVxzl4iPUGptxT36Cr7Zk2Bsg0XqwbOvK +5d+NTDREkSnUbie4GeutujmX3Dsx88UiV6UY/4lHJa6I5leHUNOHahRbpbWeOfs/ +WkBKOclmOV2xlTVuPw== +-----END CERTIFICATE----- ` rootCAPath := path.Join(temppath, "foo.example.com") - err := os.WriteFile(rootCAPath, []byte(cert), 0o666) + err := os.WriteFile(rootCAPath, []byte(certFromFile), 0o666) if err != nil { panic(err) } - certPool := x509.NewCertPool() - ok := certPool.AppendCertsFromPEM([]byte(cert)) - assert.True(t, ok) - testCases := []struct { name string scmRootCAPath string insecure bool + caCerts []byte validateCertInTlsConfig bool }{ { name: "Insecure mode configured, SCM Root CA Path not set", scmRootCAPath: "", insecure: true, + caCerts: nil, validateCertInTlsConfig: false, }, { name: "SCM Root CA Path set, Insecure mode set to false", scmRootCAPath: rootCAPath, insecure: false, + caCerts: nil, validateCertInTlsConfig: true, }, { name: "SCM Root CA Path set, Insecure mode set to true", scmRootCAPath: rootCAPath, insecure: true, + caCerts: nil, + validateCertInTlsConfig: true, + }, + { + name: "Cert passed, Insecure mode set to false", + scmRootCAPath: "", + insecure: false, + caCerts: []byte(certFromCM), + validateCertInTlsConfig: true, + }, + { + name: "SCM Root CA Path set, cert passed, Insecure mode set to false", + scmRootCAPath: rootCAPath, + insecure: false, + caCerts: []byte(certFromCM), validateCertInTlsConfig: true, }, } for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - tlsConfig := GetTlsConfig(testCase.scmRootCAPath, testCase.insecure) + certPool := x509.NewCertPool() + tlsConfig := GetTlsConfig(testCase.scmRootCAPath, testCase.insecure, testCase.caCerts) assert.Equal(t, testCase.insecure, tlsConfig.InsecureSkipVerify) + if testCase.caCerts != nil { + ok := certPool.AppendCertsFromPEM([]byte(certFromCM)) + assert.True(t, ok) + } + if testCase.scmRootCAPath != "" { + ok := certPool.AppendCertsFromPEM([]byte(certFromFile)) + assert.True(t, ok) + } + assert.NotNil(t, tlsConfig) if testCase.validateCertInTlsConfig { - assert.NotNil(t, tlsConfig) assert.True(t, tlsConfig.RootCAs.Equal(certPool)) } }) diff --git a/applicationset/webhook/testdata/github-commit-event-feature-branch.json b/applicationset/webhook/testdata/github-commit-event-feature-branch.json new file mode 100644 index 0000000000000..2cbe577da34de --- /dev/null +++ b/applicationset/webhook/testdata/github-commit-event-feature-branch.json @@ -0,0 +1,186 @@ +{ + "ref": "refs/heads/env/dev", + "before": "d5c1ffa8e294bc18c639bfb4e0df499251034414", + "after": "63738bb582c8b540af7bcfc18f87c575c3ed66e0", + "created": false, + "deleted": false, + "forced": true, + "base_ref": null, + "compare": "https://github.com/org/repo/compare/d5c1ffa8e294...63738bb582c8", + "commits": [ + { + "id": "63738bb582c8b540af7bcfc18f87c575c3ed66e0", + "tree_id": "64897da445207e409ad05af93b1f349ad0a4ee19", + "distinct": true, + "message": "Add staging-argocd-demo environment", + "timestamp": "2018-05-04T15:40:02-07:00", + "url": "https://github.com/org/repo/commit/63738bb582c8b540af7bcfc18f87c575c3ed66e0", + "author": { + "name": "Jesse Suen", + "email": "Jesse_Suen@example.com", + "username": "org" + }, + "committer": { + "name": "Jesse Suen", + "email": "Jesse_Suen@example.com", + "username": "org" + }, + "added": [ + "ksapps/test-app/environments/staging-argocd-demo/main.jsonnet", + "ksapps/test-app/environments/staging-argocd-demo/params.libsonnet" + ], + "removed": [ + + ], + "modified": [ + "ksapps/test-app/app.yaml" + ] + } + ], + "head_commit": { + "id": "63738bb582c8b540af7bcfc18f87c575c3ed66e0", + "tree_id": "64897da445207e409ad05af93b1f349ad0a4ee19", + "distinct": true, + "message": "Add staging-argocd-demo environment", + "timestamp": "2018-05-04T15:40:02-07:00", + "url": "https://github.com/org/repo/commit/63738bb582c8b540af7bcfc18f87c575c3ed66e0", + "author": { + "name": "Jesse Suen", + "email": "Jesse_Suen@example.com", + "username": "org" + }, + "committer": { + "name": "Jesse Suen", + "email": "Jesse_Suen@example.com", + "username": "org" + }, + "added": [ + "ksapps/test-app/environments/staging-argocd-demo/main.jsonnet", + "ksapps/test-app/environments/staging-argocd-demo/params.libsonnet" + ], + "removed": [ + + ], + "modified": [ + "ksapps/test-app/app.yaml" + ] + }, + "repository": { + "id": 123060978, + "name": "repo", + "full_name": "org/repo", + "owner": { + "name": "org", + "email": "org@users.noreply.github.com", + "login": "org", + "id": 12677113, + "avatar_url": "https://avatars0.githubusercontent.com/u/12677113?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/org", + "html_url": "https://github.com/org", + "followers_url": "https://api.github.com/users/org/followers", + "following_url": "https://api.github.com/users/org/following{/other_user}", + "gists_url": "https://api.github.com/users/org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/org/subscriptions", + "organizations_url": "https://api.github.com/users/org/orgs", + "repos_url": "https://api.github.com/users/org/repos", + "events_url": "https://api.github.com/users/org/events{/privacy}", + "received_events_url": "https://api.github.com/users/org/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/org/repo", + "description": "Test Repository", + "fork": false, + "url": "https://github.com/org/repo", + "forks_url": "https://api.github.com/repos/org/repo/forks", + "keys_url": "https://api.github.com/repos/org/repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/org/repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/org/repo/teams", + "hooks_url": "https://api.github.com/repos/org/repo/hooks", + "issue_events_url": "https://api.github.com/repos/org/repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/org/repo/events", + "assignees_url": "https://api.github.com/repos/org/repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/org/repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/org/repo/tags", + "blobs_url": "https://api.github.com/repos/org/repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/org/repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/org/repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/org/repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/org/repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/org/repo/languages", + "stargazers_url": "https://api.github.com/repos/org/repo/stargazers", + "contributors_url": "https://api.github.com/repos/org/repo/contributors", + "subscribers_url": "https://api.github.com/repos/org/repo/subscribers", + "subscription_url": "https://api.github.com/repos/org/repo/subscription", + "commits_url": "https://api.github.com/repos/org/repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/org/repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/org/repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/org/repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/org/repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/org/repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/org/repo/merges", + "archive_url": "https://api.github.com/repos/org/repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/org/repo/downloads", + "issues_url": "https://api.github.com/repos/org/repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/org/repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/org/repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/org/repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/org/repo/labels{/name}", + "releases_url": "https://api.github.com/repos/org/repo/releases{/id}", + "deployments_url": "https://api.github.com/repos/org/repo/deployments", + "created_at": 1519698615, + "updated_at": "2018-05-04T22:37:55Z", + "pushed_at": 1525473610, + "git_url": "git://github.com/org/repo.git", + "ssh_url": "git@github.com:org/repo.git", + "clone_url": "https://github.com/org/repo.git", + "svn_url": "https://github.com/org/repo", + "homepage": null, + "size": 538, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 1, + "mirror_url": null, + "archived": false, + "open_issues_count": 0, + "license": null, + "forks": 1, + "open_issues": 0, + "watchers": 0, + "default_branch": "master", + "stargazers": 0, + "master_branch": "master" + }, + "pusher": { + "name": "org", + "email": "org@users.noreply.github.com" + }, + "sender": { + "login": "org", + "id": 12677113, + "avatar_url": "https://avatars0.githubusercontent.com/u/12677113?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/org", + "html_url": "https://github.com/org", + "followers_url": "https://api.github.com/users/org/followers", + "following_url": "https://api.github.com/users/org/following{/other_user}", + "gists_url": "https://api.github.com/users/org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/org/subscriptions", + "organizations_url": "https://api.github.com/users/org/orgs", + "repos_url": "https://api.github.com/users/org/repos", + "events_url": "https://api.github.com/users/org/events{/privacy}", + "received_events_url": "https://api.github.com/users/org/received_events", + "type": "User", + "site_admin": false + } + } \ No newline at end of file diff --git a/applicationset/webhook/webhook.go b/applicationset/webhook/webhook.go index 30f1a2eb1ad0e..e1c5d63cdb440 100644 --- a/applicationset/webhook/webhook.go +++ b/applicationset/webhook/webhook.go @@ -2,7 +2,6 @@ package webhook import ( "context" - "errors" "fmt" "html" "net/http" @@ -10,6 +9,7 @@ import ( "regexp" "strconv" "strings" + "sync" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/retry" @@ -19,6 +19,7 @@ import ( "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" @@ -26,16 +27,17 @@ import ( log "github.com/sirupsen/logrus" ) -var errBasicAuthVerificationFailed = errors.New("basic auth verification failed") +const payloadQueueSize = 50000 type WebhookHandler struct { - namespace string - github *github.Webhook - gitlab *gitlab.Webhook - azuredevops *azuredevops.Webhook - azuredevopsAuthHandler func(r *http.Request) error - client client.Client - generators map[string]generators.Generator + sync.WaitGroup // for testing + namespace string + github *github.Webhook + gitlab *gitlab.Webhook + azuredevops *azuredevops.Webhook + client client.Client + generators map[string]generators.Generator + queue chan interface{} } type gitGeneratorInfo struct { @@ -66,7 +68,7 @@ type prGeneratorGitlabInfo struct { APIHostname string } -func NewWebhookHandler(namespace string, argocdSettingsMgr *argosettings.SettingsManager, client client.Client, generators map[string]generators.Generator) (*WebhookHandler, error) { +func NewWebhookHandler(namespace string, webhookParallelism int, argocdSettingsMgr *argosettings.SettingsManager, client client.Client, generators map[string]generators.Generator) (*WebhookHandler, error) { // register the webhook secrets stored under "argocd-secret" for verifying incoming payloads argocdSettings, err := argocdSettingsMgr.GetSettings() if err != nil { @@ -80,29 +82,40 @@ func NewWebhookHandler(namespace string, argocdSettingsMgr *argosettings.Setting if err != nil { return nil, fmt.Errorf("Unable to init GitLab webhook: %w", err) } - azuredevopsHandler, err := azuredevops.New() + 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) } - azuredevopsAuthHandler := func(r *http.Request) error { - if argocdSettings.WebhookAzureDevOpsUsername != "" && argocdSettings.WebhookAzureDevOpsPassword != "" { - username, password, ok := r.BasicAuth() - if !ok || username != argocdSettings.WebhookAzureDevOpsUsername || password != argocdSettings.WebhookAzureDevOpsPassword { - return errBasicAuthVerificationFailed - } - } - return nil + + webhookHandler := &WebhookHandler{ + namespace: namespace, + github: githubHandler, + gitlab: gitlabHandler, + azuredevops: azuredevopsHandler, + client: client, + generators: generators, + queue: make(chan interface{}, payloadQueueSize), } - return &WebhookHandler{ - namespace: namespace, - github: githubHandler, - gitlab: gitlabHandler, - azuredevops: azuredevopsHandler, - azuredevopsAuthHandler: azuredevopsAuthHandler, - client: client, - generators: generators, - }, nil + webhookHandler.startWorkerPool(webhookParallelism) + + return webhookHandler, nil +} + +func (h *WebhookHandler) startWorkerPool(webhookParallelism int) { + for i := 0; i < webhookParallelism; i++ { + h.Add(1) + go func() { + defer h.Done() + for { + payload, ok := <-h.queue + if !ok { + return + } + h.HandleEvent(payload) + } + }() + } } func (h *WebhookHandler) HandleEvent(payload interface{}) { @@ -153,13 +166,7 @@ func (h *WebhookHandler) Handler(w http.ResponseWriter, r *http.Request) { case r.Header.Get("X-Gitlab-Event") != "": payload, err = h.gitlab.Parse(r, gitlab.PushEvents, gitlab.TagEvents, gitlab.MergeRequestEvents) case r.Header.Get("X-Vss-Activityid") != "": - if err = h.azuredevopsAuthHandler(r); err != nil { - if errors.Is(err, errBasicAuthVerificationFailed) { - log.WithField(common.SecurityField, common.SecurityHigh).Infof("Azure DevOps webhook basic auth verification failed") - } - } else { - payload, err = h.azuredevops.Parse(r, azuredevops.GitPushEventType, azuredevops.GitPullRequestCreatedEventType, azuredevops.GitPullRequestUpdatedEventType, azuredevops.GitPullRequestMergedEventType) - } + payload, err = h.azuredevops.Parse(r, azuredevops.GitPushEventType, azuredevops.GitPullRequestCreatedEventType, azuredevops.GitPullRequestUpdatedEventType, azuredevops.GitPullRequestMergedEventType) default: log.Debug("Ignoring unknown webhook event") http.Error(w, "Unknown webhook event", http.StatusBadRequest) @@ -176,12 +183,12 @@ func (h *WebhookHandler) Handler(w http.ResponseWriter, r *http.Request) { return } - h.HandleEvent(payload) -} - -func parseRevision(ref string) string { - refParts := strings.SplitN(ref, "/", 3) - return refParts[len(refParts)-1] + select { + case h.queue <- payload: + default: + log.Info("Queue is full, discarding webhook payload") + http.Error(w, "Queue is full, discarding webhook payload", http.StatusServiceUnavailable) + } } func getGitGeneratorInfo(payload interface{}) *gitGeneratorInfo { @@ -193,16 +200,16 @@ func getGitGeneratorInfo(payload interface{}) *gitGeneratorInfo { switch payload := payload.(type) { case github.PushPayload: webURL = payload.Repository.HTMLURL - revision = parseRevision(payload.Ref) + revision = webhook.ParseRevision(payload.Ref) touchedHead = payload.Repository.DefaultBranch == revision case gitlab.PushEventPayload: webURL = payload.Project.WebURL - revision = parseRevision(payload.Ref) + revision = webhook.ParseRevision(payload.Ref) touchedHead = payload.Project.DefaultBranch == revision case azuredevops.GitPushEvent: // See: https://learn.microsoft.com/en-us/azure/devops/service-hooks/events?view=azure-devops#git.push webURL = payload.Resource.Repository.RemoteURL - revision = parseRevision(payload.Resource.RefUpdates[0].Name) + revision = webhook.ParseRevision(payload.Resource.RefUpdates[0].Name) touchedHead = payload.Resource.RefUpdates[0].Name == payload.Resource.Repository.DefaultBranch // unfortunately, Azure DevOps doesn't provide a list of changed files default: @@ -362,12 +369,12 @@ func shouldRefreshPluginGenerator(gen *v1alpha1.PluginGenerator) bool { } func genRevisionHasChanged(gen *v1alpha1.GitGenerator, revision string, touchedHead bool) bool { - targetRev := parseRevision(gen.Revision) + targetRev := webhook.ParseRevision(gen.Revision) if targetRev == "HEAD" || targetRev == "" { // revision is head return touchedHead } - return targetRev == revision + return targetRev == revision || gen.Revision == revision } func gitGeneratorUsesURL(gen *v1alpha1.GitGenerator, webURL string, repoRegexp *regexp.Regexp) bool { diff --git a/applicationset/webhook/webhook_test.go b/applicationset/webhook/webhook_test.go index 6c1f6be29cfc4..046bbf35f09ab 100644 --- a/applicationset/webhook/webhook_test.go +++ b/applicationset/webhook/webhook_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -66,6 +67,15 @@ func TestWebhookHandler(t *testing.T) { expectedStatusCode: http.StatusOK, expectedRefresh: true, }, + { + desc: "WebHook from a GitHub repository via Commit shorthand", + headerKey: "X-GitHub-Event", + headerValue: "push", + payloadFile: "github-commit-event-feature-branch.json", + effectedAppSets: []string{"github-shorthand", "matrix-pull-request-github-plugin", "plugin"}, + expectedStatusCode: http.StatusOK, + expectedRefresh: true, + }, { desc: "WebHook from a GitHub repository via Commit to branch", headerKey: "X-GitHub-Event", @@ -177,12 +187,13 @@ func TestWebhookHandler(t *testing.T) { } namespace := "test" + webhookParallelism := 10 fakeClient := newFakeClient(namespace) scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) err = v1alpha1.AddToScheme(scheme) - assert.NoError(t, err) + require.NoError(t, err) for _, test := range tt { t.Run(test.desc, func(t *testing.T) { @@ -190,6 +201,7 @@ func TestWebhookHandler(t *testing.T) { fakeAppWithGitGenerator("git-github", namespace, "https://github.com/org/repo"), 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"), fakeAppWithGitlabPullRequestGenerator("pull-request-gitlab", namespace, "100500"), fakeAppWithAzureDevOpsPullRequestGenerator("pull-request-azure-devops", namespace, "DefaultCollection", "Fabrikam"), @@ -205,22 +217,24 @@ func TestWebhookHandler(t *testing.T) { fakeAppWithMergeAndNestedGitGenerator("merge-nested-git-github", namespace, "https://github.com/org/repo"), ).Build() set := argosettings.NewSettingsManager(context.TODO(), fakeClient, namespace) - h, err := NewWebhookHandler(namespace, set, fc, mockGenerators()) - assert.NoError(t, err) + h, err := NewWebhookHandler(namespace, webhookParallelism, set, fc, mockGenerators()) + require.NoError(t, err) req := httptest.NewRequest(http.MethodPost, "/api/webhook", nil) req.Header.Set(test.headerKey, test.headerValue) eventJSON, err := os.ReadFile(filepath.Join("testdata", test.payloadFile)) - assert.NoError(t, err) + require.NoError(t, err) req.Body = io.NopCloser(bytes.NewReader(eventJSON)) w := httptest.NewRecorder() h.Handler(w, req) + close(h.queue) + h.Wait() assert.Equal(t, test.expectedStatusCode, w.Code) list := &v1alpha1.ApplicationSetList{} err = fc.List(context.TODO(), list) - assert.NoError(t, err) + require.NoError(t, err) effectedAppSetsAsExpected := make(map[string]bool) for _, appSetName := range test.effectedAppSets { effectedAppSetsAsExpected[appSetName] = false @@ -298,14 +312,62 @@ func mockGenerators() map[string]generators.Generator { } func TestGenRevisionHasChanged(t *testing.T) { - assert.True(t, genRevisionHasChanged(&v1alpha1.GitGenerator{}, "master", true)) - assert.False(t, genRevisionHasChanged(&v1alpha1.GitGenerator{}, "master", false)) - - assert.True(t, genRevisionHasChanged(&v1alpha1.GitGenerator{Revision: "dev"}, "dev", true)) - assert.False(t, genRevisionHasChanged(&v1alpha1.GitGenerator{Revision: "dev"}, "master", false)) - - assert.True(t, genRevisionHasChanged(&v1alpha1.GitGenerator{Revision: "refs/heads/dev"}, "dev", true)) - assert.False(t, genRevisionHasChanged(&v1alpha1.GitGenerator{Revision: "refs/heads/dev"}, "master", false)) + type args struct { + gen *v1alpha1.GitGenerator + revision string + touchedHead bool + } + tests := []struct { + name string + args args + want bool + }{ + {name: "touchedHead", args: args{ + gen: &v1alpha1.GitGenerator{}, + revision: "main", + touchedHead: true, + }, want: true}, + {name: "didntTouchHead", args: args{ + gen: &v1alpha1.GitGenerator{}, + revision: "main", + touchedHead: false, + }, want: false}, + {name: "foundEqualShort", args: args{ + gen: &v1alpha1.GitGenerator{Revision: "dev"}, + revision: "dev", + touchedHead: true, + }, want: true}, + {name: "foundEqualLongGen", args: args{ + gen: &v1alpha1.GitGenerator{Revision: "refs/heads/dev"}, + revision: "dev", + touchedHead: true, + }, want: true}, + {name: "foundNotEqualLongGen", args: args{ + gen: &v1alpha1.GitGenerator{Revision: "refs/heads/dev"}, + revision: "main", + touchedHead: true, + }, want: false}, + {name: "foundNotEqualShort", args: args{ + gen: &v1alpha1.GitGenerator{Revision: "dev"}, + revision: "main", + touchedHead: false, + }, want: false}, + {name: "foundEqualTag", args: args{ + gen: &v1alpha1.GitGenerator{Revision: "v3.14.1"}, + revision: "v3.14.1", + touchedHead: false, + }, want: true}, + {name: "foundEqualTagLongGen", args: args{ + gen: &v1alpha1.GitGenerator{Revision: "refs/tags/v3.14.1"}, + revision: "v3.14.1", + touchedHead: false, + }, want: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, genRevisionHasChanged(tt.args.gen, tt.args.revision, tt.args.touchedHead), "genRevisionHasChanged(%v, %v, %v)", tt.args.gen, tt.args.revision, tt.args.touchedHead) + }) + } } func fakeAppWithGitGenerator(name, namespace, repo string) *v1alpha1.ApplicationSet { @@ -327,6 +389,12 @@ func fakeAppWithGitGenerator(name, namespace, repo string) *v1alpha1.Application } } +func fakeAppWithGitGeneratorWithRevision(name, namespace, repo, revision string) *v1alpha1.ApplicationSet { + appSet := fakeAppWithGitGenerator(name, namespace, repo) + appSet.Spec.Generators[0].Git.Revision = revision + return appSet +} + func fakeAppWithGitlabPullRequestGenerator(name, namespace, projectId string) *v1alpha1.ApplicationSet { return &v1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ @@ -707,7 +775,7 @@ func fakeAppWithMatrixAndPullRequestGeneratorWithPluginGenerator(name, namespace func newFakeClient(ns string) *kubefake.Clientset { s := runtime.NewScheme() s.AddKnownTypes(v1alpha1.SchemeGroupVersion, &v1alpha1.ApplicationSet{}) - return kubefake.NewSimpleClientset(&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "argocd-cm", Namespace: ns, Labels: map[string]string{ + return kubefake.NewClientset(&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "argocd-cm", Namespace: ns, Labels: map[string]string{ "app.kubernetes.io/part-of": "argocd", }}}, &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ diff --git a/assets/builtin-policy.csv b/assets/builtin-policy.csv index 9413b53d1cba5..81c8ca5092cb4 100644 --- a/assets/builtin-policy.csv +++ b/assets/builtin-policy.csv @@ -1,10 +1,10 @@ # Built-in policy which defines two roles: role:readonly and role:admin, # and additionally assigns the admin user to the role:admin role. # There are two policy formats: -# 1. Applications, logs, and exec (which belong to a project): -# p, , , , / +# 1. Applications, applicationsets, logs, and exec (which belong to a project): +# p, , , , /, # 2. All other resources: -# p, , , , +# p, , , , , p, role:readonly, applications, get, */*, allow p, role:readonly, certificates, get, *, allow diff --git a/assets/swagger.json b/assets/swagger.json index 7d863dc71a028..1e8a981c51c66 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -1967,6 +1967,11 @@ "type": "boolean", "name": "upsert", "in": "query" + }, + { + "type": "boolean", + "name": "dryRun", + "in": "query" } ], "responses": { @@ -4484,6 +4489,27 @@ } } }, + "applicationsetApplicationSetGenerateRequest": { + "type": "object", + "title": "ApplicationSetGetQuery is a query for applicationset resources", + "properties": { + "applicationSet": { + "$ref": "#/definitions/v1alpha1ApplicationSet" + } + } + }, + "applicationsetApplicationSetGenerateResponse": { + "type": "object", + "title": "ApplicationSetGenerateResponse is a response for applicationset generate request", + "properties": { + "applications": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Application" + } + } + } + }, "applicationsetApplicationSetResponse": { "type": "object", "properties": { @@ -4509,6 +4535,43 @@ } } }, + "applicationv1alpha1ResourceStatus": { + "type": "object", + "title": "ResourceStatus holds the current sync and health status of a resource\nTODO: describe members of this type", + "properties": { + "group": { + "type": "string" + }, + "health": { + "$ref": "#/definitions/v1alpha1HealthStatus" + }, + "hook": { + "type": "boolean" + }, + "kind": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "requiresPruning": { + "type": "boolean" + }, + "status": { + "type": "string" + }, + "syncWave": { + "type": "integer", + "format": "int64" + }, + "version": { + "type": "string" + } + } + }, "clusterClusterID": { "type": "object", "title": "ClusterID holds a cluster server URL or cluster name", @@ -4653,6 +4716,9 @@ "help": { "$ref": "#/definitions/clusterHelp" }, + "impersonationEnabled": { + "type": "boolean" + }, "kustomizeOptions": { "$ref": "#/definitions/v1alpha1KustomizeOptions" }, @@ -5044,6 +5110,13 @@ "repositoryManifestResponse": { "type": "object", "properties": { + "commands": { + "type": "array", + "title": "Commands is the list of commands used to hydrate the manifests", + "items": { + "type": "string" + } + }, "manifests": { "type": "array", "items": { @@ -5452,7 +5525,7 @@ "properties": { "matchExpressions": { "type": "array", - "title": "matchExpressions is a list of label selector requirements. The requirements are ANDed.\n+optional", + "title": "matchExpressions is a list of label selector requirements. The requirements are ANDed.\n+optional\n+listType=atomic", "items": { "$ref": "#/definitions/v1LabelSelectorRequirement" } @@ -5480,7 +5553,7 @@ }, "values": { "type": "array", - "title": "values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. This array is replaced during a strategic\nmerge patch.\n+optional", + "title": "values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. This array is replaced during a strategic\nmerge patch.\n+optional\n+listType=atomic", "items": { "type": "string" } @@ -5604,7 +5677,7 @@ "type": "string" }, "kubeProxyVersion": { - "description": "KubeProxy Version reported by the node.", + "description": "Deprecated: KubeProxy Version reported by the node.", "type": "string" }, "kubeletVersion": { @@ -5653,7 +5726,7 @@ }, "finalizers": { "type": "array", - "title": "Must be empty before the object is deleted from the registry. Each entry\nis an identifier for the responsible component that will remove the entry\nfrom the list. If the deletionTimestamp of the object is non-nil, entries\nin this list can only be removed.\nFinalizers may be processed and removed in any order. Order is NOT enforced\nbecause it introduces significant risk of stuck finalizers.\nfinalizers is a shared field, any actor with permission can reorder it.\nIf the finalizer list is processed in order, then this can lead to a situation\nin which the component responsible for the first finalizer in the list is\nwaiting for a signal (field value, external system, or other) produced by a\ncomponent responsible for a finalizer later in the list, resulting in a deadlock.\nWithout enforced ordering finalizers are free to order amongst themselves and\nare not vulnerable to ordering changes in the list.\n+optional\n+patchStrategy=merge", + "title": "Must be empty before the object is deleted from the registry. Each entry\nis an identifier for the responsible component that will remove the entry\nfrom the list. If the deletionTimestamp of the object is non-nil, entries\nin this list can only be removed.\nFinalizers may be processed and removed in any order. Order is NOT enforced\nbecause it introduces significant risk of stuck finalizers.\nfinalizers is a shared field, any actor with permission can reorder it.\nIf the finalizer list is processed in order, then this can lead to a situation\nin which the component responsible for the first finalizer in the list is\nwaiting for a signal (field value, external system, or other) produced by a\ncomponent responsible for a finalizer later in the list, resulting in a deadlock.\nWithout enforced ordering finalizers are free to order amongst themselves and\nare not vulnerable to ordering changes in the list.\n+optional\n+patchStrategy=merge\n+listType=set", "items": { "type": "string" } @@ -5675,7 +5748,7 @@ } }, "managedFields": { - "description": "ManagedFields maps workflow-id and version to the set of fields\nthat are managed by that workflow. This is mostly for internal\nhousekeeping, and users typically shouldn't need to set or\nunderstand this field. A workflow can be the user's name, a\ncontroller's name, or the name of a specific apply path like\n\"ci-cd\". The set of fields is always in the version that the\nworkflow used when modifying the object.\n\n+optional", + "description": "ManagedFields maps workflow-id and version to the set of fields\nthat are managed by that workflow. This is mostly for internal\nhousekeeping, and users typically shouldn't need to set or\nunderstand this field. A workflow can be the user's name, a\ncontroller's name, or the name of a specific apply path like\n\"ci-cd\". The set of fields is always in the version that the\nworkflow used when modifying the object.\n\n+optional\n+listType=atomic", "type": "array", "items": { "$ref": "#/definitions/v1ManagedFieldsEntry" @@ -5691,7 +5764,7 @@ }, "ownerReferences": { "type": "array", - "title": "List of objects depended by this object. If ALL objects in the list have\nbeen deleted, this object will be garbage collected. If this object is managed by a controller,\nthen an entry in this list will point to this controller, with the controller field set to true.\nThere cannot be more than one managing controller.\n+optional\n+patchMergeKey=uid\n+patchStrategy=merge", + "title": "List of objects depended by this object. If ALL objects in the list have\nbeen deleted, this object will be garbage collected. If this object is managed by a controller,\nthen an entry in this list will point to this controller, with the controller field set to true.\nThere cannot be more than one managing controller.\n+optional\n+patchMergeKey=uid\n+patchStrategy=merge\n+listType=map\n+listMapKey=uid", "items": { "$ref": "#/definitions/v1OwnerReference" } @@ -5867,6 +5940,13 @@ "type": "string", "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.", + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ApplicationDestinationServiceAccount" + } + }, "destinations": { "type": "array", "title": "Destinations contains list of destinations available for deployment", @@ -5998,6 +6078,24 @@ } } }, + "v1alpha1ApplicationDestinationServiceAccount": { + "description": "ApplicationDestinationServiceAccount holds information about the service account to be impersonated for the application sync operation.", + "type": "object", + "properties": { + "defaultServiceAccount": { + "type": "string", + "title": "ServiceAccountName to be used for impersonation during the sync operation" + }, + "namespace": { + "description": "Namespace specifies the target namespace for the application's resources.", + "type": "string" + }, + "server": { + "description": "Server specifies the URL of the target cluster's Kubernetes control plane API.", + "type": "string" + } + } + }, "v1alpha1ApplicationList": { "type": "object", "title": "ApplicationList is list of Application resources\n+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object", @@ -6322,7 +6420,7 @@ "description": "Resources is a list of Applications resources managed by this application set.", "type": "array", "items": { - "$ref": "#/definitions/v1alpha1ResourceStatus" + "$ref": "#/definitions/applicationv1alpha1ResourceStatus" } } } @@ -6471,6 +6569,13 @@ "type": "object", "title": "ApplicationSourceHelm holds helm specific options", "properties": { + "apiVersions": { + "description": "APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default,\nArgo CD uses the API versions of the target cluster. The format is [group/]version/kind.", + "type": "array", + "items": { + "type": "string" + } + }, "fileParameters": { "type": "array", "title": "FileParameters are file parameters to the helm template", @@ -6482,6 +6587,14 @@ "type": "boolean", "title": "IgnoreMissingValueFiles prevents helm template from failing when valueFiles do not exist locally by not appending them to helm template --values" }, + "kubeVersion": { + "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" + }, + "namespace": { + "description": "Namespace is an optional namespace to template with. If left empty, defaults to the app's destination namespace.", + "type": "string" + }, "parameters": { "type": "array", "title": "Parameters is a list of Helm parameters which are passed to the helm template command upon manifest generation", @@ -6552,6 +6665,13 @@ "type": "object", "title": "ApplicationSourceKustomize holds options specific to an Application source specific to Kustomize", "properties": { + "apiVersions": { + "description": "APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default,\nArgo CD uses the API versions of the target cluster. The format is [group/]version/kind.", + "type": "array", + "items": { + "type": "string" + } + }, "commonAnnotations": { "type": "object", "title": "CommonAnnotations is a list of additional annotations to add to rendered manifests", @@ -6592,6 +6712,10 @@ "type": "string" } }, + "kubeVersion": { + "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" + }, "labelWithoutSelector": { "type": "boolean", "title": "LabelWithoutSelector specifies whether to apply common labels to resource selectors or not" @@ -6763,7 +6887,7 @@ "type": "array", "title": "Resources is a list of Kubernetes resources managed by this application", "items": { - "$ref": "#/definitions/v1alpha1ResourceStatus" + "$ref": "#/definitions/applicationv1alpha1ResourceStatus" } }, "sourceType": { @@ -6829,6 +6953,11 @@ "items": { "$ref": "#/definitions/v1alpha1ResourceNode" } + }, + "shardsCount": { + "type": "integer", + "format": "int64", + "title": "ShardsCount contains total number of shards the application tree is split into" } } }, @@ -6876,6 +7005,15 @@ } } }, + "v1alpha1BearerTokenBitbucket": { + "description": "BearerTokenBitbucket defines the Bearer token for BitBucket AppToken auth.", + "type": "object", + "properties": { + "tokenRef": { + "$ref": "#/definitions/v1alpha1SecretRef" + } + } + }, "v1alpha1BearerTokenBitbucketCloud": { "description": "BearerTokenBitbucketCloud defines the Bearer token for BitBucket AppToken auth.", "type": "object", @@ -6960,7 +7098,7 @@ }, "serverVersion": { "type": "string", - "title": "DEPRECATED: use Info.ServerVersion field instead.\nThe server version" + "title": "Deprecated: use Info.ServerVersion field instead.\nThe server version" }, "shard": { "description": "Shard contains optional shard number. Calculated on the fly by the application controller if not specified.", @@ -7138,6 +7276,18 @@ } } }, + "v1alpha1ConfigMapKeyRef": { + "description": "Utility struct for a reference to a configmap key.", + "type": "object", + "properties": { + "configMapName": { + "type": "string" + }, + "key": { + "type": "string" + } + } + }, "v1alpha1ConnectionState": { "type": "object", "title": "ConnectionState contains information about remote resource connection state, currently used for clusters and repositories", @@ -7962,6 +8112,16 @@ "basicAuth": { "$ref": "#/definitions/v1alpha1BasicAuthBitbucketServer" }, + "bearerToken": { + "$ref": "#/definitions/v1alpha1BearerTokenBitbucket" + }, + "caRef": { + "$ref": "#/definitions/v1alpha1ConfigMapKeyRef" + }, + "insecure": { + "type": "boolean", + "title": "Allow self-signed TLS / Certificates; default: false" + }, "project": { "description": "Project to scan. Required.", "type": "string" @@ -7992,6 +8152,9 @@ "description": "The GitLab API URL to talk to. If blank, uses https://gitlab.com/.", "type": "string" }, + "caRef": { + "$ref": "#/definitions/v1alpha1ConfigMapKeyRef" + }, "insecure": { "type": "boolean", "title": "Skips validating the SCM provider's TLS certificate - useful for self-signed certificates.; default: false" @@ -8107,6 +8270,10 @@ "type": "string", "title": "GithubAppPrivateKey specifies the private key PEM data for authentication via GitHub app" }, + "noProxy": { + "type": "string", + "title": "NoProxy specifies a list of targets where the proxy isn't used, applies only in cases where the proxy is applied" + }, "password": { "type": "string", "title": "Password for authenticating at the repo server" @@ -8213,6 +8380,10 @@ "type": "string", "title": "Name specifies a name to be used for this repo. Only used with Helm repos" }, + "noProxy": { + "type": "string", + "title": "NoProxy specifies a list of targets where the proxy isn't used, applies only in cases where the proxy is applied" + }, "password": { "type": "string", "title": "Password contains the password or PAT used for authenticating at the remote repository" @@ -8610,43 +8781,6 @@ } } }, - "v1alpha1ResourceStatus": { - "type": "object", - "title": "ResourceStatus holds the current sync and health status of a resource\nTODO: describe members of this type", - "properties": { - "group": { - "type": "string" - }, - "health": { - "$ref": "#/definitions/v1alpha1HealthStatus" - }, - "hook": { - "type": "boolean" - }, - "kind": { - "type": "string" - }, - "name": { - "type": "string" - }, - "namespace": { - "type": "string" - }, - "requiresPruning": { - "type": "boolean" - }, - "status": { - "type": "string" - }, - "syncWave": { - "type": "integer", - "format": "int64" - }, - "version": { - "type": "string" - } - } - }, "v1alpha1RetryStrategy": { "type": "object", "title": "RetryStrategy contains information about the strategy to apply when a sync failed", @@ -8869,6 +9003,16 @@ "basicAuth": { "$ref": "#/definitions/v1alpha1BasicAuthBitbucketServer" }, + "bearerToken": { + "$ref": "#/definitions/v1alpha1BearerTokenBitbucket" + }, + "caRef": { + "$ref": "#/definitions/v1alpha1ConfigMapKeyRef" + }, + "insecure": { + "type": "boolean", + "title": "Allow self-signed TLS / Certificates; default: false" + }, "project": { "description": "Project to scan. Required.", "type": "string" @@ -8969,6 +9113,9 @@ "description": "The Gitlab API URL to talk to.", "type": "string" }, + "caRef": { + "$ref": "#/definitions/v1alpha1ConfigMapKeyRef" + }, "group": { "description": "Gitlab group to scan. Required. You can use either the project id (recommended) or the full namespaced path.", "type": "string" diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index 5d7fd803e7aca..95dc64466ccef 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -4,6 +4,9 @@ import ( "context" "fmt" "math" + "os" + "os/signal" + "syscall" "time" "github.com/argoproj/pkg/stats" @@ -21,6 +24,7 @@ import ( appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" "github.com/argoproj/argo-cd/v2/pkg/ratelimiter" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/argo" "github.com/argoproj/argo-cd/v2/util/argo/normalizers" cacheutil "github.com/argoproj/argo-cd/v2/util/cache" appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" @@ -59,6 +63,7 @@ func NewCommand() *cobra.Command { metricsPort int metricsCacheExpiration time.Duration metricsAplicationLabels []string + metricsAplicationConditions []string kubectlParallelismLimit int64 cacheSource func() (*appstatecache.Cache, error) redisClient *redis.Client @@ -74,6 +79,9 @@ func NewCommand() *cobra.Command { enableDynamicClusterDistribution bool serverSideDiff bool ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts + + // argocd k8s event logging flag + enableK8sEvent []string ) command := cobra.Command{ Use: cliName, @@ -164,6 +172,7 @@ func NewCommand() *cobra.Command { metricsPort, metricsCacheExpiration, metricsAplicationLabels, + metricsAplicationConditions, kubectlParallelismLimit, persistResourceHealth, clusterSharding, @@ -172,6 +181,7 @@ func NewCommand() *cobra.Command { serverSideDiff, enableDynamicClusterDistribution, ignoreNormalizerOpts, + enableK8sEvent, ) errors.CheckError(err) cacheutil.CollectMetrics(redisClient, appController.GetMetricsServer()) @@ -188,10 +198,22 @@ func NewCommand() *cobra.Command { defer closeTracer() } + // Graceful shutdown code + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) + go func() { + s := <-sigCh + log.Printf("got signal %v, attempting graceful shutdown", s) + cancel() + }() + go appController.Run(ctx, statusProcessors, operationProcessors) - // Wait forever - select {} + <-ctx.Done() + + log.Println("clean shutdown") + + return nil }, } @@ -214,6 +236,7 @@ func NewCommand() *cobra.Command { command.Flags().BoolVar(&repoServerPlaintext, "repo-server-plaintext", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT", false), "Disable TLS on connections to repo server") command.Flags().BoolVar(&repoServerStrictTLS, "repo-server-strict-tls", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS", false), "Whether to use strict validation of the TLS cert presented by the repo server") command.Flags().StringSliceVar(&metricsAplicationLabels, "metrics-application-labels", []string{}, "List of Application labels that will be added to the argocd_application_labels metric") + command.Flags().StringSliceVar(&metricsAplicationConditions, "metrics-application-conditions", []string{}, "List of Application conditions that will be added to the argocd_application_conditions 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)") @@ -233,6 +256,9 @@ func NewCommand() *cobra.Command { command.Flags().BoolVar(&enableDynamicClusterDistribution, "dynamic-cluster-distribution-enabled", env.ParseBoolFromEnv(common.EnvEnableDynamicClusterDistribution, false), "Enables dynamic cluster distribution.") command.Flags().BoolVar(&serverSideDiff, "server-side-diff-enabled", env.ParseBoolFromEnv(common.EnvServerSideDiff, false), "Feature flag to enable ServerSide diff. Default (\"false\")") command.Flags().DurationVar(&ignoreNormalizerOpts.JQExecutionTimeout, "ignore-normalizer-jq-execution-timeout-seconds", env.ParseDurationFromEnv("ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT", 0*time.Second, 0, math.MaxInt64), "Set ignore normalizer JQ execution timeout") + // argocd k8s event logging flag + command.Flags().StringSliceVar(&enableK8sEvent, "enable-k8s-event", env.StringsFromEnv("ARGOCD_ENABLE_K8S_EVENT", argo.DefaultEnableEventList(), ","), "Enable ArgoCD to use k8s event. For disabling all events, set the value as `none`. (e.g --enable-k8s-event=none), For enabling specific events, set the value as `event reason`. (e.g --enable-k8s-event=StatusRefreshed,ResourceCreated)") + cacheSource = appstatecache.AddCacheFlagsToCmd(&command, cacheutil.Options{ OnClientCreated: func(client *redis.Client) { redisClient = client diff --git a/cmd/argocd-applicationset-controller/commands/applicationset_controller.go b/cmd/argocd-applicationset-controller/commands/applicationset_controller.go index b90bd7dbd1f65..d2f4ce36d98cf 100644 --- a/cmd/argocd-applicationset-controller/commands/applicationset_controller.go +++ b/cmd/argocd-applicationset-controller/commands/applicationset_controller.go @@ -12,6 +12,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "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/v2/applicationset/controllers" @@ -34,6 +35,7 @@ import ( ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + appsetmetrics "github.com/argoproj/argo-cd/v2/applicationset/metrics" "github.com/argoproj/argo-cd/v2/applicationset/services" appv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" @@ -68,7 +70,9 @@ func NewCommand() *cobra.Command { allowedScmProviders []string globalPreservedAnnotations []string globalPreservedLabels []string + metricsAplicationsetLabels []string enableScmProviders bool + webhookParallelism int ) scheme := runtime.NewScheme() _ = clientgoscheme.AddToScheme(scheme) @@ -94,6 +98,8 @@ func NewCommand() *cobra.Command { cli.SetLogFormat(cmdutil.LogFormat) cli.SetLogLevel(cmdutil.LogLevel) + ctrl.SetLogger(logutils.NewLogrusLogger(logutils.NewWithCurrentConfig())) + restConfig, err := clientConfig.ClientConfig() errors.CheckError(err) @@ -126,7 +132,14 @@ func NewCommand() *cobra.Command { } } - mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ + cfg := ctrl.GetConfigOrDie() + err = appv1alpha1.SetK8SConfigDefaults(cfg) + if err != nil { + log.Error(err, "Unable to apply K8s REST config defaults") + os.Exit(1) + } + + mgr, err := ctrl.NewManager(cfg, ctrl.Options{ Scheme: scheme, Metrics: metricsserver.Options{ BindAddress: metricsAddr, @@ -152,13 +165,11 @@ func NewCommand() *cobra.Command { appSetConfig := appclientset.NewForConfigOrDie(mgr.GetConfig()) argoCDDB := db.NewDB(namespace, argoSettingsMgr, k8sClient) - scmAuth := generators.SCMAuthProviders{ - GitHubApps: github_app.NewAuthCredentials(argoCDDB.(db.RepoCredsDB)), - } + scmConfig := generators.NewSCMConfig(scmRootCAPath, allowedScmProviders, enableScmProviders, github_app.NewAuthCredentials(argoCDDB.(db.RepoCredsDB))) tlsConfig := apiclient.TLSConfiguration{ DisableTLS: repoServerPlaintext, - StrictValidation: repoServerPlaintext, + StrictValidation: repoServerStrictTLS, } if !repoServerPlaintext && repoServerStrictTLS { @@ -174,42 +185,10 @@ func NewCommand() *cobra.Command { argoCDService, err := services.NewArgoCDService(argoCDDB.GetRepository, gitSubmoduleEnabled, repoClientset, enableNewGitFileGlobbing) errors.CheckError(err) - terminalGenerators := map[string]generators.Generator{ - "List": generators.NewListGenerator(), - "Clusters": generators.NewClusterGenerator(mgr.GetClient(), ctx, k8sClient, namespace), - "Git": generators.NewGitGenerator(argoCDService), - "SCMProvider": generators.NewSCMProviderGenerator(mgr.GetClient(), scmAuth, scmRootCAPath, allowedScmProviders, enableScmProviders), - "ClusterDecisionResource": generators.NewDuckTypeGenerator(ctx, dynamicClient, k8sClient, namespace), - "PullRequest": generators.NewPullRequestGenerator(mgr.GetClient(), scmAuth, scmRootCAPath, allowedScmProviders, enableScmProviders), - "Plugin": generators.NewPluginGenerator(mgr.GetClient(), ctx, k8sClient, namespace), - } - - nestedGenerators := map[string]generators.Generator{ - "List": terminalGenerators["List"], - "Clusters": terminalGenerators["Clusters"], - "Git": terminalGenerators["Git"], - "SCMProvider": terminalGenerators["SCMProvider"], - "ClusterDecisionResource": terminalGenerators["ClusterDecisionResource"], - "PullRequest": terminalGenerators["PullRequest"], - "Plugin": terminalGenerators["Plugin"], - "Matrix": generators.NewMatrixGenerator(terminalGenerators), - "Merge": generators.NewMergeGenerator(terminalGenerators), - } - - topLevelGenerators := map[string]generators.Generator{ - "List": terminalGenerators["List"], - "Clusters": terminalGenerators["Clusters"], - "Git": terminalGenerators["Git"], - "SCMProvider": terminalGenerators["SCMProvider"], - "ClusterDecisionResource": terminalGenerators["ClusterDecisionResource"], - "PullRequest": terminalGenerators["PullRequest"], - "Plugin": terminalGenerators["Plugin"], - "Matrix": generators.NewMatrixGenerator(nestedGenerators), - "Merge": generators.NewMergeGenerator(nestedGenerators), - } + topLevelGenerators := generators.GetGenerators(ctx, mgr.GetClient(), k8sClient, namespace, argoCDService, dynamicClient, scmConfig) // start a webhook server that listens to incoming webhook payloads - webhookHandler, err := webhook.NewWebhookHandler(namespace, argoSettingsMgr, mgr.GetClient(), topLevelGenerators) + webhookHandler, err := webhook.NewWebhookHandler(namespace, webhookParallelism, argoSettingsMgr, mgr.GetClient(), topLevelGenerators) if err != nil { log.Error(err, "failed to create webhook handler") } @@ -217,6 +196,13 @@ func NewCommand() *cobra.Command { startWebhookServer(webhookHandler, webhookAddr) } + metrics := appsetmetrics.NewApplicationsetMetrics( + utils.NewAppsetLister(mgr.GetClient()), + metricsAplicationsetLabels, + func(appset *appv1alpha1.ApplicationSet) bool { + return utils.IsNamespaceAllowed(applicationSetNamespaces, appset.Namespace) + }) + if err = (&controllers.ApplicationSetReconciler{ Generators: topLevelGenerators, Client: mgr.GetClient(), @@ -234,7 +220,7 @@ func NewCommand() *cobra.Command { SCMRootCAPath: scmRootCAPath, GlobalPreservedAnnotations: globalPreservedAnnotations, GlobalPreservedLabels: globalPreservedLabels, - Cache: mgr.GetCache(), + Metrics: &metrics, }).SetupWithManager(mgr, enableProgressiveSyncs, maxConcurrentReconciliations); err != nil { log.Error(err, "unable to create controller", "controller", "ApplicationSet") os.Exit(1) @@ -258,7 +244,7 @@ func NewCommand() *cobra.Command { "Enabling this will ensure there is only one active controller manager.") command.Flags().StringSliceVar(&applicationSetNamespaces, "applicationset-namespaces", env.StringsFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES", []string{}, ","), "Argo CD applicationset namespaces") command.Flags().StringVar(&argocdRepoServer, "argocd-repo-server", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER", common.DefaultRepoServerAddr), "Argo CD repo server address") - command.Flags().StringVar(&policy, "policy", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_POLICY", ""), "Modify how application is synced between the generator and the cluster. Default is 'sync' (create & update & delete), options: 'create-only', 'create-update' (no deletion), 'create-delete' (no update)") + 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", "text"), "Set the logging format. One of: text|json") @@ -275,6 +261,8 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&scmRootCAPath, "scm-root-ca-path", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH", ""), "Provide Root CA Path for self-signed TLS Certificates") command.Flags().StringSliceVar(&globalPreservedAnnotations, "preserved-annotations", env.StringsFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_ANNOTATIONS", []string{}, ","), "Sets global preserved field values for annotations") command.Flags().StringSliceVar(&globalPreservedLabels, "preserved-labels", env.StringsFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_LABELS", []string{}, ","), "Sets global preserved field values for labels") + command.Flags().IntVar(&webhookParallelism, "webhook-parallelism-limit", env.ParseNumFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT", 50, 1, 1000), "Number of webhook requests processed concurrently") + command.Flags().StringSliceVar(&metricsAplicationsetLabels, "metrics-applicationset-labels", []string{}, "List of Application labels that will be added to the argocd_applicationset_labels metric") return &command } @@ -282,7 +270,7 @@ func startWebhookServer(webhookHandler *webhook.WebhookHandler, webhookAddr stri mux := http.NewServeMux() mux.HandleFunc("/api/webhook", webhookHandler.Handler) go func() { - log.Info("Starting webhook server") + log.Infof("Starting webhook server %s", webhookAddr) err := http.ListenAndServe(webhookAddr, mux) if err != nil { log.Error(err, "failed to start webhook server") diff --git a/cmd/argocd-cmp-server/commands/argocd_cmp_server.go b/cmd/argocd-cmp-server/commands/argocd_cmp_server.go index 0b9f50c4b305e..197f52e01ade7 100644 --- a/cmd/argocd-cmp-server/commands/argocd_cmp_server.go +++ b/cmd/argocd-cmp-server/commands/argocd_cmp_server.go @@ -81,8 +81,8 @@ func NewCommand() *cobra.Command { }, } - 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") + 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") command.Flags().BoolVar(&otlpInsecure, "otlp-insecure", env.ParseBoolFromEnv("ARGOCD_CMP_SERVER_OTLP_INSECURE", true), "OpenTelemetry collector insecure mode") diff --git a/cmd/argocd-dex/commands/argocd_dex.go b/cmd/argocd-dex/commands/argocd_dex.go index 55b628ba96dc1..43efbbb050dd5 100644 --- a/cmd/argocd-dex/commands/argocd_dex.go +++ b/cmd/argocd-dex/commands/argocd_dex.go @@ -136,8 +136,8 @@ func NewRunDexCommand() *cobra.Command { } clientConfig = cli.AddKubectlFlagsToCmd(&command) - 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") + 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 } @@ -204,8 +204,8 @@ func NewGenDexConfigCommand() *cobra.Command { } clientConfig = cli.AddKubectlFlagsToCmd(&command) - 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") + 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 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 a5b925ca925b8..0b9d05787a6e1 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 @@ -5,8 +5,6 @@ import ( "os" "strings" - "github.com/argoproj/argo-cd/v2/util/git" - "github.com/spf13/cobra" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -33,9 +31,9 @@ func NewCommand() *cobra.Command { if len(os.Args) != 2 { errors.CheckError(fmt.Errorf("expected 1 argument, got %d", len(os.Args)-1)) } - nonce := os.Getenv(git.ASKPASS_NONCE_ENV) + nonce := os.Getenv(askpass.ASKPASS_NONCE_ENV) if nonce == "" { - errors.CheckError(fmt.Errorf("%s is not set", git.ASKPASS_NONCE_ENV)) + errors.CheckError(fmt.Errorf("%s is not set", askpass.ASKPASS_NONCE_ENV)) } conn, err := grpc_util.BlockingDial(ctx, "unix", askpass.SocketPath, nil, grpc.WithTransportCredentials(insecure.NewCredentials())) errors.CheckError(err) diff --git a/cmd/argocd-notification/commands/controller.go b/cmd/argocd-notification/commands/controller.go index a2ae2cb7e4c51..7245a0b75a667 100644 --- a/cmd/argocd-notification/commands/controller.go +++ b/cmd/argocd-notification/commands/controller.go @@ -1,10 +1,14 @@ package commands import ( + "context" "fmt" "net/http" "os" + "os/signal" "strings" + "sync" + "syscall" "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" @@ -62,7 +66,8 @@ func NewCommand() *cobra.Command { Use: "controller", Short: "Starts Argo CD Notifications controller", RunE: func(c *cobra.Command, args []string) error { - ctx := c.Context() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() vers := common.GetVersion() namespace, _, err := clientConfig.Namespace() @@ -146,6 +151,17 @@ func NewCommand() *cobra.Command { return fmt.Errorf("failed to initialize controller: %w", err) } + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + s := <-sigCh + log.Printf("got signal %v, attempting graceful shutdown", s) + cancel() + }() + go ctrl.Run(ctx, processorsCount) <-ctx.Done() return nil @@ -159,7 +175,7 @@ func NewCommand() *cobra.Command { 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", false, "Use a plaintext client (non-TLS) to connect to repository server") + 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") command.Flags().BoolVar(&argocdRepoServerStrictTLS, "argocd-repo-server-strict-tls", false, "Perform strict validation of TLS certificates when connecting to repo server") command.Flags().StringVar(&configMapName, "config-map-name", "argocd-notifications-cm", "Set notifications ConfigMap name") command.Flags().StringVar(&secretName, "secret-name", "argocd-notifications-secret", "Set notifications Secret name") diff --git a/cmd/argocd-repo-server/commands/argocd_repo_server.go b/cmd/argocd-repo-server/commands/argocd_repo_server.go index 50d444eb53e90..f8bb868f0bd0f 100644 --- a/cmd/argocd-repo-server/commands/argocd_repo_server.go +++ b/cmd/argocd-repo-server/commands/argocd_repo_server.go @@ -5,6 +5,10 @@ import ( "math" "net" "net/http" + "os" + "os/signal" + "sync" + "syscall" "time" "github.com/argoproj/pkg/stats" @@ -71,6 +75,7 @@ func NewCommand() *cobra.Command { helmRegistryMaxIndexSize string disableManifestMaxExtractedSize bool includeHiddenDirectories bool + cmpUseManifestGeneratePaths bool ) command := cobra.Command{ Use: cliName, @@ -115,7 +120,7 @@ func NewCommand() *cobra.Command { helmRegistryMaxIndexSizeQuantity, err := resource.ParseQuantity(helmRegistryMaxIndexSize) errors.CheckError(err) - askPassServer := askpass.NewServer() + askPassServer := askpass.NewServer(askpass.SocketPath) metricsServer := metrics.NewMetricsServer() cacheutil.CollectMetrics(redisClient, metricsServer) server, err := reposerver.NewServer(metricsServer, cache, tlsConfigCustomizer, repository.RepoServerInitConstants{ @@ -132,6 +137,7 @@ func NewCommand() *cobra.Command { HelmManifestMaxExtractedSize: helmManifestMaxExtractedSizeQuantity.ToDec().Value(), HelmRegistryMaxIndexSize: helmRegistryMaxIndexSizeQuantity.ToDec().Value(), IncludeHiddenDirectories: includeHiddenDirectories, + CMPUseManifestGeneratePaths: cmpUseManifestGeneratePaths, }, askPassServer) errors.CheckError(err) @@ -173,7 +179,7 @@ func NewCommand() *cobra.Command { }) http.Handle("/metrics", metricsServer.GetHandler()) go func() { errors.CheckError(http.ListenAndServe(fmt.Sprintf("%s:%d", metricsHost, metricsPort), nil)) }() - go func() { errors.CheckError(askPassServer.Run(askpass.SocketPath)) }() + go func() { errors.CheckError(askPassServer.Run()) }() if gpg.IsGPGEnabled() { log.Infof("Initializing GnuPG keyring at %s", common.GetGnuPGHomePath()) @@ -192,8 +198,27 @@ func NewCommand() *cobra.Command { stats.RegisterStackDumper() stats.StartStatsTicker(10 * time.Minute) stats.RegisterHeapDumper("memprofile") + + // Graceful shutdown code adapted from https://gist.github.com/embano1/e0bf49d24f1cdd07cffad93097c04f0a + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + s := <-sigCh + log.Printf("got signal %v, attempting graceful shutdown", s) + grpc.GracefulStop() + wg.Done() + }() + + log.Println("starting grpc server") err = grpc.Serve(listener) - errors.CheckError(err) + if err != nil { + log.Fatalf("could not serve: %v", err) + } + wg.Wait() + log.Println("clean shutdown") + return nil }, } @@ -218,6 +243,7 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&helmRegistryMaxIndexSize, "helm-registry-max-index-size", env.StringFromEnv("ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_INDEX_SIZE", "1G"), "Maximum size of registry index file") command.Flags().BoolVar(&disableManifestMaxExtractedSize, "disable-helm-manifest-max-extracted-size", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE", false), "Disable maximum size of helm manifest archives when extracted") command.Flags().BoolVar(&includeHiddenDirectories, "include-hidden-directories", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_INCLUDE_HIDDEN_DIRECTORIES", false), "Include hidden directories from Git") + command.Flags().BoolVar(&cmpUseManifestGeneratePaths, "plugin-use-manifest-generate-paths", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS", false), "Pass the resources described in argocd.argoproj.io/manifest-generate-paths value to the cmpserver to generate the application manifests.") tlsConfigCustomizerSrc = tls.AddTLSFlagsToCmd(&command) cacheSrc = reposervercache.AddCacheFlagsToCmd(&command, cacheutil.Options{ OnClientCreated: func(client *redis.Client) { diff --git a/cmd/argocd-server/commands/argocd_server.go b/cmd/argocd-server/commands/argocd_server.go index 707cc2d80eaf5..d1e9cf05f98d5 100644 --- a/cmd/argocd-server/commands/argocd_server.go +++ b/cmd/argocd-server/commands/argocd_server.go @@ -8,12 +8,16 @@ import ( "time" "github.com/redis/go-redis/v9" + "k8s.io/apimachinery/pkg/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" "github.com/argoproj/pkg/stats" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" + "sigs.k8s.io/controller-runtime/pkg/client" cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" "github.com/argoproj/argo-cd/v2/common" @@ -23,6 +27,7 @@ import ( reposervercache "github.com/argoproj/argo-cd/v2/reposerver/cache" "github.com/argoproj/argo-cd/v2/server" servercache "github.com/argoproj/argo-cd/v2/server/cache" + "github.com/argoproj/argo-cd/v2/util/argo" cacheutil "github.com/argoproj/argo-cd/v2/util/cache" "github.com/argoproj/argo-cd/v2/util/cli" "github.com/argoproj/argo-cd/v2/util/dex" @@ -42,6 +47,7 @@ const ( var ( failureRetryCount = env.ParseNumFromEnv(failureRetryCountEnv, 0, 0, 10) failureRetryPeriodMilliSeconds = env.ParseNumFromEnv(failureRetryPeriodMilliSecondsEnv, 100, 0, 1000) + gitSubmoduleEnabled = env.ParseBoolFromEnv(common.EnvGitSubmoduleEnabled, true) ) // NewCommand returns a new instance of an argocd command @@ -79,6 +85,16 @@ func NewCommand() *cobra.Command { staticAssetsDir string applicationNamespaces []string enableProxyExtension bool + webhookParallelism int + + // ApplicationSet + enableNewGitFileGlobbing bool + scmRootCAPath string + allowedScmProviders []string + enableScmProviders bool + + // argocd k8s event logging flag + enableK8sEvent []string ) command := &cobra.Command{ Use: cliName, @@ -130,6 +146,16 @@ func NewCommand() *cobra.Command { StrictValidation: repoServerStrictTLS, } + dynamicClient := dynamic.NewForConfigOrDie(config) + + scheme := runtime.NewScheme() + _ = clientgoscheme.AddToScheme(scheme) + _ = v1alpha1.AddToScheme(scheme) + + controllerClient, err := client.New(config, client.Options{Scheme: scheme}) + errors.CheckError(err) + controllerClient = client.NewDryRunClient(controllerClient) + // Load CA information to use for validating connections to the // repository server, if strict TLS validation was requested. if !repoServerPlaintext && repoServerStrictTLS { @@ -179,37 +205,49 @@ func NewCommand() *cobra.Command { } argoCDOpts := server.ArgoCDServerOpts{ - Insecure: insecure, - ListenPort: listenPort, - ListenHost: listenHost, - MetricsPort: metricsPort, - MetricsHost: metricsHost, - Namespace: namespace, - BaseHRef: baseHRef, - RootPath: rootPath, - KubeClientset: kubeclientset, - AppClientset: appClientSet, - RepoClientset: repoclientset, - DexServerAddr: dexServerAddress, - DexTLSConfig: dexTlsConfig, - DisableAuth: disableAuth, - ContentTypes: contentTypesList, - EnableGZip: enableGZip, - TLSConfigCustomizer: tlsConfigCustomizer, - Cache: cache, - RepoServerCache: repoServerCache, - XFrameOptions: frameOptions, - ContentSecurityPolicy: contentSecurityPolicy, - RedisClient: redisClient, - StaticAssetsDir: staticAssetsDir, - ApplicationNamespaces: applicationNamespaces, - EnableProxyExtension: enableProxyExtension, + Insecure: insecure, + ListenPort: listenPort, + ListenHost: listenHost, + MetricsPort: metricsPort, + MetricsHost: metricsHost, + Namespace: namespace, + BaseHRef: baseHRef, + RootPath: rootPath, + DynamicClientset: dynamicClient, + KubeControllerClientset: controllerClient, + KubeClientset: kubeclientset, + AppClientset: appClientSet, + RepoClientset: repoclientset, + DexServerAddr: dexServerAddress, + DexTLSConfig: dexTlsConfig, + DisableAuth: disableAuth, + ContentTypes: contentTypesList, + EnableGZip: enableGZip, + TLSConfigCustomizer: tlsConfigCustomizer, + Cache: cache, + RepoServerCache: repoServerCache, + XFrameOptions: frameOptions, + ContentSecurityPolicy: contentSecurityPolicy, + RedisClient: redisClient, + StaticAssetsDir: staticAssetsDir, + ApplicationNamespaces: applicationNamespaces, + EnableProxyExtension: enableProxyExtension, + WebhookParallelism: webhookParallelism, + EnableK8sEvent: enableK8sEvent, + } + + appsetOpts := server.ApplicationSetOpts{ + GitSubmoduleEnabled: gitSubmoduleEnabled, + EnableNewGitFileGlobbing: enableNewGitFileGlobbing, + ScmRootCAPath: scmRootCAPath, + AllowedScmProviders: allowedScmProviders, + EnableScmProviders: enableScmProviders, } stats.RegisterStackDumper() stats.StartStatsTicker(10 * time.Minute) stats.RegisterHeapDumper("memprofile") - argocd := server.NewServer(ctx, argoCDOpts) + argocd := server.NewServer(ctx, argoCDOpts, appsetOpts) argocd.Init(ctx) lns, err := argocd.Listen() errors.CheckError(err) @@ -232,7 +270,7 @@ func NewCommand() *cobra.Command { Example: templates.Examples(` # Start the Argo CD API server with default settings $ argocd-server - + # Start the Argo CD API server on a custom port and enable tracing $ argocd-server --port 8888 --otlp-address localhost:4317 `), @@ -269,6 +307,15 @@ func NewCommand() *cobra.Command { command.Flags().BoolVar(&dexServerStrictTLS, "dex-server-strict-tls", env.ParseBoolFromEnv("ARGOCD_SERVER_DEX_SERVER_STRICT_TLS", false), "Perform strict validation of TLS certificates when connecting to dex server") command.Flags().StringSliceVar(&applicationNamespaces, "application-namespaces", env.StringsFromEnv("ARGOCD_APPLICATION_NAMESPACES", []string{}, ","), "List of additional namespaces where application resources can be managed in") command.Flags().BoolVar(&enableProxyExtension, "enable-proxy-extension", env.ParseBoolFromEnv("ARGOCD_SERVER_ENABLE_PROXY_EXTENSION", false), "Enable Proxy Extension feature") + command.Flags().IntVar(&webhookParallelism, "webhook-parallelism-limit", env.ParseNumFromEnv("ARGOCD_SERVER_WEBHOOK_PARALLELISM_LIMIT", 50, 1, 1000), "Number of webhook requests processed concurrently") + command.Flags().StringSliceVar(&enableK8sEvent, "enable-k8s-event", env.StringsFromEnv("ARGOCD_ENABLE_K8S_EVENT", argo.DefaultEnableEventList(), ","), "Enable ArgoCD to use k8s event. For disabling all events, set the value as `none`. (e.g --enable-k8s-event=none), For enabling specific events, set the value as `event reason`. (e.g --enable-k8s-event=StatusRefreshed,ResourceCreated)") + + // Flags related to the applicationSet component. + command.Flags().StringVar(&scmRootCAPath, "appset-scm-root-ca-path", env.StringFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH", ""), "Provide Root CA Path for self-signed TLS Certificates") + command.Flags().BoolVar(&enableScmProviders, "appset-enable-scm-providers", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS", true), "Enable retrieving information from SCM providers, used by the SCM and PR generators (Default: true)") + command.Flags().StringSliceVar(&allowedScmProviders, "appset-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(&enableNewGitFileGlobbing, "appset-enable-new-git-file-globbing", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING", false), "Enable new globbing in Git files generator.") + tlsConfigCustomizerSrc = tls.AddTLSFlagsToCmd(command) cacheSrc = servercache.AddCacheFlagsToCmd(command, cacheutil.Options{ OnClientCreated: func(client *redis.Client) { diff --git a/cmd/argocd/commands/admin/admin.go b/cmd/argocd/commands/admin/admin.go index e5465d9209507..6c120bd425cdb 100644 --- a/cmd/argocd/commands/admin/admin.go +++ b/cmd/argocd/commands/admin/admin.go @@ -1,10 +1,13 @@ package admin import ( + "context" "reflect" + "strings" "github.com/spf13/cobra" 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" @@ -83,11 +86,12 @@ func newArgoCDClientsets(config *rest.Config, namespace string) *argoCDClientset 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), } } @@ -186,7 +190,11 @@ func isArgoCDConfigMap(name string) bool { // specsEqual returns if the spec, data, labels, annotations, and finalizers of the two // supplied objects are equal, indicating that no update is necessary during importing func specsEqual(left, right unstructured.Unstructured) bool { - if !reflect.DeepEqual(left.GetAnnotations(), right.GetAnnotations()) { + leftAnnotation := left.GetAnnotations() + rightAnnotation := right.GetAnnotations() + delete(leftAnnotation, apiv1.LastAppliedConfigAnnotation) + delete(rightAnnotation, apiv1.LastAppliedConfigAnnotation) + if !reflect.DeepEqual(leftAnnotation, rightAnnotation) { return false } if !reflect.DeepEqual(left.GetLabels(), right.GetLabels()) { @@ -219,34 +227,51 @@ func specsEqual(left, right unstructured.Unstructured) bool { return false } -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) - } else { - iterateStringFields(val, callback) - } - } - } else if arrayField, ok := obj.([]interface{}); ok { - for i := range arrayField { - iterateStringFields(arrayField[i], callback) - } - } +type argocdAdditonalNamespaces struct { + applicationNamespaces []string + applicationsetNamespaces []string } -func redactor(dirtyString string) string { - config := make(map[string]interface{}) - err := yaml.Unmarshal([]byte(dirtyString), &config) +const ( + applicationsetNamespacesCmdParamsKey = "applicationsetcontroller.namespaces" + applicationNamespacesCmdParamsKey = "application.namespaces" +) + +// Get additional namespaces from argocd-cmd-params +func getAdditionalNamespaces(ctx context.Context, argocdClientsets *argoCDClientsets) *argocdAdditonalNamespaces { + applicationNamespaces := make([]string, 0) + applicationsetNamespaces := make([]string, 0) + + un, err := argocdClientsets.configMaps.Get(ctx, common.ArgoCDCmdParamsConfigMapName, v1.GetOptions{}) errors.CheckError(err) - iterateStringFields(config, func(name string, val string) string { - if name == "clientSecret" || name == "secret" || name == "bindPW" { - return "********" - } else { - return val - } - }) - data, err := yaml.Marshal(config) + var cm apiv1.ConfigMap + err = runtime.DefaultUnstructuredConverter.FromUnstructured(un.Object, &cm) errors.CheckError(err) - return string(data) + + namespacesListFromString := func(namespaces string) []string { + listOfNamespaces := []string{} + + ss := strings.Split(namespaces, ",") + + for _, namespace := range ss { + if namespace != "" { + listOfNamespaces = append(listOfNamespaces, strings.TrimSpace(namespace)) + } + } + + return listOfNamespaces + } + + if strNamespaces, ok := cm.Data[applicationNamespacesCmdParamsKey]; ok { + applicationNamespaces = namespacesListFromString(strNamespaces) + } + + if strNamespaces, ok := cm.Data[applicationsetNamespacesCmdParamsKey]; ok { + applicationsetNamespaces = namespacesListFromString(strNamespaces) + } + + return &argocdAdditonalNamespaces{ + applicationNamespaces: applicationNamespaces, + applicationsetNamespaces: applicationsetNamespaces, + } } diff --git a/cmd/argocd/commands/admin/admin_test.go b/cmd/argocd/commands/admin/admin_test.go new file mode 100644 index 0000000000000..85f59b5dee699 --- /dev/null +++ b/cmd/argocd/commands/admin/admin_test.go @@ -0,0 +1,75 @@ +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]interface{}) *unstructured.Unstructured { + return &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "v1", + "kind": "ConfigMap", + "metadata": map[string]interface{}{ + "name": "argocd-cmd-params-cm", + "namespace": "argocd", + }, + "data": data, + }, + } + } + + testCases := []struct { + CmdParamsKeys map[string]interface{} + expected argocdAdditonalNamespaces + description string + }{ + { + description: "empty configmap should return no additional namespaces", + 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]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]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]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]interface{}{applicationNamespacesCmdParamsKey: " bar ", applicationsetNamespacesCmdParamsKey: " foo , bar* "}, + expected: argocdAdditonalNamespaces{applicationNamespaces: []string{"bar"}, applicationsetNamespaces: []string{"foo", "bar*"}}, + }, + } + + for _, c := range testCases { + fakeDynClient := dynfake.NewSimpleDynamicClient(runtime.NewScheme(), createArgoCDCmdCMWithKeys(c.CmdParamsKeys)) + + argoCDClientsets := &argoCDClientsets{ + 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(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 284b4fa9f20bf..e8869493d05fc 100644 --- a/cmd/argocd/commands/admin/app.go +++ b/cmd/argocd/commands/admin/app.go @@ -78,6 +78,7 @@ func NewGenAppSpecCommand() *cobra.Command { outputFormat string annotations []string inline bool + setFinalizer bool ) command := &cobra.Command{ Use: "generate-spec APPNAME", @@ -112,7 +113,9 @@ func NewGenAppSpecCommand() *cobra.Command { c.HelpFunc()(c, args) os.Exit(1) } - + if setFinalizer { + app.Finalizers = append(app.Finalizers, "resources-finalizer.argocd.argoproj.io") + } out, closer, err := getOutWriter(inline, fileURL) errors.CheckError(err) defer io.Close(closer) @@ -126,6 +129,7 @@ func NewGenAppSpecCommand() *cobra.Command { command.Flags().StringArrayVarP(&annotations, "annotations", "", []string{}, "Set metadata annotations (e.g. example=value)") command.Flags().StringVarP(&outputFormat, "output", "o", "yaml", "Output format. One of: json|yaml") command.Flags().BoolVarP(&inline, "inline", "i", false, "If set then generated resource is written back to the file specified in --file flag") + command.Flags().BoolVar(&setFinalizer, "set-finalizer", false, "Sets deletion finalizer on the application, application resources will be cascaded on deletion") // Only complete files with appropriate extension. err := command.Flags().SetAnnotation("file", cobra.BashCompFilenameExt, []string{"json", "yaml", "yml"}) @@ -383,7 +387,7 @@ func reconcileApplications( return true }, func(r *http.Request) error { return nil - }, []string{}) + }, []string{}, []string{}) if err != nil { return nil, err } diff --git a/cmd/argocd/commands/admin/backup.go b/cmd/argocd/commands/admin/backup.go index fb54c5c7c7951..918bbc234b9a2 100644 --- a/cmd/argocd/commands/admin/backup.go +++ b/cmd/argocd/commands/admin/backup.go @@ -20,13 +20,16 @@ import ( "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" + secutil "github.com/argoproj/argo-cd/v2/util/security" ) // NewExportCommand defines a new command for exporting Kubernetes and Argo CD resources. func NewExportCommand() *cobra.Command { var ( - clientConfig clientcmd.ClientConfig - out string + clientConfig clientcmd.ClientConfig + out string + applicationNamespaces []string + applicationsetNamespaces []string ) command := cobra.Command{ Use: "export", @@ -58,34 +61,47 @@ func NewExportCommand() *cobra.Command { acdClients := newArgoCDClientsets(config, namespace) acdConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDConfigMapName, v1.GetOptions{}) errors.CheckError(err) - export(writer, *acdConfigMap) + export(writer, *acdConfigMap, namespace) acdRBACConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDRBACConfigMapName, v1.GetOptions{}) errors.CheckError(err) - export(writer, *acdRBACConfigMap) + export(writer, *acdRBACConfigMap, namespace) acdKnownHostsConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDKnownHostsConfigMapName, v1.GetOptions{}) errors.CheckError(err) - export(writer, *acdKnownHostsConfigMap) + export(writer, *acdKnownHostsConfigMap, namespace) acdTLSCertsConfigMap, err := acdClients.configMaps.Get(ctx, common.ArgoCDTLSCertsConfigMapName, v1.GetOptions{}) errors.CheckError(err) - export(writer, *acdTLSCertsConfigMap) + export(writer, *acdTLSCertsConfigMap, namespace) referencedSecrets := getReferencedSecrets(*acdConfigMap) secrets, err := acdClients.secrets.List(ctx, v1.ListOptions{}) errors.CheckError(err) for _, secret := range secrets.Items { if isArgoCDSecret(referencedSecrets, secret) { - export(writer, secret) + export(writer, secret, namespace) } } projects, err := acdClients.projects.List(ctx, v1.ListOptions{}) errors.CheckError(err) for _, proj := range projects.Items { - export(writer, proj) + export(writer, proj, namespace) } + + 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(writer, app) + // Export application only if it is in one of the enabled namespaces + if secutil.IsNamespaceEnabled(app.GetNamespace(), namespace, applicationNamespaces) { + export(writer, app, namespace) + } } applicationSets, err := acdClients.applicationSets.List(ctx, v1.ListOptions{}) if err != nil && !apierr.IsNotFound(err) { @@ -97,7 +113,9 @@ func NewExportCommand() *cobra.Command { } if applicationSets != nil { for _, appSet := range applicationSets.Items { - export(writer, appSet) + if secutil.IsNamespaceEnabled(appSet.GetNamespace(), namespace, applicationsetNamespaces) { + export(writer, appSet, namespace) + } } } }, @@ -105,18 +123,22 @@ 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. 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 } // NewImportCommand defines a new command for exporting Kubernetes and Argo CD resources. func NewImportCommand() *cobra.Command { var ( - clientConfig clientcmd.ClientConfig - prune bool - dryRun bool - verbose bool - stopOperation bool + clientConfig clientcmd.ClientConfig + prune bool + dryRun bool + verbose bool + stopOperation bool + ignoreTracking bool + applicationNamespaces []string + applicationsetNamespaces []string ) command := cobra.Command{ Use: "import SOURCE", @@ -135,6 +157,8 @@ func NewImportCommand() *cobra.Command { namespace, _, err := clientConfig.Namespace() errors.CheckError(err) acdClients := newArgoCDClientsets(config, namespace) + client, err := dynamic.NewForConfig(config) + errors.CheckError(err) var input []byte if in := args[0]; in == "-" { @@ -148,6 +172,15 @@ func NewImportCommand() *cobra.Command { dryRunMsg = " (dry run)" } + additionalNamespaces := getAdditionalNamespaces(ctx, acdClients) + + if len(applicationNamespaces) == 0 { + applicationNamespaces = additionalNamespaces.applicationNamespaces + } + if len(applicationsetNamespaces) == 0 { + applicationsetNamespaces = additionalNamespaces.applicationsetNamespaces + } + // 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 @@ -159,7 +192,7 @@ func NewImportCommand() *cobra.Command { var referencedSecrets map[string]bool for _, cm := range configMaps.Items { if isArgoCDConfigMap(cm.GetName()) { - pruneObjects[kube.ResourceKey{Group: "", Kind: "ConfigMap", Name: cm.GetName()}] = cm + pruneObjects[kube.ResourceKey{Group: "", Kind: "ConfigMap", Name: cm.GetName(), Namespace: cm.GetNamespace()}] = cm } if cm.GetName() == common.ArgoCDConfigMapName { referencedSecrets = getReferencedSecrets(cm) @@ -170,18 +203,20 @@ func NewImportCommand() *cobra.Command { errors.CheckError(err) for _, secret := range secrets.Items { if isArgoCDSecret(referencedSecrets, secret) { - pruneObjects[kube.ResourceKey{Group: "", Kind: "Secret", Name: secret.GetName()}] = secret + pruneObjects[kube.ResourceKey{Group: "", Kind: "Secret", Name: secret.GetName(), Namespace: secret.GetNamespace()}] = secret } } applications, err := acdClients.applications.List(ctx, v1.ListOptions{}) errors.CheckError(err) for _, app := range applications.Items { - pruneObjects[kube.ResourceKey{Group: application.Group, Kind: application.ApplicationKind, Name: app.GetName()}] = app + 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, v1.ListOptions{}) errors.CheckError(err) for _, proj := range projects.Items { - pruneObjects[kube.ResourceKey{Group: application.Group, Kind: application.AppProjectKind, Name: proj.GetName()}] = proj + pruneObjects[kube.ResourceKey{Group: application.Group, Kind: application.AppProjectKind, Name: proj.GetName(), Namespace: proj.GetNamespace()}] = proj } applicationSets, err := acdClients.applicationSets.List(ctx, v1.ListOptions{}) if apierr.IsForbidden(err) || apierr.IsNotFound(err) { @@ -191,7 +226,9 @@ func NewImportCommand() *cobra.Command { } if applicationSets != nil { for _, appSet := range applicationSets.Items { - pruneObjects[kube.ResourceKey{Group: application.Group, Kind: application.ApplicationSetKind, Name: appSet.GetName()}] = appSet + if secutil.IsNamespaceEnabled(appSet.GetNamespace(), namespace, applicationsetNamespaces) { + pruneObjects[kube.ResourceKey{Group: application.Group, Kind: application.ApplicationSetKind, Name: appSet.GetName(), Namespace: appSet.GetNamespace()}] = appSet + } } } @@ -200,22 +237,41 @@ func NewImportCommand() *cobra.Command { errors.CheckError(err) for _, bakObj := range backupObjects { gvk := bakObj.GroupVersionKind() - key := kube.ResourceKey{Group: gvk.Group, Kind: gvk.Kind, Name: bakObj.GetName()} + // For objects without namespace, assume they belong in ArgoCD namespace + if bakObj.GetNamespace() == "" { + bakObj.SetNamespace(namespace) + } + key := kube.ResourceKey{Group: gvk.Group, Kind: gvk.Kind, Name: bakObj.GetName(), Namespace: bakObj.GetNamespace()} liveObj, exists := pruneObjects[key] delete(pruneObjects, key) var dynClient dynamic.ResourceInterface switch bakObj.GetKind() { case "Secret": - dynClient = acdClients.secrets + dynClient = client.Resource(secretResource).Namespace(bakObj.GetNamespace()) case "ConfigMap": - dynClient = acdClients.configMaps + dynClient = client.Resource(configMapResource).Namespace(bakObj.GetNamespace()) case application.AppProjectKind: - dynClient = acdClients.projects + dynClient = client.Resource(appprojectsResource).Namespace(bakObj.GetNamespace()) case application.ApplicationKind: - dynClient = acdClients.applications + 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 + } case application.ApplicationSetKind: - dynClient = acdClients.applicationSets + 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 + } + } + + // If there is a live object, remove the tracking annotations/label that might conflict + // when argo is managed with an application. + if ignoreTracking && exists { + updateTracking(bakObj, &liveObj) } + if !exists { isForbidden := false if !dryRun { @@ -228,7 +284,7 @@ func NewImportCommand() *cobra.Command { } } if !isForbidden { - fmt.Printf("%s/%s %s created%s\n", gvk.Group, gvk.Kind, bakObj.GetName(), dryRunMsg) + fmt.Printf("%s/%s %s in namespace %s created%s\n", gvk.Group, gvk.Kind, bakObj.GetName(), bakObj.GetNamespace(), dryRunMsg) } } else if specsEqual(*bakObj, liveObj) && checkAppHasNoNeedToStopOperation(liveObj, stopOperation) { if verbose { @@ -247,7 +303,7 @@ func NewImportCommand() *cobra.Command { } } if !isForbidden { - fmt.Printf("%s/%s %s updated%s\n", gvk.Group, gvk.Kind, bakObj.GetName(), dryRunMsg) + fmt.Printf("%s/%s %s in namespace %s updated%s\n", gvk.Group, gvk.Kind, bakObj.GetName(), bakObj.GetNamespace(), dryRunMsg) } } } @@ -258,11 +314,11 @@ func NewImportCommand() *cobra.Command { var dynClient dynamic.ResourceInterface switch key.Kind { case "Secret": - dynClient = acdClients.secrets + dynClient = client.Resource(secretResource).Namespace(liveObj.GetNamespace()) case application.AppProjectKind: - dynClient = acdClients.projects + dynClient = client.Resource(appprojectsResource).Namespace(liveObj.GetNamespace()) case application.ApplicationKind: - dynClient = acdClients.applications + dynClient = client.Resource(applicationsResource).Namespace(liveObj.GetNamespace()) if !dryRun { if finalizers := liveObj.GetFinalizers(); len(finalizers) > 0 { newLive := liveObj.DeepCopy() @@ -274,7 +330,7 @@ func NewImportCommand() *cobra.Command { } } case application.ApplicationSetKind: - dynClient = acdClients.applicationSets + dynClient = client.Resource(appplicationSetResource).Namespace(liveObj.GetNamespace()) default: log.Fatalf("Unexpected kind '%s' in prune list", key.Kind) } @@ -301,8 +357,11 @@ func NewImportCommand() *cobra.Command { clientConfig = cli.AddKubectlFlagsToCmd(&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(&verbose, "verbose", false, "Verbose output (versus only changed output)") command.Flags().BoolVar(&stopOperation, "stop-operation", false, "Stop any existing operations") + command.Flags().StringSliceVarP(&applicationNamespaces, "application-namespaces", "", []string{}, fmt.Sprintf("Comma separated list of namespace globs to which import of applications is allowed. If not provided value from '%s' in %s will be used,if it's not defined only applications without an explicit namespace will be imported to the Argo CD namespace", applicationNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName)) + command.Flags().StringSliceVarP(&applicationsetNamespaces, "applicationset-namespaces", "", []string{}, fmt.Sprintf("Comma separated list of namespace globs which import of applicationsets is allowed. If not provided value from '%s' in %s will be used,if it's not defined only applicationsets without an explicit namespace will be imported to the Argo CD namespace", applicationsetNamespacesCmdParamsKey, common.ArgoCDCmdParamsConfigMapName)) return &command } @@ -320,13 +379,14 @@ func checkAppHasNoNeedToStopOperation(liveObj unstructured.Unstructured, stopOpe } // export writes the unstructured object and removes extraneous cruft from output before writing -func export(w io.Writer, un unstructured.Unstructured) { +func export(w io.Writer, un unstructured.Unstructured, argocdNamespace string) { name := un.GetName() finalizers := un.GetFinalizers() apiVersion := un.GetAPIVersion() kind := un.GetKind() labels := un.GetLabels() annotations := un.GetAnnotations() + namespace := un.GetNamespace() unstructured.RemoveNestedField(un.Object, "metadata") un.SetName(name) un.SetFinalizers(finalizers) @@ -334,6 +394,9 @@ func export(w io.Writer, un unstructured.Unstructured) { un.SetKind(kind) un.SetLabels(labels) un.SetAnnotations(annotations) + if namespace != argocdNamespace { + un.SetNamespace(namespace) + } data, err := yaml.Marshal(un.Object) errors.CheckError(err) _, err = w.Write(data) @@ -368,3 +431,32 @@ func updateLive(bak, live *unstructured.Unstructured, stopOperation bool) *unstr } return newLive } + +// updateTracking will update the tracking label and annotation in the bak resources to the +// value of the live resource. +func updateTracking(bak, live *unstructured.Unstructured) { + // update the common annotation + bakAnnotations := bak.GetAnnotations() + liveAnnotations := live.GetAnnotations() + if liveAnnotations != nil && bakAnnotations != nil { + if v, ok := liveAnnotations[common.AnnotationKeyAppInstance]; ok { + if _, ok := bakAnnotations[common.AnnotationKeyAppInstance]; ok { + bakAnnotations[common.AnnotationKeyAppInstance] = v + bak.SetAnnotations(bakAnnotations) + } + } + } + + // update the common label + // A custom label can be set, but it is impossible to know which instance is managing the application + bakLabels := bak.GetLabels() + liveLabels := live.GetLabels() + if liveLabels != nil && bakLabels != nil { + if v, ok := liveLabels[common.LabelKeyAppInstance]; ok { + if _, ok := bakLabels[common.LabelKeyAppInstance]; ok { + bakLabels[common.LabelKeyAppInstance] = v + bak.SetLabels(bakLabels) + } + } + } +} diff --git a/cmd/argocd/commands/admin/backup_test.go b/cmd/argocd/commands/admin/backup_test.go new file mode 100644 index 0000000000000..b4fd07ad04c1a --- /dev/null +++ b/cmd/argocd/commands/admin/backup_test.go @@ -0,0 +1,87 @@ +package admin + +import ( + "testing" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" + "github.com/stretchr/testify/assert" + 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/v2/common" +) + +func newBackupObject(trackingValue string, trackingLabel bool, trackingAnnotation bool) *unstructured.Unstructured { + cm := v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-configmap", + Namespace: "namespace", + }, + Data: map[string]string{ + "foo": "bar", + }, + } + if trackingLabel { + cm.SetLabels(map[string]string{ + common.LabelKeyAppInstance: trackingValue, + }) + } + if trackingAnnotation { + cm.SetAnnotations(map[string]string{ + common.AnnotationKeyAppInstance: trackingValue, + }) + } + return kube.MustToUnstructured(&cm) +} + +func Test_updateTracking(t *testing.T) { + type args struct { + bak *unstructured.Unstructured + live *unstructured.Unstructured + } + tests := []struct { + name string + args args + expected *unstructured.Unstructured + }{ + { + name: "update annotation when present in live", + args: args{ + bak: newBackupObject("bak", false, true), + live: newBackupObject("live", false, true), + }, + expected: newBackupObject("live", false, true), + }, + { + name: "update default label when present in live", + args: args{ + bak: newBackupObject("bak", true, true), + live: newBackupObject("live", true, true), + }, + expected: newBackupObject("live", true, true), + }, + { + name: "do not update if live object does not have tracking", + args: args{ + bak: newBackupObject("bak", true, true), + live: newBackupObject("live", false, false), + }, + expected: newBackupObject("bak", true, true), + }, + { + name: "do not update if bak object does not have tracking", + args: args{ + bak: newBackupObject("bak", false, false), + live: newBackupObject("live", true, true), + }, + expected: newBackupObject("bak", false, false), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + updateTracking(tt.args.bak, tt.args.live) + assert.Equal(t, tt.expected, tt.args.bak) + }) + } +} diff --git a/cmd/argocd/commands/admin/cluster.go b/cmd/argocd/commands/admin/cluster.go index 932460dc24d26..48ee0254fd1b7 100644 --- a/cmd/argocd/commands/admin/cluster.go +++ b/cmd/argocd/commands/admin/cluster.go @@ -104,7 +104,12 @@ func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClie if err != nil { return nil, err } - client := redis.NewClient(&redis.Options{Addr: fmt.Sprintf("localhost:%d", port)}) + + redisOptions := &redis.Options{Addr: fmt.Sprintf("localhost:%d", port)} + if err = common.SetOptionalRedisPasswordFromKubeConfig(ctx, kubeClient, namespace, redisOptions); err != nil { + log.Warnf("Failed to fetch & set redis password for namespace %s: %v", namespace, err) + } + client := redis.NewClient(redisOptions) compressionType, err := cacheutil.CompressionTypeFromString(redisCompressionStr) if err != nil { return nil, err diff --git a/cmd/argocd/commands/admin/notifications.go b/cmd/argocd/commands/admin/notifications.go index 104a12a8596c2..32ae589270938 100644 --- a/cmd/argocd/commands/admin/notifications.go +++ b/cmd/argocd/commands/admin/notifications.go @@ -35,7 +35,8 @@ func NewNotificationsCommand() *cobra.Command { "notifications", "argocd admin notifications", applications, - settings.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm", false), func(clientConfig clientcmd.ClientConfig) { + settings.GetFactorySettingsForCLI(&argocdService, "argocd-notifications-secret", "argocd-notifications-cm", false), + func(clientConfig clientcmd.ClientConfig) { k8sCfg, err := clientConfig.ClientConfig() if err != nil { log.Fatalf("Failed to parse k8s config: %v", err) diff --git a/cmd/argocd/commands/admin/project_allowlist_test.go b/cmd/argocd/commands/admin/project_allowlist_test.go index eeec46b9be231..7c22fd1c0ee75 100644 --- a/cmd/argocd/commands/admin/project_allowlist_test.go +++ b/cmd/argocd/commands/admin/project_allowlist_test.go @@ -17,5 +17,5 @@ func TestProjectAllowListGen(t *testing.T) { globalProj, err := generateProjectAllowList(resourceList, "testdata/test_clusterrole.yaml", "testproj") require.NoError(t, err) - assert.Positive(t, len(globalProj.Spec.NamespaceResourceWhitelist)) + assert.NotEmpty(t, globalProj.Spec.NamespaceResourceWhitelist) } diff --git a/cmd/argocd/commands/admin/redis_initial_password.go b/cmd/argocd/commands/admin/redis_initial_password.go index eddd915373b15..3f89b54010659 100644 --- a/cmd/argocd/commands/admin/redis_initial_password.go +++ b/cmd/argocd/commands/admin/redis_initial_password.go @@ -6,25 +6,18 @@ import ( "fmt" "math/big" + "github.com/spf13/cobra" + corev1 "k8s.io/api/core/v1" apierr "k8s.io/apimachinery/pkg/api/errors" - - "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v2/util/cli" - 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/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" - - "github.com/spf13/cobra" - corev1 "k8s.io/api/core/v1" -) - -const ( - defaulRedisInitialPasswordSecretName = "argocd-redis" - defaultResisInitialPasswordKey = "auth" ) func generateRandomPassword() (string, error) { @@ -52,8 +45,8 @@ func NewRedisInitialPasswordCommand() *cobra.Command { namespace, _, err := clientConfig.Namespace() errors.CheckError(err) - redisInitialPasswordSecretName := defaulRedisInitialPasswordSecretName - redisInitialPasswordKey := defaultResisInitialPasswordKey + redisInitialPasswordSecretName := common.DefaultRedisInitialPasswordSecretName + redisInitialPasswordKey := common.DefaultRedisInitialPasswordKey fmt.Printf("Checking for initial Redis password in secret %s/%s at key %s. \n", namespace, redisInitialPasswordSecretName, redisInitialPasswordKey) config, err := clientConfig.ClientConfig() diff --git a/cmd/argocd/commands/admin/secrets_redactor_test.go b/cmd/argocd/commands/admin/secrets_redactor_test.go deleted file mode 100644 index cb1b3e78dbfea..0000000000000 --- a/cmd/argocd/commands/admin/secrets_redactor_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package admin - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -var textToRedact = ` -connectors: -- config: - clientID: aabbccddeeff00112233 - clientSecret: | - theSecret - orgs: - - name: your-github-org - redirectURI: https://argocd.example.com/api/dex/callback - id: github - name: GitHub - type: github -- config: - bindDN: uid=serviceaccount,cn=users,dc=example,dc=com - bindPW: theSecret - host: ldap.example.com:636 - id: ldap - name: LDAP - type: ldap -grpc: - addr: 0.0.0.0:5557 -telemetry: - http: 0.0.0.0:5558 -issuer: https://argocd.example.com/api/dex -oauth2: - skipApprovalScreen: true -staticClients: -- id: argo-cd - name: Argo CD - redirectURIs: - - https://argocd.example.com/auth/callback - secret: Dis9M-GA11oTwZVQQWdDklPQw-sWXZkWJFyyEhMs -- id: argo-cd-cli - name: Argo CD CLI - public: true - redirectURIs: - - http://localhost -storage: - type: memory -web: - http: 0.0.0.0:5556` - -var expectedRedaction = `connectors: -- config: - clientID: aabbccddeeff00112233 - clientSecret: '********' - orgs: - - name: your-github-org - redirectURI: https://argocd.example.com/api/dex/callback - id: github - name: GitHub - type: github -- config: - bindDN: uid=serviceaccount,cn=users,dc=example,dc=com - bindPW: '********' - host: ldap.example.com:636 - id: ldap - name: LDAP - type: ldap -grpc: - addr: 0.0.0.0:5557 -issuer: https://argocd.example.com/api/dex -oauth2: - skipApprovalScreen: true -staticClients: -- id: argo-cd - name: Argo CD - redirectURIs: - - https://argocd.example.com/auth/callback - secret: '********' -- id: argo-cd-cli - name: Argo CD CLI - public: true - redirectURIs: - - http://localhost -storage: - type: memory -telemetry: - http: 0.0.0.0:5558 -web: - http: 0.0.0.0:5556 -` - -func TestSecretsRedactor(t *testing.T) { - assert.Equal(t, expectedRedaction, redactor(textToRedact)) -} diff --git a/cmd/argocd/commands/admin/settings.go b/cmd/argocd/commands/admin/settings.go index b9c68bbbd58f6..7cd49b0c94031 100644 --- a/cmd/argocd/commands/admin/settings.go +++ b/cmd/argocd/commands/admin/settings.go @@ -159,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") diff --git a/cmd/argocd/commands/admin/settings_rbac.go b/cmd/argocd/commands/admin/settings_rbac.go index de0a857397f62..dc8faf657b520 100644 --- a/cmd/argocd/commands/admin/settings_rbac.go +++ b/cmd/argocd/commands/admin/settings_rbac.go @@ -18,6 +18,7 @@ import ( "github.com/argoproj/argo-cd/v2/server/rbacpolicy" "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" ) @@ -28,7 +29,7 @@ type rbacTrait struct { } // Provide a mapping of short-hand resource names to their RBAC counterparts -var resourceMap map[string]string = map[string]string{ +var resourceMap = map[string]string{ "account": rbacpolicy.ResourceAccounts, "app": rbacpolicy.ResourceApplications, "apps": rbacpolicy.ResourceApplications, @@ -52,8 +53,17 @@ var resourceMap map[string]string = map[string]string{ "repository": rbacpolicy.ResourceRepositories, } +var projectScoped = map[string]bool{ + rbacpolicy.ResourceApplications: true, + rbacpolicy.ResourceApplicationSets: true, + rbacpolicy.ResourceLogs: true, + rbacpolicy.ResourceExec: true, + rbacpolicy.ResourceClusters: true, + rbacpolicy.ResourceRepositories: true, +} + // List of allowed RBAC resources -var validRBACResourcesActions map[string]actionTraitMap = map[string]actionTraitMap{ +var validRBACResourcesActions = map[string]actionTraitMap{ rbacpolicy.ResourceAccounts: accountsActions, rbacpolicy.ResourceApplications: applicationsActions, rbacpolicy.ResourceApplicationSets: defaultCRUDActions, @@ -109,7 +119,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", @@ -117,13 +127,13 @@ func NewRBACCommand() *cobra.Command { c.HelpFunc()(c, args) }, } - command.AddCommand(NewRBACCanCommand()) + command.AddCommand(NewRBACCanCommand(cmdCtx)) command.AddCommand(NewRBACValidateCommand()) return command } -// NewRBACCanRoleCommand is the command for 'rbac can-role' -func NewRBACCanCommand() *cobra.Command { +// NewRBACCanCommand is the command for 'rbac can' +func NewRBACCanCommand(cmdCtx commandContext) *cobra.Command { var ( policyFile string defaultRole string @@ -175,11 +185,6 @@ argocd admin settings rbac can someuser create application 'default/app' --defau subResource = args[3] } - userPolicy := "" - builtinPolicy := "" - - var newDefaultRole string - namespace, nsOverride, err := clientConfig.Namespace() if err != nil { log.Fatalf("could not create k8s client: %v", err) @@ -203,6 +208,7 @@ argocd admin settings rbac can someuser create application 'default/app' --defau userPolicy, newDefaultRole, matchMode := getPolicy(ctx, policyFile, realClientset, namespace) // Use built-in policy as augmentation if requested + builtinPolicy := "" if useBuiltin { builtinPolicy = assets.BuiltinPolicyCSV } @@ -213,7 +219,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) == rbacpolicy.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") @@ -359,20 +388,16 @@ func getPolicyFromFile(policyFile string) (string, string, string, error) { // Retrieve policy information from a ConfigMap func getPolicyFromConfigMap(cm *corev1.ConfigMap) (string, string, string) { var ( - userPolicy string defaultRole string ok bool ) - userPolicy, ok = cm.Data[rbac.ConfigMapPolicyCSVKey] - if !ok { - userPolicy = "" - } + defaultRole, ok = cm.Data[rbac.ConfigMapPolicyDefaultKey] if !ok { defaultRole = "" } - return userPolicy, defaultRole, cm.Data[rbac.ConfigMapMatchModeKey] + return rbac.PolicyCSV(cm.Data), defaultRole, cm.Data[rbac.ConfigMapMatchModeKey] } // getPolicyConfigMap fetches the RBAC config map from K8s cluster @@ -386,7 +411,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) @@ -420,15 +445,19 @@ func checkPolicy(subject, action, resource, subResource, builtinPolicy, userPoli } } - // Application resources have a special notation - for simplicity's sake, + // Some project scoped resources have a special notation - for simplicity's sake, // if user gives no sub-resource (or specifies simple '*'), we construct // the required notation by setting subresource to '*/*'. - if realResource == rbacpolicy.ResourceApplications { + if projectScoped[realResource] { if subResource == "*" || subResource == "" { subResource = "*/*" } } - + if realResource == rbacpolicy.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 c2a5c6c2c3370..9fe9ab6953a68 100644 --- a/cmd/argocd/commands/admin/settings_rbac_test.go +++ b/cmd/argocd/commands/admin/settings_rbac_test.go @@ -130,6 +130,16 @@ func Test_PolicyFromYAML(t *testing.T) { 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, nil)) +} + +func trueLogRbacEnforce() bool { + return true +} + +func falseLogRbacEnforce() bool { + return false } func Test_PolicyFromK8s(t *testing.T) { @@ -153,43 +163,105 @@ func Test_PolicyFromK8s(t *testing.T) { 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, 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, 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, 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, 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, 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) }) } @@ -229,49 +301,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/testdata/rbac/argocd-rbac-cm.yaml b/cmd/argocd/commands/admin/testdata/rbac/argocd-rbac-cm.yaml index bf947fb8b7110..ed98df6c94879 100644 --- a/cmd/argocd/commands/admin/testdata/rbac/argocd-rbac-cm.yaml +++ b/cmd/argocd/commands/admin/testdata/rbac/argocd-rbac-cm.yaml @@ -12,6 +12,10 @@ data: p, role:user, applicationsets, delete, */*, allow p, role:user, logs, get, */*, allow g, test, role:user + policy.overlay.csv: | + p, role:tester, applications, *, */*, allow + p, role:tester, projects, *, *, allow + g, my-org:team-qa, role:tester policy.default: role:unknown kind: ConfigMap metadata: diff --git a/cmd/argocd/commands/admin/testdata/rbac/policy.csv b/cmd/argocd/commands/admin/testdata/rbac/policy.csv index b18d0904f5f60..a9f830ae92d8c 100644 --- a/cmd/argocd/commands/admin/testdata/rbac/policy.csv +++ b/cmd/argocd/commands/admin/testdata/rbac/policy.csv @@ -10,4 +10,6 @@ p, role:user, applicationsets, delete, */*, allow p, role:test, certificates, get, *, allow p, role:test, logs, get, */*, allow p, role:test, exec, create, */*, allow +p, log-allow-user, logs, get, */*, allow +p, log-deny-user, logs, get, */*, deny g, test, role:user diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 2218eb2163a54..500c0ada88260 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -294,7 +294,7 @@ func parentChildDetails(appIf application.ApplicationServiceClient, ctx context. return mapUidToNode, mapParentToChild, parentNode } -func printHeader(acdClient argocdclient.Client, app *argoappv1.Application, ctx context.Context, windows *argoappv1.SyncWindows, showOperation bool, showParams bool) { +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) @@ -309,20 +309,21 @@ func printHeader(acdClient argocdclient.Client, app *argoappv1.Application, ctx fmt.Println() printOperationResult(app.Status.OperationState) } - if !app.Spec.HasMultipleSources() && showParams { - printParams(app) + if showParams { + printParams(app, sourcePosition) } } // NewApplicationGetCommand returns a new instance of an `argocd app get` command func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( - refresh bool - hardRefresh bool - output string - showParams bool - showOperation bool - appNamespace string + refresh bool + hardRefresh bool + output string + showParams bool + showOperation bool + appNamespace string + sourcePosition int ) command := &cobra.Command{ Use: "get APPNAME", @@ -343,6 +344,9 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com # Show application parameters and overrides argocd app get my-app --show-params + # Show application parameters and overrides for a source at position 1 under spec.sources of app my-app + argocd app get my-app --show-params --source-position 1 + # Refresh application data when retrieving argocd app get my-app --refresh @@ -373,9 +377,17 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com Refresh: getRefreshType(refresh, hardRefresh), AppNamespace: &appNs, }) - errors.CheckError(err) + if app.Spec.HasMultipleSources() { + if sourcePosition <= 0 { + errors.CheckError(fmt.Errorf("Source position should be specified and must be greater than 0 for applications with multiple sources")) + } + if len(app.Spec.GetSources()) < sourcePosition { + 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 argoio.Close(pConn) proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: app.Spec.Project}) @@ -388,7 +400,7 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com err := PrintResource(app, output) errors.CheckError(err) case "wide", "": - printHeader(acdClient, app, ctx, windows, showOperation, showParams) + 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) @@ -396,14 +408,14 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com _ = w.Flush() } case "tree": - printHeader(acdClient, app, ctx, windows, showOperation, showParams) + 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) } case "tree=detailed": - printHeader(acdClient, app, ctx, windows, showOperation, showParams) + printHeader(acdClient, app, ctx, windows, showOperation, showParams, sourcePosition) mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState := resourceParentChild(ctx, acdClient, appName, appNs) if len(mapUidToNode) > 0 { fmt.Println() @@ -420,6 +432,7 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com command.Flags().BoolVar(&refresh, "refresh", false, "Refresh application data when retrieving") command.Flags().BoolVar(&hardRefresh, "hard-refresh", false, "Refresh application data as well as target manifests cache") command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only get application from namespace") + command.Flags().IntVar(&sourcePosition, "source-position", -1, "Position of the source from the list of sources of the app. Counting starts at 1.") return command } @@ -701,9 +714,22 @@ func truncateString(str string, num int) string { } // printParams prints parameters and overrides -func printParams(app *argoappv1.Application) { - if app.Spec.GetSource().Helm != nil { - printHelmParams(app.Spec.GetSource().Helm) +func printParams(app *argoappv1.Application, sourcePosition int) { + var source *argoappv1.ApplicationSource + + if app.Spec.HasMultipleSources() { + // Get the source by the sourcePosition whose params you'd like to print + source = app.Spec.GetSourcePtrByPosition(sourcePosition) + if source == nil { + source = &argoappv1.ApplicationSource{} + } + } else { + src := app.Spec.GetSource() + source = &src + } + + if source.Helm != nil { + printHelmParams(source.Helm) } } @@ -776,8 +802,6 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com } } - // sourcePosition startes with 1, thus, it needs to be decreased by 1 to find the correct index in the list of sources - sourcePosition = sourcePosition - 1 visited := cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, sourcePosition) if visited == 0 { log.Error("Please set at least one option to update") @@ -795,9 +819,9 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com errors.CheckError(err) }, } - command.Flags().IntVar(&sourcePosition, "source-position", -1, "Position of the source from the list of sources of the app. Counting starts at 1.") cmdutil.AddAppFlags(command, &appOpts) command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Set application parameters in namespace") + command.Flags().IntVar(&sourcePosition, "source-position", -1, "Position of the source from the list of sources of the app. Counting starts at 1.") return command } @@ -1056,17 +1080,18 @@ func getLocalObjectsString(ctx context.Context, app *argoappv1.Application, proj ) []string { source := app.Spec.GetSource() res, err := repository.GenerateManifests(ctx, local, localRepoRoot, source.TargetRevision, &repoapiclient.ManifestRequest{ - Repo: &argoappv1.Repository{Repo: source.RepoURL}, - AppLabelKey: appLabelKey, - AppName: app.Name, - Namespace: app.Spec.Destination.Namespace, - ApplicationSource: &source, - KustomizeOptions: kustomizeOptions, - KubeVersion: kubeVersion, - ApiVersions: apiVersions, - TrackingMethod: trackingMethod, - ProjectName: proj.Name, - ProjectSourceRepos: proj.Spec.SourceRepos, + Repo: &argoappv1.Repository{Repo: source.RepoURL}, + AppLabelKey: appLabelKey, + AppName: app.Name, + Namespace: app.Spec.Destination.Namespace, + ApplicationSource: &source, + KustomizeOptions: kustomizeOptions, + KubeVersion: kubeVersion, + ApiVersions: apiVersions, + TrackingMethod: trackingMethod, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, + AnnotationManifestGeneratePaths: app.GetAnnotation(argoappv1.AnnotationKeyManifestGeneratePaths), }, true, &git.NoopCredsStore{}, resource.MustParse("0"), nil) errors.CheckError(err) @@ -1257,7 +1282,7 @@ func findandPrintDiff(ctx context.Context, app *argoappv1.Application, proj *arg 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) - } else if diffOptions.revision != "" || (diffOptions.revisions != nil && 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) @@ -1908,7 +1933,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co if len(projects) != 0 { errMsg += fmt.Sprintf(" projects %v", projects) } - log.Fatalf(errMsg) + log.Fatal(errMsg) } for _, i := range list.Items { @@ -2169,7 +2194,7 @@ func getAppNamesBySelector(ctx context.Context, appIf application.ApplicationSer return appNames, nil } -// ResourceDiff tracks the state of a resource when waiting on an application status. +// ResourceState tracks the state of a resource when waiting on an application status. type resourceState struct { Group string Kind string @@ -2361,6 +2386,10 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, // time when the sync status lags behind when an operation completes refresh := false + // 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" + appRealName, appNs := argo.ParseFromQualifiedName(appName, "") printFinalStatus := func(app *argoappv1.Application) *argoappv1.Application { @@ -2377,11 +2406,13 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, _ = conn.Close() } - fmt.Println() - printAppSummaryTable(app, appURL(ctx, acdClient, appName), nil) - fmt.Println() - if watch.operation { - printOperationResult(app.Status.OperationState) + if printSummary { + fmt.Println() + printAppSummaryTable(app, appURL(ctx, acdClient, appName), nil) + fmt.Println() + if watch.operation { + printOperationResult(app.Status.OperationState) + } } switch output { @@ -2396,13 +2427,13 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, _ = w.Flush() } case "tree": - mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState := resourceParentChild(ctx, acdClient, appName, appNs) + mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState := resourceParentChild(ctx, acdClient, appRealName, appNs) if len(mapUidToNode) > 0 { fmt.Println() printTreeView(mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState) } case "tree=detailed": - mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState := resourceParentChild(ctx, acdClient, appName, appNs) + mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState := resourceParentChild(ctx, acdClient, appRealName, appNs) if len(mapUidToNode) > 0 { fmt.Println() printTreeViewDetailed(mapUidToNode, mapParentToChild, parentNode, mapNodeNameToResourceState) @@ -2421,17 +2452,26 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, AppNamespace: &appNs, }) errors.CheckError(err) - fmt.Println() - fmt.Println("This is the state of the app after `wait` timed out:") + + if printSummary { + fmt.Println() + fmt.Println("This is the state of the app after `wait` timed out:") + } + printFinalStatus(app) cancel() - fmt.Println() - fmt.Println("The command timed out waiting for the conditions to be met.") + + if printSummary { + fmt.Println() + fmt.Println("The command timed out waiting for the conditions to be met.") + } }) } w := tabwriter.NewWriter(os.Stdout, 5, 0, 2, ' ', 0) - _, _ = fmt.Fprintf(w, waitFormatString, "TIMESTAMP", "GROUP", "KIND", "NAMESPACE", "NAME", "STATUS", "HEALTH", "HOOK", "MESSAGE") + if printSummary { + _, _ = fmt.Fprintf(w, waitFormatString, "TIMESTAMP", "GROUP", "KIND", "NAMESPACE", "NAME", "STATUS", "HEALTH", "HOOK", "MESSAGE") + } prevStates := make(map[string]*resourceState) conn, appClient := acdClient.NewApplicationClientOrDie() @@ -2515,7 +2555,7 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, prevStates[stateKey] = newState doPrint = true } - if doPrint { + if doPrint && printSummary { _, _ = fmt.Fprintf(w, waitFormatString, prevStates[stateKey].FormatItems()...) } } @@ -2836,6 +2876,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob errors.CheckError(err) 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) } else if len(revisions) > 0 && len(sourcePositions) > 0 { q := application.ApplicationManifestQuery{ diff --git a/cmd/argocd/commands/app_resource_test.go b/cmd/argocd/commands/app_resource_test.go index 5b85f96050109..4a6cd50d6800f 100644 --- a/cmd/argocd/commands/app_resource_test.go +++ b/cmd/argocd/commands/app_resource_test.go @@ -36,7 +36,7 @@ func TestPrintTreeViewAppResources(t *testing.T) { buf := &bytes.Buffer{} w := tabwriter.NewWriter(buf, 0, 0, 2, ' ', 0) - printTreeViewAppResourcesNotOrphaned(nodeMapping, mapParentToChild, parentNode, false, false, w) + printTreeViewAppResourcesNotOrphaned(nodeMapping, mapParentToChild, parentNode, w) if err := w.Flush(); err != nil { t.Fatal(err) } @@ -77,7 +77,7 @@ func TestPrintTreeViewDetailedAppResources(t *testing.T) { buf := &bytes.Buffer{} w := tabwriter.NewWriter(buf, 0, 0, 2, ' ', 0) - printDetailedTreeViewAppResourcesNotOrphaned(nodeMapping, mapParentToChild, parentNode, false, false, w) + printDetailedTreeViewAppResourcesNotOrphaned(nodeMapping, mapParentToChild, parentNode, w) if err := w.Flush(); err != nil { t.Fatal(err) } diff --git a/cmd/argocd/commands/app_resources.go b/cmd/argocd/commands/app_resources.go index c1fc1dfc82f2a..f86ab0669661b 100644 --- a/cmd/argocd/commands/app_resources.go +++ b/cmd/argocd/commands/app_resources.go @@ -175,25 +175,25 @@ func parentChildInfo(nodes []v1alpha1.ResourceNode) (map[string]v1alpha1.Resourc return mapUidToNode, mapParentToChild, parentNode } -func printDetailedTreeViewAppResourcesNotOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, orphaned bool, listAll bool, w *tabwriter.Writer) { +func printDetailedTreeViewAppResourcesNotOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, w *tabwriter.Writer) { for uid := range parentNodes { detailedTreeViewAppResourcesNotOrphaned("", nodeMapping, parentChildMapping, nodeMapping[uid], w) } } -func printDetailedTreeViewAppResourcesOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, orphaned bool, listAll bool, w *tabwriter.Writer) { +func printDetailedTreeViewAppResourcesOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, w *tabwriter.Writer) { for uid := range parentNodes { detailedTreeViewAppResourcesOrphaned("", nodeMapping, parentChildMapping, nodeMapping[uid], w) } } -func printTreeViewAppResourcesNotOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, orphaned bool, listAll bool, w *tabwriter.Writer) { +func printTreeViewAppResourcesNotOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, w *tabwriter.Writer) { for uid := range parentNodes { treeViewAppResourcesNotOrphaned("", nodeMapping, parentChildMapping, nodeMapping[uid], w) } } -func printTreeViewAppResourcesOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, orphaned bool, listAll bool, w *tabwriter.Writer) { +func printTreeViewAppResourcesOrphaned(nodeMapping map[string]v1alpha1.ResourceNode, parentChildMapping map[string][]string, parentNodes map[string]struct{}, w *tabwriter.Writer) { for uid := range parentNodes { treeViewAppResourcesOrphaned("", nodeMapping, parentChildMapping, nodeMapping[uid], w) } @@ -206,24 +206,24 @@ func printResources(listAll bool, orphaned bool, appResourceTree *v1alpha1.Appli if !orphaned || listAll { mapUidToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.Nodes) - printDetailedTreeViewAppResourcesNotOrphaned(mapUidToNode, mapParentToChild, parentNode, orphaned, listAll, w) + printDetailedTreeViewAppResourcesNotOrphaned(mapUidToNode, mapParentToChild, parentNode, w) } if orphaned || listAll { mapUidToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.OrphanedNodes) - printDetailedTreeViewAppResourcesOrphaned(mapUidToNode, mapParentToChild, parentNode, orphaned, listAll, w) + printDetailedTreeViewAppResourcesOrphaned(mapUidToNode, mapParentToChild, parentNode, w) } } 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, orphaned, listAll, w) + printTreeViewAppResourcesNotOrphaned(mapUidToNode, mapParentToChild, parentNode, w) } if orphaned || listAll { mapUidToNode, mapParentToChild, parentNode := parentChildInfo(appResourceTree.OrphanedNodes) - printTreeViewAppResourcesOrphaned(mapUidToNode, mapParentToChild, parentNode, orphaned, listAll, w) + printTreeViewAppResourcesOrphaned(mapUidToNode, mapParentToChild, parentNode, w) } } else { headers := []interface{}{"GROUP", "KIND", "NAMESPACE", "NAME", "ORPHANED"} diff --git a/cmd/argocd/commands/app_test.go b/cmd/argocd/commands/app_test.go index 73eace8bd250a..ffd7d78329cd9 100644 --- a/cmd/argocd/commands/app_test.go +++ b/cmd/argocd/commands/app_test.go @@ -2,13 +2,25 @@ package commands import ( "context" + "encoding/json" "fmt" "io" "net/http" "os" + "slices" + "strings" "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" @@ -906,35 +918,83 @@ func TestPrintAppConditions(t *testing.T) { } func TestPrintParams(t *testing.T) { - output, _ := captureOutput(func() error { - app := &v1alpha1.Application{ - Spec: v1alpha1.ApplicationSpec{ - Source: &v1alpha1.ApplicationSource{ - Helm: &v1alpha1.ApplicationSourceHelm{ - Parameters: []v1alpha1.HelmParameter{ - { - Name: "name1", - Value: "value1", + testCases := []struct { + name string + app *v1alpha1.Application + sourcePosition int + expectedOutput string + }{ + { + name: "Single Source application with valid helm parameters", + app: &v1alpha1.Application{ + Spec: v1alpha1.ApplicationSpec{ + Source: &v1alpha1.ApplicationSource{ + Helm: &v1alpha1.ApplicationSourceHelm{ + Parameters: []v1alpha1.HelmParameter{ + { + Name: "name1", + Value: "value1", + }, + { + Name: "name2", + Value: "value2", + }, + { + Name: "name3", + Value: "value3", + }, }, - { - Name: "name2", - Value: "value2", + }, + }, + }, + }, + sourcePosition: -1, + expectedOutput: "\n\nNAME VALUE\nname1 value1\nname2 value2\nname3 value3\n", + }, + { + name: "Multi-source application with a valid Source Position", + app: &v1alpha1.Application{ + Spec: v1alpha1.ApplicationSpec{ + Sources: []v1alpha1.ApplicationSource{ + { + Helm: &v1alpha1.ApplicationSourceHelm{ + Parameters: []v1alpha1.HelmParameter{ + { + Name: "nameA", + Value: "valueA", + }, + }, }, - { - Name: "name3", - Value: "value3", + }, + { + Helm: &v1alpha1.ApplicationSourceHelm{ + Parameters: []v1alpha1.HelmParameter{ + { + Name: "nameB", + Value: "valueB", + }, + }, }, }, }, }, }, - } - printParams(app) - return nil - }) - expectation := "\n\nNAME VALUE\nname1 value1\nname2 value2\nname3 value3\n" - if output != expectation { - t.Fatalf("Incorrect print params output %q, should be %q", output, expectation) + sourcePosition: 1, + expectedOutput: "\n\nNAME VALUE\nnameA valueA\n", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + output, _ := captureOutput(func() error { + printParams(tc.app, tc.sourcePosition) + return nil + }) + + if output != tc.expectedOutput { + t.Fatalf("Incorrect print params output %q, should be %q\n", output, tc.expectedOutput) + } + }) } } @@ -1323,6 +1383,14 @@ func TestFilterAppResources(t *testing.T) { Namespace: "", Exclude: true, } + // apps:ReplicaSet:* + includeAllReplicaSetResource = v1alpha1.SyncOperationResource{ + Group: "apps", + Kind: "ReplicaSet", + Name: "*", + Namespace: "", + Exclude: false, + } // apps:ReplicaSet:replicaSet-name1 includeReplicaSet1Resource = v1alpha1.SyncOperationResource{ Group: "apps", @@ -1395,13 +1463,13 @@ func TestFilterAppResources(t *testing.T) { { testName: "Include ReplicaSet replicaSet-name1 resource and exclude all service resources", selectedResources: []*v1alpha1.SyncOperationResource{&excludeAllServiceResources, &includeReplicaSet1Resource}, - expectedResult: []*v1alpha1.SyncOperationResource{&replicaSet1, &replicaSet2, &job, &deployment}, + expectedResult: []*v1alpha1.SyncOperationResource{&replicaSet1}, }, // --resource !apps:ReplicaSet:replicaSet-name2 --resource !*:Service:* { testName: "Exclude ReplicaSet replicaSet-name2 resource and all service resources", selectedResources: []*v1alpha1.SyncOperationResource{&excludeReplicaSet2Resource, &excludeAllServiceResources}, - expectedResult: []*v1alpha1.SyncOperationResource{&replicaSet1, &replicaSet2, &job, &service1, &service2, &deployment}, + expectedResult: []*v1alpha1.SyncOperationResource{&replicaSet1, &job, &deployment}, }, // --resource !apps:ReplicaSet:replicaSet-name2 { @@ -1415,6 +1483,12 @@ func TestFilterAppResources(t *testing.T) { selectedResources: []*v1alpha1.SyncOperationResource{&includeReplicaSet1Resource}, expectedResult: []*v1alpha1.SyncOperationResource{&replicaSet1}, }, + // --resource apps:ReplicaSet:* --resource !apps:ReplicaSet:replicaSet-name2 + { + testName: "Include All ReplicaSet resource and exclude replicaSet-name1 resource", + selectedResources: []*v1alpha1.SyncOperationResource{&includeAllReplicaSetResource, &excludeReplicaSet2Resource}, + expectedResult: []*v1alpha1.SyncOperationResource{&replicaSet1}, + }, // --resource !*:Service:* { testName: "Exclude Service resources", @@ -1849,6 +1923,316 @@ func testApp(name, project string, labels map[string]string, annotations map[str } } +func TestWaitOnApplicationStatus_JSON_YAML_WideOutput(t *testing.T) { + acdClient := &customAcdClient{&fakeAcdClient{}} + ctx := context.Background() + var selectResource []*v1alpha1.SyncOperationResource + watch := watchOpts{ + sync: false, + health: false, + operation: true, + suspended: false, + } + watch = getWatchOpts(watch) + + output, err := captureOutput(func() error { + _, _, _ = waitOnApplicationStatus(ctx, acdClient, "app-name", 0, watch, selectResource, "json") + return nil + }, + ) + require.NoError(t, err) + assert.True(t, json.Valid([]byte(output))) + + output, err = captureOutput(func() error { + _, _, _ = waitOnApplicationStatus(ctx, acdClient, "app-name", 0, watch, selectResource, "yaml") + return nil + }) + + require.NoError(t, err) + err = yaml.Unmarshal([]byte(output), &v1alpha1.Application{}) + require.NoError(t, err) + + output, _ = captureOutput(func() error { + _, _, _ = waitOnApplicationStatus(ctx, acdClient, "app-name", 0, 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 + +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-message) + +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) +} + +type customAcdClient struct { + *fakeAcdClient +} + +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{}) + + newApp := v1alpha1.Application{ + TypeMeta: app.TypeMeta, + ObjectMeta: app.ObjectMeta, + Spec: app.Spec, + Status: app.Status, + Operation: app.Operation, + } + + go func() { + appEventsCh <- &v1alpha1.ApplicationWatchEvent{ + Type: watch.Bookmark, + Application: newApp, + } + close(appEventsCh) + }() + + return appEventsCh +} + +func (c *customAcdClient) NewApplicationClientOrDie() (io.Closer, applicationpkg.ApplicationServiceClient) { + return &fakeConnection{}, &fakeAppServiceClient{} +} + +func (c *customAcdClient) NewSettingsClientOrDie() (io.Closer, settingspkg.SettingsServiceClient) { + return &fakeConnection{}, &fakeSettingsServiceClient{} +} + +type fakeConnection struct{} + +func (c *fakeConnection) Close() error { + return nil +} + +type fakeSettingsServiceClient struct{} + +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(ctx context.Context, in *settingspkg.SettingsQuery, opts ...grpc.CallOption) (*settingspkg.SettingsPluginsResponse, error) { + return nil, nil +} + +type fakeAppServiceClient struct{} + +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{ + Name: "test", + Namespace: "argocd", + }, + Spec: v1alpha1.ApplicationSpec{ + SyncPolicy: &v1alpha1.SyncPolicy{ + Automated: &v1alpha1.SyncPolicyAutomated{ + Prune: true, + }, + }, + Project: "default", + Destination: v1alpha1.ApplicationDestination{Server: "local", Namespace: "argocd"}, + Source: &v1alpha1.ApplicationSource{ + RepoURL: "test", + TargetRevision: "master", + Path: "/test", + Helm: &v1alpha1.ApplicationSourceHelm{ + ValueFiles: []string{"path1", "path2"}, + }, + Kustomize: &v1alpha1.ApplicationSourceKustomize{NamePrefix: "prefix"}, + }, + }, + Status: v1alpha1.ApplicationStatus{ + Resources: []v1alpha1.ResourceStatus{ + { + Group: "", + Kind: "Service", + Namespace: "default", + Name: "service-name1", + Status: "Synced", + Health: &v1alpha1.HealthStatus{ + Status: health.HealthStatusHealthy, + Message: "health-message", + }, + }, + { + Group: "apps", + Kind: "Deployment", + Namespace: "default", + Name: "test", + Status: "Synced", + Health: &v1alpha1.HealthStatus{ + Status: health.HealthStatusHealthy, + Message: "health-message", + }, + }, + }, + OperationState: &v1alpha1.OperationState{ + SyncResult: &v1alpha1.SyncOperationResult{ + Revision: "revision", + }, + FinishedAt: &time, + Message: "test", + }, + Sync: v1alpha1.SyncStatus{ + Status: v1alpha1.SyncStatusCodeOutOfSync, + }, + Health: v1alpha1.HealthStatus{ + Status: health.HealthStatusProgressing, + Message: "health-message", + }, + }, + }, nil +} + +func (c *fakeAppServiceClient) List(ctx context.Context, in *applicationpkg.ApplicationQuery, opts ...grpc.CallOption) (*v1alpha1.ApplicationList, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) ListResourceEvents(ctx context.Context, in *applicationpkg.ApplicationResourceEventsQuery, opts ...grpc.CallOption) (*v1.EventList, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) Watch(ctx context.Context, in *applicationpkg.ApplicationQuery, opts ...grpc.CallOption) (applicationpkg.ApplicationService_WatchClient, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) Create(ctx context.Context, in *applicationpkg.ApplicationCreateRequest, opts ...grpc.CallOption) (*v1alpha1.Application, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) GetApplicationSyncWindows(ctx context.Context, in *applicationpkg.ApplicationSyncWindowsQuery, opts ...grpc.CallOption) (*applicationpkg.ApplicationSyncWindowsResponse, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) RevisionMetadata(ctx context.Context, in *applicationpkg.RevisionMetadataQuery, opts ...grpc.CallOption) (*v1alpha1.RevisionMetadata, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) RevisionChartDetails(ctx context.Context, in *applicationpkg.RevisionMetadataQuery, opts ...grpc.CallOption) (*v1alpha1.ChartDetails, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) GetManifests(ctx context.Context, in *applicationpkg.ApplicationManifestQuery, opts ...grpc.CallOption) (*apiclient.ManifestResponse, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) GetManifestsWithFiles(ctx context.Context, opts ...grpc.CallOption) (applicationpkg.ApplicationService_GetManifestsWithFilesClient, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) Update(ctx context.Context, in *applicationpkg.ApplicationUpdateRequest, opts ...grpc.CallOption) (*v1alpha1.Application, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) UpdateSpec(ctx context.Context, in *applicationpkg.ApplicationUpdateSpecRequest, opts ...grpc.CallOption) (*v1alpha1.ApplicationSpec, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) Patch(ctx context.Context, in *applicationpkg.ApplicationPatchRequest, opts ...grpc.CallOption) (*v1alpha1.Application, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) Delete(ctx context.Context, in *applicationpkg.ApplicationDeleteRequest, opts ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) Sync(ctx context.Context, in *applicationpkg.ApplicationSyncRequest, opts ...grpc.CallOption) (*v1alpha1.Application, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) ManagedResources(ctx context.Context, in *applicationpkg.ResourcesQuery, opts ...grpc.CallOption) (*applicationpkg.ManagedResourcesResponse, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) ResourceTree(ctx context.Context, in *applicationpkg.ResourcesQuery, opts ...grpc.CallOption) (*v1alpha1.ApplicationTree, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) WatchResourceTree(ctx context.Context, in *applicationpkg.ResourcesQuery, opts ...grpc.CallOption) (applicationpkg.ApplicationService_WatchResourceTreeClient, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) Rollback(ctx context.Context, in *applicationpkg.ApplicationRollbackRequest, opts ...grpc.CallOption) (*v1alpha1.Application, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) TerminateOperation(ctx context.Context, in *applicationpkg.OperationTerminateRequest, opts ...grpc.CallOption) (*applicationpkg.OperationTerminateResponse, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) GetResource(ctx context.Context, in *applicationpkg.ApplicationResourceRequest, opts ...grpc.CallOption) (*applicationpkg.ApplicationResourceResponse, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) PatchResource(ctx context.Context, in *applicationpkg.ApplicationResourcePatchRequest, opts ...grpc.CallOption) (*applicationpkg.ApplicationResourceResponse, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) ListResourceActions(ctx context.Context, in *applicationpkg.ApplicationResourceRequest, opts ...grpc.CallOption) (*applicationpkg.ResourceActionsListResponse, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) RunResourceAction(ctx context.Context, in *applicationpkg.ResourceActionRunRequest, opts ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) DeleteResource(ctx context.Context, in *applicationpkg.ApplicationResourceDeleteRequest, opts ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) PodLogs(ctx context.Context, in *applicationpkg.ApplicationPodLogsQuery, opts ...grpc.CallOption) (applicationpkg.ApplicationService_PodLogsClient, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) ListLinks(ctx context.Context, in *applicationpkg.ListAppLinksRequest, opts ...grpc.CallOption) (*applicationpkg.LinksResponse, error) { + return nil, nil +} + +func (c *fakeAppServiceClient) ListResourceLinks(ctx context.Context, in *applicationpkg.ApplicationResourceRequest, opts ...grpc.CallOption) (*applicationpkg.LinksResponse, error) { + return nil, nil +} + type fakeAcdClient struct{} func (c *fakeAcdClient) ClientOptions() argocdclient.ClientOptions { diff --git a/cmd/argocd/commands/applicationset.go b/cmd/argocd/commands/applicationset.go index ed125629b9393..4bed5aea8a992 100644 --- a/cmd/argocd/commands/applicationset.go +++ b/cmd/argocd/commands/applicationset.go @@ -11,6 +11,7 @@ import ( "github.com/spf13/cobra" "google.golang.org/grpc/codes" + "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/admin" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" cmdutil "github.com/argoproj/argo-cd/v2/cmd/util" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" @@ -53,6 +54,7 @@ func NewAppSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { command.AddCommand(NewApplicationSetCreateCommand(clientOpts)) command.AddCommand(NewApplicationSetListCommand(clientOpts)) command.AddCommand(NewApplicationSetDeleteCommand(clientOpts)) + command.AddCommand(NewApplicationSetGenerateCommand(clientOpts)) return command } @@ -114,13 +116,17 @@ func NewApplicationSetGetCommand(clientOpts *argocdclient.ClientOptions) *cobra. // NewApplicationSetCreateCommand returns a new instance of an `argocd appset create` command func NewApplicationSetCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { - var upsert bool + var output string + var upsert, dryRun bool command := &cobra.Command{ Use: "create", Short: "Create one or more ApplicationSets", Example: templates.Examples(` # Create ApplicationSets argocd appset create (...) + + # Dry-run AppSet creation to see what applications would be managed + argocd appset create --dry-run -o json | jq -r '.status.resources[].name' `), Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -157,10 +163,16 @@ func NewApplicationSetCreateCommand(clientOpts *argocdclient.ClientOptions) *cob appSetCreateRequest := applicationset.ApplicationSetCreateRequest{ Applicationset: appset, Upsert: upsert, + DryRun: dryRun, } created, err := appIf.Create(ctx, &appSetCreateRequest) errors.CheckError(err) + dryRunMsg := "" + if dryRun { + dryRunMsg = " (dry-run)" + } + var action string if existing == nil { action = "created" @@ -170,11 +182,100 @@ func NewApplicationSetCreateCommand(clientOpts *argocdclient.ClientOptions) *cob action = "updated" } - fmt.Printf("ApplicationSet '%s' %s\n", created.ObjectMeta.Name, action) + c.PrintErrf("ApplicationSet '%s' %s%s\n", created.ObjectMeta.Name, action, dryRunMsg) + + switch output { + case "yaml", "json": + err := PrintResource(created, output) + errors.CheckError(err) + case "wide", "": + printAppSetSummaryTable(created) + + if len(created.Status.Conditions) > 0 { + fmt.Println() + w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) + printAppSetConditions(w, created) + _ = w.Flush() + fmt.Println() + } + default: + errors.CheckError(fmt.Errorf("unknown output format: %s", output)) + } } }, } command.Flags().BoolVar(&upsert, "upsert", false, "Allows to override ApplicationSet with the same name even if supplied ApplicationSet spec is different from existing spec") + command.Flags().BoolVar(&dryRun, "dry-run", false, "Allows to evaluate the ApplicationSet template on the server to get a preview of the applications that would be created") + command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: json|yaml|wide") + return command +} + +// NewApplicationSetGenerateCommand returns a new instance of an `argocd appset generate` command +func NewApplicationSetGenerateCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { + var output string + command := &cobra.Command{ + Use: "generate", + Short: "Generate apps of ApplicationSet rendered templates", + Example: templates.Examples(` + # Generate apps of ApplicationSet rendered templates + argocd appset generate (...) +`), + Run: func(c *cobra.Command, args []string) { + ctx := c.Context() + + if len(args) == 0 { + c.HelpFunc()(c, args) + os.Exit(1) + } + argocdClient := headless.NewClientOrDie(clientOpts, c) + fileUrl := args[0] + appsets, err := cmdutil.ConstructApplicationSet(fileUrl) + errors.CheckError(err) + + if len(appsets) != 1 { + fmt.Printf("Input file must contain one ApplicationSet") + os.Exit(1) + } + appset := appsets[0] + if appset.Name == "" { + 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 argoio.Close(conn) + + req := applicationset.ApplicationSetGenerateRequest{ + ApplicationSet: appset, + } + resp, err := appIf.Generate(ctx, &req) + errors.CheckError(err) + + var appsList []arogappsetv1.Application + for i := range resp.Applications { + appsList = append(appsList, *resp.Applications[i]) + } + + switch output { + case "yaml", "json": + 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 + app.APIVersion = arogappsetv1.ApplicationSchemaGroupVersionKind.GroupVersion().String() + app.Kind = arogappsetv1.ApplicationSchemaGroupVersionKind.Kind + resources = append(resources, app) + } + + cobra.CheckErr(admin.PrintResources(output, os.Stdout, resources...)) + case "wide", "": + printApplicationTable(appsList, &output) + default: + errors.CheckError(fmt.Errorf("unknown output format: %s", output)) + } + }, + } + command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: json|yaml|wide") return command } @@ -189,7 +290,7 @@ func NewApplicationSetListCommand(clientOpts *argocdclient.ClientOptions) *cobra command := &cobra.Command{ Use: "list", Short: "List ApplicationSets", - Example: templates.Examples(` + Example: templates.Examples(` # List all ApplicationSets argocd appset list `), @@ -230,7 +331,7 @@ func NewApplicationSetDeleteCommand(clientOpts *argocdclient.ClientOptions) *cob command := &cobra.Command{ Use: "delete", Short: "Delete one or more ApplicationSets", - Example: templates.Examples(` + Example: templates.Examples(` # Delete an applicationset argocd appset delete APPSETNAME (APPSETNAME...) `), diff --git a/cmd/argocd/commands/cluster.go b/cmd/argocd/commands/cluster.go index 2493e09455372..729848de78634 100644 --- a/cmd/argocd/commands/cluster.go +++ b/cmd/argocd/commands/cluster.go @@ -34,6 +34,10 @@ const ( clusterFieldName = "name" // cluster field is 'namespaces' clusterFieldNamespaces = "namespaces" + // cluster field is 'labels' + clusterFieldLabel = "labels" + // cluster field is 'annotations' + clusterFieldAnnotation = "annotations" // indicates managing all namespaces allNamespaces = "*" ) @@ -220,6 +224,8 @@ func NewClusterSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command var ( clusterOptions cmdutil.ClusterOptions clusterName string + labels []string + annotations []string ) command := &cobra.Command{ Use: "set NAME", @@ -238,17 +244,25 @@ func NewClusterSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command conn, clusterIf := headless.NewClientOrDie(clientOpts, c).NewClusterClientOrDie() defer io.Close(conn) // checks the fields that needs to be updated - updatedFields := checkFieldsToUpdate(clusterOptions) + updatedFields := checkFieldsToUpdate(clusterOptions, labels, annotations) namespaces := clusterOptions.Namespaces // check if all namespaces have to be considered if len(namespaces) == 1 && strings.EqualFold(namespaces[0], allNamespaces) { namespaces[0] = "" } + // parse the labels you're receiving from the label flag + labelsMap, err := label.Parse(labels) + errors.CheckError(err) + // parse the annotations you're receiving from the annotation flag + annotationsMap, err := label.Parse(annotations) + errors.CheckError(err) if updatedFields != nil { clusterUpdateRequest := clusterpkg.ClusterUpdateRequest{ Cluster: &argoappv1.Cluster{ - Name: clusterOptions.Name, - Namespaces: namespaces, + Name: clusterOptions.Name, + Namespaces: namespaces, + Labels: labelsMap, + Annotations: annotationsMap, }, UpdatedFields: updatedFields, Id: &clusterpkg.ClusterID{ @@ -266,11 +280,13 @@ func NewClusterSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command } command.Flags().StringVar(&clusterOptions.Name, "name", "", "Overwrite the cluster name") command.Flags().StringArrayVar(&clusterOptions.Namespaces, "namespace", nil, "List of namespaces which are allowed to manage. Specify '*' to manage all namespaces") + command.Flags().StringArrayVar(&labels, "label", nil, "Set metadata labels (e.g. --label key=value)") + command.Flags().StringArrayVar(&annotations, "annotation", nil, "Set metadata annotations (e.g. --annotation key=value)") return command } // checkFieldsToUpdate returns the fields that needs to be updated -func checkFieldsToUpdate(clusterOptions cmdutil.ClusterOptions) []string { +func checkFieldsToUpdate(clusterOptions cmdutil.ClusterOptions, labels []string, annotations []string) []string { var updatedFields []string if clusterOptions.Name != "" { updatedFields = append(updatedFields, clusterFieldName) @@ -278,6 +294,12 @@ func checkFieldsToUpdate(clusterOptions cmdutil.ClusterOptions) []string { if clusterOptions.Namespaces != nil { updatedFields = append(updatedFields, clusterFieldNamespaces) } + if labels != nil { + updatedFields = append(updatedFields, clusterFieldLabel) + } + if annotations != nil { + updatedFields = append(updatedFields, clusterFieldAnnotation) + } return updatedFields } @@ -341,6 +363,7 @@ 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 fmt.Printf(" Server Version: %s\n", cluster.ServerVersion) fmt.Printf(" Namespaces: %s\n", formatNamespaces(cluster)) fmt.Printf("\nTLS configuration\n\n") @@ -433,6 +456,7 @@ func printClusterTable(clusters []argoappv1.Cluster) { if len(c.Namespaces) > 0 { server = fmt.Sprintf("%s (%d namespaces)", c.Server, len(c.Namespaces)) } + // 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() diff --git a/cmd/argocd/commands/headless/headless.go b/cmd/argocd/commands/headless/headless.go index d148e527abab4..f4d4503a9b723 100644 --- a/cmd/argocd/commands/headless/headless.go +++ b/cmd/argocd/commands/headless/headless.go @@ -8,23 +8,23 @@ import ( "sync" "time" - "github.com/spf13/cobra" - - "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/initialize" - "github.com/argoproj/argo-cd/v2/common" - "github.com/alicebob/miniredis/v2" "github.com/golang/protobuf/ptypes/empty" "github.com/redis/go-redis/v9" log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" "github.com/spf13/pflag" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" cache2 "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/clientcmd" "k8s.io/utils/ptr" + "sigs.k8s.io/controller-runtime/pkg/client" + "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" @@ -48,6 +48,7 @@ type forwardCacheClient struct { err error redisHaProxyName string redisName string + redisPassword string } func (c *forwardCacheClient) doLazy(action func(client cache.CacheClient) error) error { @@ -64,7 +65,7 @@ func (c *forwardCacheClient) doLazy(action func(client cache.CacheClient) error) return } - redisClient := redis.NewClient(&redis.Options{Addr: fmt.Sprintf("localhost:%d", redisPort)}) + redisClient := redis.NewClient(&redis.Options{Addr: fmt.Sprintf("localhost:%d", redisPort), Password: c.redisPassword}) c.client = cache.NewRedisCache(redisClient, time.Hour, c.compression) }) if c.err != nil { @@ -231,6 +232,17 @@ func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOpti return fmt.Errorf("error creating kubernetes clientset: %w", err) } + dynamicClientset, err := dynamic.NewForConfig(restConfig) + if err != nil { + return fmt.Errorf("error creating kubernetes dynamic clientset: %w", err) + } + + controllerClientset, err := client.New(restConfig, client.Options{}) + if err != nil { + return fmt.Errorf("error creating kubernetes controller clientset: %w", err) + } + controllerClientset = client.NewDryRunClient(controllerClientset) + namespace, _, err := clientConfig.Namespace() if err != nil { return fmt.Errorf("error getting namespace: %w", err) @@ -240,21 +252,28 @@ func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOpti if err != nil { return fmt.Errorf("error running miniredis: %w", err) } - appstateCache := appstatecache.NewCache(cache.NewCache(&forwardCacheClient{namespace: namespace, context: ctxStr, compression: compression, redisHaProxyName: clientOpts.RedisHaProxyName, redisName: clientOpts.RedisName}), time.Hour) + redisOptions := &redis.Options{Addr: mr.Addr()} + if err = common.SetOptionalRedisPasswordFromKubeConfig(ctx, kubeClientset, namespace, redisOptions); err != nil { + log.Warnf("Failed to fetch & set redis password for namespace %s: %v", namespace, err) + } + + appstateCache := appstatecache.NewCache(cache.NewCache(&forwardCacheClient{namespace: namespace, context: ctxStr, compression: compression, redisHaProxyName: clientOpts.RedisHaProxyName, redisName: clientOpts.RedisName, redisPassword: redisOptions.Password}), time.Hour) srv := server.NewServer(ctx, server.ArgoCDServerOpts{ - EnableGZip: false, - Namespace: namespace, - ListenPort: *port, - AppClientset: appClientset, - DisableAuth: true, - RedisClient: redis.NewClient(&redis.Options{Addr: mr.Addr()}), - Cache: servercache.NewCache(appstateCache, 0, 0, 0), - KubeClientset: kubeClientset, - Insecure: true, - ListenHost: *address, - RepoClientset: &forwardRepoClientset{namespace: namespace, context: ctxStr, repoServerName: clientOpts.RepoServerName, kubeClientset: kubeClientset}, - EnableProxyExtension: false, - }) + EnableGZip: false, + Namespace: namespace, + ListenPort: *port, + AppClientset: appClientset, + DisableAuth: true, + RedisClient: redis.NewClient(redisOptions), + Cache: servercache.NewCache(appstateCache, 0, 0, 0), + KubeClientset: kubeClientset, + DynamicClientset: dynamicClientset, + KubeControllerClientset: controllerClientset, + Insecure: true, + ListenHost: *address, + RepoClientset: &forwardRepoClientset{namespace: namespace, context: ctxStr, repoServerName: clientOpts.RepoServerName, kubeClientset: kubeClientset}, + EnableProxyExtension: false, + }, server.ApplicationSetOpts{}) srv.Init(ctx) lns, err := srv.Listen() diff --git a/cmd/argocd/commands/login.go b/cmd/argocd/commands/login.go index f8dde97e9c77a..72b89dae1771c 100644 --- a/cmd/argocd/commands/login.go +++ b/cmd/argocd/commands/login.go @@ -37,12 +37,13 @@ import ( // NewLoginCommand returns a new instance of `argocd login` command func NewLoginCommand(globalClientOpts *argocdclient.ClientOptions) *cobra.Command { var ( - ctxName string - username string - password string - sso bool - ssoPort int - skipTestTLS bool + ctxName string + username string + password string + sso bool + ssoPort int + skipTestTLS bool + ssoLaunchBrowser bool ) command := &cobra.Command{ Use: "login SERVER", @@ -135,7 +136,7 @@ argocd login cd.argoproj.io --core`, errors.CheckError(err) oauth2conf, provider, err := acdClient.OIDCConfig(ctx, acdSet) errors.CheckError(err) - tokenString, refreshToken = oauth2Login(ctx, ssoPort, acdSet.GetOIDCConfig(), oauth2conf, provider) + tokenString, refreshToken = oauth2Login(ctx, ssoPort, acdSet.GetOIDCConfig(), oauth2conf, provider, ssoLaunchBrowser) } parser := jwt.NewParser(jwt.WithoutClaimsValidation()) claims := jwt.MapClaims{} @@ -184,6 +185,7 @@ argocd login cd.argoproj.io --core`, command.Flags().IntVar(&ssoPort, "sso-port", DefaultSSOLocalPort, "Port to run local OAuth2 login application") command.Flags(). BoolVar(&skipTestTLS, "skip-test-tls", false, "Skip testing whether the server is configured with TLS (this can help when the command hangs for no apparent reason)") + command.Flags().BoolVar(&ssoLaunchBrowser, "sso-launch-browser", true, "Automatically launch the system default browser when performing SSO login") return command } @@ -205,6 +207,7 @@ func oauth2Login( oidcSettings *settingspkg.OIDCConfig, oauth2conf *oauth2.Config, provider *oidc.Provider, + ssoLaunchBrowser bool, ) (string, string) { oauth2conf.RedirectURL = fmt.Sprintf("http://localhost:%d/auth/callback", port) oidcConf, err := oidcutil.ParseConfig(provider) @@ -304,8 +307,6 @@ func oauth2Login( http.HandleFunc("/auth/callback", callbackHandler) // Redirect user to login & consent page to ask for permission for the scopes specified above. - fmt.Printf("Opening browser for authentication\n") - var url string var oidcconfig oidcconfig.OIDCConfig grantType := oidcutil.InferGrantType(oidcConf) @@ -330,8 +331,7 @@ func oauth2Login( } fmt.Printf("Performing %s flow login: %s\n", grantType, url) time.Sleep(1 * time.Second) - err = open.Start(url) - errors.CheckError(err) + ssoAuthFlow(url, ssoLaunchBrowser) go func() { log.Debugf("Listen: %s", srv.Addr) if err := srv.ListenAndServe(); err != http.ErrServerClosed { @@ -363,3 +363,13 @@ func passwordLogin(ctx context.Context, acdClient argocdclient.Client, username, errors.CheckError(err) return createdSession.Token } + +func ssoAuthFlow(url string, ssoLaunchBrowser bool) { + if ssoLaunchBrowser { + fmt.Printf("Opening system default browser for authentication\n") + err := open.Start(url) + errors.CheckError(err) + } else { + fmt.Printf("To authenticate, copy-and-paste the following URL into your preferred browser: %s\n", url) + } +} diff --git a/cmd/argocd/commands/login_test.go b/cmd/argocd/commands/login_test.go index 3a7411b4b7fa3..420b484674901 100644 --- a/cmd/argocd/commands/login_test.go +++ b/cmd/argocd/commands/login_test.go @@ -1,12 +1,39 @@ package commands import ( + "io" + "os" "testing" + utils "github.com/argoproj/argo-cd/v2/util/io" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/assert" ) +func captureStdout(callback func()) (string, error) { + oldStdout := os.Stdout + oldStderr := os.Stderr + r, w, err := os.Pipe() + if err != nil { + return "", err + } + os.Stdout = w + defer func() { + os.Stdout = oldStdout + os.Stderr = oldStderr + }() + + callback() + utils.Close(w) + + data, err := io.ReadAll(r) + if err != nil { + return "", err + } + return string(data), err +} + func Test_userDisplayName_email(t *testing.T) { claims := jwt.MapClaims{"iss": "qux", "sub": "foo", "email": "firstname.lastname@example.com", "groups": []string{"baz"}} actualName := userDisplayName(claims) @@ -27,3 +54,11 @@ func Test_userDisplayName_sub(t *testing.T) { expectedName := "foo" assert.Equal(t, expectedName, actualName) } + +func Test_ssoAuthFlow_ssoLaunchBrowser_false(t *testing.T) { + out, _ := captureStdout(func() { + ssoAuthFlow("http://test-sso-browser-flow.com", false) + }) + + assert.Contains(t, out, "To authenticate, copy-and-paste the following URL into your preferred browser: http://test-sso-browser-flow.com") +} diff --git a/cmd/argocd/commands/project.go b/cmd/argocd/commands/project.go index 8cbb637c484e3..827af5e536c33 100644 --- a/cmd/argocd/commands/project.go +++ b/cmd/argocd/commands/project.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "os" + "slices" "strings" "text/tabwriter" "time" @@ -80,6 +81,8 @@ func NewProjectCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { command.AddCommand(NewProjectRemoveOrphanedIgnoreCommand(clientOpts)) command.AddCommand(NewProjectAddSourceNamespace(clientOpts)) command.AddCommand(NewProjectRemoveSourceNamespace(clientOpts)) + command.AddCommand(NewProjectAddDestinationServiceAccountCommand(clientOpts)) + command.AddCommand(NewProjectRemoveDestinationServiceAccountCommand(clientOpts)) return command } @@ -799,7 +802,7 @@ func printProjectNames(projects []v1alpha1.AppProject) { // Print table of project info func printProjectTable(projects []v1alpha1.AppProject) { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) - fmt.Fprintf(w, "NAME\tDESCRIPTION\tDESTINATIONS\tSOURCES\tCLUSTER-RESOURCE-WHITELIST\tNAMESPACE-RESOURCE-BLACKLIST\tSIGNATURE-KEYS\tORPHANED-RESOURCES\n") + fmt.Fprintf(w, "NAME\tDESCRIPTION\tDESTINATIONS\tSOURCES\tCLUSTER-RESOURCE-WHITELIST\tNAMESPACE-RESOURCE-BLACKLIST\tSIGNATURE-KEYS\tORPHANED-RESOURCES\tDESTINATION-SERVICE-ACCOUNTS\n") for _, p := range projects { printProjectLine(w, &p) } @@ -855,7 +858,7 @@ func formatOrphanedResources(p *v1alpha1.AppProject) string { } func printProjectLine(w io.Writer, p *v1alpha1.AppProject) { - var destinations, sourceRepos, clusterWhitelist, namespaceBlacklist, signatureKeys string + var destinations, destinationServiceAccounts, sourceRepos, clusterWhitelist, namespaceBlacklist, signatureKeys string switch len(p.Spec.Destinations) { case 0: destinations = "" @@ -864,6 +867,14 @@ func printProjectLine(w io.Writer, p *v1alpha1.AppProject) { default: destinations = fmt.Sprintf("%d destinations", len(p.Spec.Destinations)) } + switch len(p.Spec.DestinationServiceAccounts) { + case 0: + destinationServiceAccounts = "" + case 1: + destinationServiceAccounts = fmt.Sprintf("%s,%s,%s", p.Spec.DestinationServiceAccounts[0].Server, p.Spec.DestinationServiceAccounts[0].Namespace, p.Spec.DestinationServiceAccounts[0].DefaultServiceAccount) + default: + destinationServiceAccounts = fmt.Sprintf("%d destinationServiceAccounts", len(p.Spec.DestinationServiceAccounts)) + } switch len(p.Spec.SourceRepos) { case 0: sourceRepos = "" @@ -892,7 +903,7 @@ func printProjectLine(w io.Writer, p *v1alpha1.AppProject) { default: signatureKeys = fmt.Sprintf("%d key(s)", len(p.Spec.SignatureKeys)) } - fmt.Fprintf(w, "%s\t%s\t%v\t%v\t%v\t%v\t%v\t%v\n", p.Name, p.Spec.Description, destinations, sourceRepos, clusterWhitelist, namespaceBlacklist, signatureKeys, formatOrphanedResources(p)) + fmt.Fprintf(w, "%s\t%s\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", p.Name, p.Spec.Description, destinations, sourceRepos, clusterWhitelist, namespaceBlacklist, signatureKeys, formatOrphanedResources(p), destinationServiceAccounts) } func printProject(p *v1alpha1.AppProject, scopedRepositories []*v1alpha1.Repository, scopedClusters []*v1alpha1.Cluster) { @@ -921,6 +932,16 @@ func printProject(p *v1alpha1.AppProject, scopedRepositories []*v1alpha1.Reposit fmt.Printf(printProjFmtStr, "", p.Spec.SourceRepos[i]) } + // Print source namespaces + ns0 := "" + if len(p.Spec.SourceNamespaces) > 0 { + ns0 = p.Spec.SourceNamespaces[0] + } + fmt.Printf(printProjFmtStr, "Source Namespaces:", ns0) + for i := 1; i < len(p.Spec.SourceNamespaces); i++ { + fmt.Printf(printProjFmtStr, "", p.Spec.SourceNamespaces[i]) + } + // Print scoped repositories scr0 := "" if len(scopedRepositories) > 0 { @@ -1072,3 +1093,122 @@ func NewProjectEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman } return command } + +// NewProjectAddDestinationServiceAccountCommand returns a new instance of an `argocd proj add-destination-service-account` command +func NewProjectAddDestinationServiceAccountCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { + var serviceAccountNamespace string + + buildApplicationDestinationServiceAccount := func(destination string, namespace string, serviceAccount string, serviceAccountNamespace string) v1alpha1.ApplicationDestinationServiceAccount { + if serviceAccountNamespace != "" { + return v1alpha1.ApplicationDestinationServiceAccount{ + Server: destination, + Namespace: namespace, + DefaultServiceAccount: fmt.Sprintf("%s:%s", serviceAccountNamespace, serviceAccount), + } + } else { + return v1alpha1.ApplicationDestinationServiceAccount{ + Server: destination, + Namespace: namespace, + DefaultServiceAccount: serviceAccount, + } + } + } + + command := &cobra.Command{ + Use: "add-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ACCOUNT", + Short: "Add project destination's default service account", + Example: templates.Examples(` + # Add project destination service account (SERVICE_ACCOUNT) for a server URL (SERVER) in the specified namespace (NAMESPACE) on the project with name PROJECT + argocd proj add-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ACCOUNT + + # Add project destination service account (SERVICE_ACCOUNT) from a different namespace + argocd proj add-destination PROJECT SERVER NAMESPACE SERVICE_ACCOUNT --service-account-namespace + `), + Run: func(c *cobra.Command, args []string) { + ctx := c.Context() + + if len(args) != 4 { + c.HelpFunc()(c, args) + os.Exit(1) + } + projName := args[0] + server := args[1] + namespace := args[2] + serviceAccount := args[3] + + if strings.Contains(serviceAccountNamespace, "*") { + log.Fatal("service-account-namespace for DestinationServiceAccount must not contain wildcards") + } + + if strings.Contains(serviceAccount, "*") { + log.Fatal("ServiceAccount for DestinationServiceAccount must not contain wildcards") + } + + destinationServiceAccount := buildApplicationDestinationServiceAccount(server, namespace, serviceAccount, serviceAccountNamespace) + conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() + defer argoio.Close(conn) + + proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) + errors.CheckError(err) + + for _, dest := range proj.Spec.DestinationServiceAccounts { + dstServerExist := destinationServiceAccount.Server != "" && dest.Server == destinationServiceAccount.Server + dstServiceAccountExist := destinationServiceAccount.DefaultServiceAccount != "" && dest.DefaultServiceAccount == destinationServiceAccount.DefaultServiceAccount + if dest.Namespace == destinationServiceAccount.Namespace && dstServerExist && dstServiceAccountExist { + log.Fatal("Specified destination service account is already defined in project") + } + } + proj.Spec.DestinationServiceAccounts = append(proj.Spec.DestinationServiceAccounts, destinationServiceAccount) + _, err = projIf.Update(ctx, &projectpkg.ProjectUpdateRequest{Project: proj}) + errors.CheckError(err) + }, + } + command.Flags().StringVar(&serviceAccountNamespace, "service-account-namespace", "", "Use service-account-namespace as namespace where the service account is present") + return command +} + +// NewProjectRemoveDestinationCommand returns a new instance of an `argocd proj remove-destination-service-account` command +func NewProjectRemoveDestinationServiceAccountCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { + command := &cobra.Command{ + Use: "remove-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ACCOUNT", + Short: "Remove default destination service account from the project", + Example: templates.Examples(` + # Remove the destination service account (SERVICE_ACCOUNT) from the specified destination (SERVER and NAMESPACE combination) on the project with name PROJECT + argocd proj remove-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ACCOUNT + `), + Run: func(c *cobra.Command, args []string) { + ctx := c.Context() + + if len(args) != 4 { + c.HelpFunc()(c, args) + os.Exit(1) + } + projName := args[0] + server := args[1] + namespace := args[2] + serviceAccount := args[3] + conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() + defer argoio.Close(conn) + + proj, err := projIf.Get(ctx, &projectpkg.ProjectQuery{Name: projName}) + errors.CheckError(err) + + originalLength := len(proj.Spec.DestinationServiceAccounts) + proj.Spec.DestinationServiceAccounts = slices.DeleteFunc(proj.Spec.DestinationServiceAccounts, + func(destServiceAccount v1alpha1.ApplicationDestinationServiceAccount) bool { + return destServiceAccount.Namespace == namespace && + destServiceAccount.Server == server && + destServiceAccount.DefaultServiceAccount == serviceAccount + }, + ) + 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") + } + }, + } + + return command +} diff --git a/cmd/argocd/commands/relogin.go b/cmd/argocd/commands/relogin.go index 95159066d2cb1..effb0239c051b 100644 --- a/cmd/argocd/commands/relogin.go +++ b/cmd/argocd/commands/relogin.go @@ -20,8 +20,9 @@ import ( // NewReloginCommand returns a new instance of `argocd relogin` command func NewReloginCommand(globalClientOpts *argocdclient.ClientOptions) *cobra.Command { var ( - password string - ssoPort int + password string + ssoPort int + ssoLaunchBrowser bool ) command := &cobra.Command{ Use: "relogin", @@ -72,7 +73,7 @@ func NewReloginCommand(globalClientOpts *argocdclient.ClientOptions) *cobra.Comm errors.CheckError(err) oauth2conf, provider, err := acdClient.OIDCConfig(ctx, acdSet) errors.CheckError(err) - tokenString, refreshToken = oauth2Login(ctx, ssoPort, acdSet.GetOIDCConfig(), oauth2conf, provider) + tokenString, refreshToken = oauth2Login(ctx, ssoPort, acdSet.GetOIDCConfig(), oauth2conf, provider, ssoLaunchBrowser) } localCfg.UpsertUser(localconfig.User{ @@ -99,5 +100,6 @@ argocd login cd.argoproj.io --core } command.Flags().StringVar(&password, "password", "", "The password of an account to authenticate") command.Flags().IntVar(&ssoPort, "sso-port", DefaultSSOLocalPort, "Port to run local OAuth2 login application") + command.Flags().BoolVar(&ssoLaunchBrowser, "sso-launch-browser", true, "Automatically launch the default browser when performing SSO login") return command } diff --git a/cmd/argocd/commands/repo.go b/cmd/argocd/commands/repo.go index 35b1aebb04bf8..f58204ea76c3a 100644 --- a/cmd/argocd/commands/repo.go +++ b/cmd/argocd/commands/repo.go @@ -178,6 +178,7 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { repoOpts.Repo.GithubAppInstallationId = repoOpts.GithubAppInstallationId repoOpts.Repo.GitHubAppEnterpriseBaseURL = repoOpts.GitHubAppEnterpriseBaseURL repoOpts.Repo.Proxy = repoOpts.Proxy + repoOpts.Repo.NoProxy = repoOpts.NoProxy repoOpts.Repo.ForceHttpBasicAuth = repoOpts.ForceHttpBasicAuth if repoOpts.Repo.Type == "helm" && repoOpts.Repo.Name == "" { diff --git a/cmd/argocd/commands/repocreds.go b/cmd/argocd/commands/repocreds.go index fa6c20c8c3f98..21ebca795cdfb 100644 --- a/cmd/argocd/commands/repocreds.go +++ b/cmd/argocd/commands/repocreds.go @@ -187,6 +187,7 @@ 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().StringVar(&repo.Proxy, "proxy-url", "", "If provided, this URL will be used to connect via proxy") return command } diff --git a/cmd/argocd/commands/root.go b/cmd/argocd/commands/root.go index 10e6bed36377e..4386b8febd6c4 100644 --- a/cmd/argocd/commands/root.go +++ b/cmd/argocd/commands/root.go @@ -70,7 +70,7 @@ func NewCommand() *cobra.Command { command.PersistentFlags().StringVar(&clientOpts.CertFile, "server-crt", config.GetFlag("server-crt", ""), "Server certificate file") command.PersistentFlags().StringVar(&clientOpts.ClientCertFile, "client-crt", config.GetFlag("client-crt", ""), "Client certificate file") command.PersistentFlags().StringVar(&clientOpts.ClientCertKeyFile, "client-crt-key", config.GetFlag("client-crt-key", ""), "Client certificate key file") - command.PersistentFlags().StringVar(&clientOpts.AuthToken, "auth-token", config.GetFlag("auth-token", ""), "Authentication token") + 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", "text"), "Set the logging format. One of: text|json") @@ -80,6 +80,7 @@ func NewCommand() *cobra.Command { command.PersistentFlags().StringVar(&clientOpts.PortForwardNamespace, "port-forward-namespace", config.GetFlag("port-forward-namespace", ""), "Namespace name which should be used for port forwarding") command.PersistentFlags().IntVar(&clientOpts.HttpRetryMax, "http-retry-max", config.GetIntFlag("http-retry-max", 0), "Maximum number of retries to establish http connection to Argo CD server") command.PersistentFlags().BoolVar(&clientOpts.Core, "core", config.GetBoolFlag("core"), "If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server") + command.PersistentFlags().StringVar(&clientOpts.Context, "argocd-context", "", "The name of the Argo-CD server context to use") command.PersistentFlags().StringVar(&clientOpts.ServerName, "server-name", env.StringFromEnv(common.EnvServerName, common.DefaultServerName), fmt.Sprintf("Name of the Argo CD API server; set this or the %s environment variable when the server's name label differs from the default, for example when installing via the Helm chart", common.EnvServerName)) command.PersistentFlags().StringVar(&clientOpts.AppControllerName, "controller-name", env.StringFromEnv(common.EnvAppControllerName, common.DefaultApplicationControllerName), fmt.Sprintf("Name of the Argo CD Application controller; set this or the %s environment variable when the controller's name label differs from the default, for example when installing via the Helm chart", common.EnvAppControllerName)) command.PersistentFlags().StringVar(&clientOpts.RedisHaProxyName, "redis-haproxy-name", env.StringFromEnv(common.EnvRedisHaProxyName, common.DefaultRedisHaProxyName), fmt.Sprintf("Name of the Redis HA Proxy; set this or the %s environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart", common.EnvRedisHaProxyName)) diff --git a/cmd/main.go b/cmd/main.go index d972863992bce..e6c94c40f7c85 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -6,6 +6,8 @@ import ( "github.com/spf13/cobra" + _ "go.uber.org/automaxprocs" + 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" diff --git a/cmd/util/app.go b/cmd/util/app.go index 1ac606a22ba5c..56b48fee82131 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -48,6 +48,9 @@ type AppOptions struct { helmVersion string helmPassCredentials bool helmSkipCrds bool + helmNamespace string + helmKubeVersion string + helmApiVersions []string project string syncPolicy string syncOptions []string @@ -72,6 +75,8 @@ type AppOptions struct { kustomizeForceCommonLabels bool kustomizeForceCommonAnnotations bool kustomizeNamespace string + kustomizeKubeVersion string + kustomizeApiVersions []string pluginEnvs []string Validate bool directoryExclude string @@ -104,6 +109,9 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) { command.Flags().StringArrayVar(&opts.helmSetStrings, "helm-set-string", []string{}, "Helm set STRING values on the command line (can be repeated to set several values: --helm-set-string key1=val1 --helm-set-string key2=val2)") command.Flags().StringArrayVar(&opts.helmSetFiles, "helm-set-file", []string{}, "Helm set values from respective files specified via the command line (can be repeated to set several values: --helm-set-file key1=path1 --helm-set-file key2=path2)") command.Flags().BoolVar(&opts.helmSkipCrds, "helm-skip-crds", false, "Skip helm crd installation step") + command.Flags().StringVar(&opts.helmNamespace, "helm-namespace", "", "Helm namespace to use when running helm template. If not set, use app.spec.destination.namespace") + command.Flags().StringVar(&opts.helmKubeVersion, "helm-kube-version", "", "Helm kube-version to use when running helm template. If not set, use the kube version from the destination cluster") + command.Flags().StringArrayVar(&opts.helmApiVersions, "helm-api-versions", []string{}, "Helm api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster") command.Flags().StringVar(&opts.project, "project", "", "Application project name") command.Flags().StringVar(&opts.syncPolicy, "sync-policy", "", "Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic))") command.Flags().StringArrayVar(&opts.syncOptions, "sync-option", []string{}, "Add or remove a sync option, e.g add `Prune=false`. Remove using `!` prefix, e.g. `!Prune=false`") @@ -130,6 +138,8 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) { 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") + command.Flags().StringVar(&opts.kustomizeKubeVersion, "kustomize-kube-version", "", "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") + command.Flags().StringArrayVar(&opts.kustomizeApiVersions, "kustomize-api-versions", nil, "api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster. Only applicable when Helm is enabled for Kustomize builds") command.Flags().StringVar(&opts.directoryExclude, "directory-exclude", "", "Set glob expression used to exclude files from application source path") command.Flags().StringVar(&opts.directoryInclude, "directory-include", "", "Set glob expression used to include files from application source path") command.Flags().Int64Var(&opts.retryLimit, "sync-retry-limit", 0, "Max number of allowed sync retries") @@ -266,6 +276,8 @@ type kustomizeOpts struct { forceCommonLabels bool forceCommonAnnotations bool namespace string + kubeVersion string + apiVersions []string } func setKustomizeOpt(src *argoappv1.ApplicationSource, opts kustomizeOpts) { @@ -284,6 +296,12 @@ func setKustomizeOpt(src *argoappv1.ApplicationSource, opts kustomizeOpts) { if opts.namespace != "" { src.Kustomize.Namespace = opts.namespace } + if opts.kubeVersion != "" { + src.Kustomize.KubeVersion = opts.kubeVersion + } + if len(opts.apiVersions) > 0 { + src.Kustomize.APIVersions = opts.apiVersions + } if opts.commonLabels != nil { src.Kustomize.CommonLabels = opts.commonLabels } @@ -340,6 +358,9 @@ type helmOpts struct { helmSetFiles []string passCredentials bool skipCrds bool + namespace string + kubeVersion string + apiVersions []string } func setHelmOpt(src *argoappv1.ApplicationSource, opts helmOpts) { @@ -370,6 +391,15 @@ func setHelmOpt(src *argoappv1.ApplicationSource, opts helmOpts) { if opts.skipCrds { src.Helm.SkipCrds = opts.skipCrds } + if opts.namespace != "" { + src.Helm.Namespace = opts.namespace + } + if opts.kubeVersion != "" { + src.Helm.KubeVersion = opts.kubeVersion + } + if len(opts.apiVersions) > 0 { + src.Helm.APIVersions = opts.apiVersions + } for _, text := range opts.helmSets { p, err := argoappv1.NewHelmParameter(text, false) if err != nil { @@ -628,6 +658,12 @@ func ConstructSource(source *argoappv1.ApplicationSource, appOpts AppOptions, fl setHelmOpt(source, helmOpts{helmSetFiles: appOpts.helmSetFiles}) case "helm-skip-crds": setHelmOpt(source, helmOpts{skipCrds: appOpts.helmSkipCrds}) + case "helm-namespace": + setHelmOpt(source, helmOpts{namespace: appOpts.helmNamespace}) + case "helm-kube-version": + setHelmOpt(source, helmOpts{kubeVersion: appOpts.helmKubeVersion}) + case "helm-api-versions": + setHelmOpt(source, helmOpts{apiVersions: appOpts.helmApiVersions}) case "directory-recurse": if source.Directory != nil { source.Directory.Recurse = appOpts.directoryRecurse @@ -660,6 +696,10 @@ func ConstructSource(source *argoappv1.ApplicationSource, appOpts AppOptions, fl setKustomizeOpt(source, kustomizeOpts{version: appOpts.kustomizeVersion}) case "kustomize-namespace": setKustomizeOpt(source, kustomizeOpts{namespace: appOpts.kustomizeNamespace}) + case "kustomize-kube-version": + setKustomizeOpt(source, kustomizeOpts{kubeVersion: appOpts.kustomizeKubeVersion}) + case "kustomize-api-versions": + setKustomizeOpt(source, kustomizeOpts{apiVersions: appOpts.kustomizeApiVersions}) case "kustomize-common-label": parsedLabels, err := label.Parse(appOpts.kustomizeCommonLabels) errors.CheckError(err) diff --git a/cmd/util/app_test.go b/cmd/util/app_test.go index dcaae6ea8031e..595b9be46563e 100644 --- a/cmd/util/app_test.go +++ b/cmd/util/app_test.go @@ -65,6 +65,21 @@ func Test_setHelmOpt(t *testing.T) { setHelmOpt(&src, helmOpts{skipCrds: true}) assert.True(t, src.Helm.SkipCrds) }) + t.Run("HelmNamespace", func(t *testing.T) { + src := v1alpha1.ApplicationSource{} + setHelmOpt(&src, helmOpts{namespace: "custom-namespace"}) + assert.Equal(t, "custom-namespace", src.Helm.Namespace) + }) + t.Run("HelmKubeVersion", func(t *testing.T) { + src := v1alpha1.ApplicationSource{} + setHelmOpt(&src, helmOpts{kubeVersion: "v1.16.0"}) + assert.Equal(t, "v1.16.0", src.Helm.KubeVersion) + }) + t.Run("HelmApiVersions", func(t *testing.T) { + src := v1alpha1.ApplicationSource{} + setHelmOpt(&src, helmOpts{apiVersions: []string{"v1", "v2"}}) + assert.Equal(t, []string{"v1", "v2"}, src.Helm.APIVersions) + }) } func Test_setKustomizeOpt(t *testing.T) { @@ -114,6 +129,16 @@ func Test_setKustomizeOpt(t *testing.T) { setKustomizeOpt(&src, kustomizeOpts{namespace: "custom-namespace"}) assert.Equal(t, &v1alpha1.ApplicationSourceKustomize{Namespace: "custom-namespace"}, src.Kustomize) }) + t.Run("KubeVersion", func(t *testing.T) { + src := v1alpha1.ApplicationSource{} + setKustomizeOpt(&src, kustomizeOpts{kubeVersion: "999.999.999"}) + assert.Equal(t, &v1alpha1.ApplicationSourceKustomize{KubeVersion: "999.999.999"}, src.Kustomize) + }) + t.Run("ApiVersions", func(t *testing.T) { + src := v1alpha1.ApplicationSource{} + setKustomizeOpt(&src, kustomizeOpts{apiVersions: []string{"v1", "v2"}}) + assert.Equal(t, &v1alpha1.ApplicationSourceKustomize{APIVersions: []string{"v1", "v2"}}, src.Kustomize) + }) t.Run("Common labels", func(t *testing.T) { src := v1alpha1.ApplicationSource{} setKustomizeOpt(&src, kustomizeOpts{commonLabels: map[string]string{"foo1": "bar1", "foo2": "bar2"}}) @@ -233,6 +258,32 @@ func Test_setAppSpecOptions(t *testing.T) { require.NoError(t, f.SetFlag("kustomize-replica", "my-statefulset=4")) assert.Equal(t, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(2)}, {Name: "my-statefulset", Count: intstr.FromInt(4)}}, f.spec.Source.Kustomize.Replicas) }) + t.Run("Kustomize Namespace", func(t *testing.T) { + require.NoError(t, f.SetFlag("kustomize-namespace", "override-namespace")) + assert.Equal(t, "override-namespace", f.spec.Source.Kustomize.Namespace) + }) + t.Run("Kustomize Kube Version", func(t *testing.T) { + require.NoError(t, f.SetFlag("kustomize-kube-version", "999.999.999")) + assert.Equal(t, "999.999.999", f.spec.Source.Kustomize.KubeVersion) + }) + t.Run("Kustomize API Versions", func(t *testing.T) { + require.NoError(t, f.SetFlag("kustomize-api-versions", "v1")) + require.NoError(t, f.SetFlag("kustomize-api-versions", "v2")) + assert.Equal(t, []string{"v1", "v2"}, f.spec.Source.Kustomize.APIVersions) + }) + t.Run("Helm Namespace", func(t *testing.T) { + require.NoError(t, f.SetFlag("helm-namespace", "override-namespace")) + assert.Equal(t, "override-namespace", f.spec.Source.Helm.Namespace) + }) + t.Run("Helm Kube Version", func(t *testing.T) { + require.NoError(t, f.SetFlag("kustomize-kube-version", "999.999.999")) + assert.Equal(t, "999.999.999", f.spec.Source.Kustomize.KubeVersion) + }) + t.Run("Helm API Versions", func(t *testing.T) { + require.NoError(t, f.SetFlag("helm-api-versions", "v1")) + require.NoError(t, f.SetFlag("helm-api-versions", "v2")) + assert.Equal(t, []string{"v1", "v2"}, f.spec.Source.Helm.APIVersions) + }) } func newMultiSourceAppOptionsFixture() *appOptionsFixture { diff --git a/cmd/util/cluster_test.go b/cmd/util/cluster_test.go index f30a4aed51abd..24b46765ca686 100644 --- a/cmd/util/cluster_test.go +++ b/cmd/util/cluster_test.go @@ -1,7 +1,6 @@ package util import ( - "strings" "testing" "github.com/stretchr/testify/assert" @@ -53,8 +52,8 @@ func Test_newCluster(t *testing.T) { &v1alpha1.AWSAuthConfig{}, &v1alpha1.ExecProviderConfig{}, labels, nil) - assert.True(t, strings.Contains(string(clusterWithFiles.Config.CertData), "test-cert-data")) - assert.True(t, strings.Contains(string(clusterWithFiles.Config.KeyData), "test-key-data")) + assert.Contains(t, string(clusterWithFiles.Config.CertData), "test-cert-data") + assert.Contains(t, string(clusterWithFiles.Config.KeyData), "test-key-data") assert.Equal(t, "", clusterWithFiles.Config.BearerToken) assert.Equal(t, labels, clusterWithFiles.Labels) assert.Nil(t, clusterWithFiles.Annotations) diff --git a/cmd/util/project.go b/cmd/util/project.go index f4bbae0977430..b0a82883dc0bb 100644 --- a/cmd/util/project.go +++ b/cmd/util/project.go @@ -20,11 +20,12 @@ import ( ) type ProjectOpts struct { - Description string - destinations []string - Sources []string - SignatureKeys []string - SourceNamespaces []string + Description string + destinations []string + destinationServiceAccounts []string + Sources []string + SignatureKeys []string + SourceNamespaces []string orphanedResourcesEnabled bool orphanedResourcesWarn bool @@ -93,6 +94,23 @@ func (opts *ProjectOpts) GetDestinations() []v1alpha1.ApplicationDestination { return destinations } +func (opts *ProjectOpts) GetDestinationServiceAccounts() []v1alpha1.ApplicationDestinationServiceAccount { + destinationServiceAccounts := make([]v1alpha1.ApplicationDestinationServiceAccount, 0) + for _, destStr := range opts.destinationServiceAccounts { + parts := strings.Split(destStr, ",") + if len(parts) != 2 { + log.Fatalf("Expected destination of the form: server,namespace. Received: %s", destStr) + } else { + destinationServiceAccounts = append(destinationServiceAccounts, v1alpha1.ApplicationDestinationServiceAccount{ + Server: parts[0], + Namespace: parts[1], + DefaultServiceAccount: parts[2], + }) + } + } + return destinationServiceAccounts +} + // GetSignatureKeys TODO: Get configured keys and emit warning when a key is specified that is not configured func (opts *ProjectOpts) GetSignatureKeys() []v1alpha1.SignatureKey { signatureKeys := make([]v1alpha1.SignatureKey, 0) @@ -166,6 +184,8 @@ func SetProjSpecOptions(flags *pflag.FlagSet, spec *v1alpha1.AppProjectSpec, pro spec.NamespaceResourceBlacklist = projOpts.GetDeniedNamespacedResources() case "source-namespaces": spec.SourceNamespaces = projOpts.GetSourceNamespaces() + case "dest-service-accounts": + spec.DestinationServiceAccounts = projOpts.GetDestinationServiceAccounts() } }) if flags.Changed("orphaned-resources") || flags.Changed("orphaned-resources-warn") { diff --git a/cmd/util/repo.go b/cmd/util/repo.go index b60c30a071311..6b822c6309f70 100644 --- a/cmd/util/repo.go +++ b/cmd/util/repo.go @@ -22,6 +22,7 @@ type RepoOptions struct { GithubAppPrivateKeyPath string GitHubAppEnterpriseBaseURL string Proxy string + NoProxy string GCPServiceAccountKeyPath string ForceHttpBasicAuth bool } @@ -44,6 +45,7 @@ func AddRepoFlags(command *cobra.Command, opts *RepoOptions) { command.Flags().StringVar(&opts.GithubAppPrivateKeyPath, "github-app-private-key-path", "", "private key of the GitHub Application") command.Flags().StringVar(&opts.GitHubAppEnterpriseBaseURL, "github-app-enterprise-base-url", "", "base url to use when using GitHub Enterprise (e.g. https://ghe.example.com/api/v3") command.Flags().StringVar(&opts.Proxy, "proxy", "", "use proxy to access repository") + command.Flags().StringVar(&opts.Proxy, "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") } diff --git a/cmpserver/apiclient/plugin.pb.go b/cmpserver/apiclient/plugin.pb.go index 29ebca3ae3afc..b6fb8fca109b9 100644 --- a/cmpserver/apiclient/plugin.pb.go +++ b/cmpserver/apiclient/plugin.pb.go @@ -11,6 +11,7 @@ import ( grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" io "io" math "math" math_bits "math/bits" @@ -467,6 +468,54 @@ func (m *File) GetChunk() []byte { return nil } +// CheckPluginConfigurationResponse contains a list of plugin configuration flags. +type CheckPluginConfigurationResponse struct { + IsDiscoveryConfigured bool `protobuf:"varint,1,opt,name=isDiscoveryConfigured,proto3" json:"isDiscoveryConfigured,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CheckPluginConfigurationResponse) Reset() { *m = CheckPluginConfigurationResponse{} } +func (m *CheckPluginConfigurationResponse) String() string { return proto.CompactTextString(m) } +func (*CheckPluginConfigurationResponse) ProtoMessage() {} +func (*CheckPluginConfigurationResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_b21875a7079a06ed, []int{7} +} +func (m *CheckPluginConfigurationResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CheckPluginConfigurationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CheckPluginConfigurationResponse.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 *CheckPluginConfigurationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CheckPluginConfigurationResponse.Merge(m, src) +} +func (m *CheckPluginConfigurationResponse) XXX_Size() int { + return m.Size() +} +func (m *CheckPluginConfigurationResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CheckPluginConfigurationResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CheckPluginConfigurationResponse proto.InternalMessageInfo + +func (m *CheckPluginConfigurationResponse) GetIsDiscoveryConfigured() bool { + if m != nil { + return m.IsDiscoveryConfigured + } + return false +} + func init() { proto.RegisterType((*AppStreamRequest)(nil), "plugin.AppStreamRequest") proto.RegisterType((*ManifestRequestMetadata)(nil), "plugin.ManifestRequestMetadata") @@ -475,48 +524,54 @@ func init() { proto.RegisterType((*RepositoryResponse)(nil), "plugin.RepositoryResponse") proto.RegisterType((*ParametersAnnouncementResponse)(nil), "plugin.ParametersAnnouncementResponse") proto.RegisterType((*File)(nil), "plugin.File") + proto.RegisterType((*CheckPluginConfigurationResponse)(nil), "plugin.CheckPluginConfigurationResponse") } func init() { proto.RegisterFile("cmpserver/plugin/plugin.proto", fileDescriptor_b21875a7079a06ed) } var fileDescriptor_b21875a7079a06ed = []byte{ - // 576 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x94, 0xdd, 0x6e, 0x12, 0x4f, - 0x14, 0xc0, 0xbb, 0x85, 0xb6, 0x70, 0x68, 0xf2, 0x27, 0x93, 0x7f, 0x74, 0x25, 0x2d, 0xe2, 0x5e, - 0x18, 0x6e, 0x84, 0x04, 0xbd, 0x35, 0xb1, 0x55, 0x6c, 0xa3, 0xc1, 0x90, 0xa9, 0x37, 0x7a, 0x37, - 0x1d, 0x0e, 0x30, 0x76, 0x77, 0x66, 0x9c, 0x99, 0xdd, 0x04, 0xbd, 0xf1, 0x3d, 0x7c, 0x00, 0x5f, - 0xc5, 0x4b, 0x1f, 0xc1, 0xf4, 0x49, 0x0c, 0xb3, 0xbb, 0x40, 0x6c, 0x8b, 0x57, 0x7b, 0x3e, 0x7f, - 0x7b, 0xbe, 0x32, 0x70, 0xcc, 0x13, 0x6d, 0xd1, 0x64, 0x68, 0xfa, 0x3a, 0x4e, 0x67, 0x42, 0x16, - 0x9f, 0x9e, 0x36, 0xca, 0x29, 0xb2, 0x9f, 0x6b, 0xad, 0xe1, 0x4c, 0xb8, 0x79, 0x7a, 0xd9, 0xe3, - 0x2a, 0xe9, 0x33, 0x33, 0x53, 0xda, 0xa8, 0x4f, 0x5e, 0x78, 0xc2, 0x27, 0xfd, 0x6c, 0xd0, 0x37, - 0xa8, 0x55, 0x81, 0xf1, 0xa2, 0x70, 0xca, 0x2c, 0x36, 0xc4, 0x1c, 0x17, 0x7d, 0x0b, 0xa0, 0x79, - 0xa2, 0xf5, 0x85, 0x33, 0xc8, 0x12, 0x8a, 0x9f, 0x53, 0xb4, 0x8e, 0x3c, 0x87, 0x5a, 0x82, 0x8e, - 0x4d, 0x98, 0x63, 0x61, 0xd0, 0x09, 0xba, 0x8d, 0xc1, 0xc3, 0x5e, 0x51, 0xc4, 0x88, 0x49, 0x31, - 0x45, 0xeb, 0x8a, 0xd0, 0x51, 0x11, 0x76, 0xbe, 0x43, 0x57, 0x29, 0x24, 0x82, 0xea, 0x54, 0xc4, - 0x18, 0xee, 0xfa, 0xd4, 0xc3, 0x32, 0xf5, 0xb5, 0x88, 0xf1, 0x7c, 0x87, 0x7a, 0xdf, 0x69, 0x1d, - 0x0e, 0x4c, 0x8e, 0x88, 0x7e, 0x04, 0x70, 0xff, 0x0e, 0x2c, 0x09, 0xe1, 0x80, 0x69, 0xfd, 0x8e, - 0x25, 0xe8, 0x0b, 0xa9, 0xd3, 0x52, 0x25, 0x6d, 0x00, 0xa6, 0x35, 0xc5, 0x78, 0xcc, 0xdc, 0xdc, - 0xff, 0xaa, 0x4e, 0x37, 0x2c, 0xa4, 0x05, 0x35, 0x3e, 0x47, 0x7e, 0x65, 0xd3, 0x24, 0xac, 0x78, - 0xef, 0x4a, 0x27, 0x04, 0xaa, 0x56, 0x7c, 0xc1, 0xb0, 0xda, 0x09, 0xba, 0x15, 0xea, 0x65, 0x12, - 0x41, 0x05, 0x65, 0x16, 0xee, 0x75, 0x2a, 0xdd, 0xc6, 0xa0, 0x59, 0xd6, 0x3c, 0x94, 0xd9, 0x50, - 0x3a, 0xb3, 0xa0, 0x4b, 0x67, 0xf4, 0x0c, 0x6a, 0xa5, 0x61, 0xc9, 0x90, 0xeb, 0xb2, 0xbc, 0x4c, - 0xfe, 0x87, 0xbd, 0x8c, 0xc5, 0x29, 0x16, 0xe5, 0xe4, 0x4a, 0x34, 0x86, 0xe6, 0xba, 0x3d, 0xab, - 0x95, 0xb4, 0x48, 0x8e, 0xa0, 0x9e, 0x14, 0x36, 0x1b, 0x06, 0x9d, 0x4a, 0xb7, 0x4e, 0xd7, 0x86, - 0x65, 0x6f, 0x56, 0xa5, 0x86, 0xe3, 0xfb, 0x85, 0x2e, 0x61, 0x1b, 0x96, 0x68, 0x0a, 0x84, 0xae, - 0x16, 0xb9, 0x62, 0x76, 0xa0, 0x21, 0xec, 0x45, 0xaa, 0xb5, 0x32, 0x0e, 0x27, 0xbe, 0xb0, 0x1a, - 0xdd, 0x34, 0x91, 0x1e, 0x10, 0x61, 0x5f, 0x09, 0xcb, 0x55, 0x86, 0x66, 0x31, 0x94, 0xec, 0x32, - 0xc6, 0x89, 0xe7, 0xd7, 0xe8, 0x2d, 0x9e, 0xe8, 0x2b, 0xb4, 0xc7, 0xcc, 0xb0, 0x04, 0x1d, 0x1a, - 0x7b, 0x22, 0xa5, 0x4a, 0x25, 0xc7, 0x04, 0xe5, 0xba, 0x8f, 0x0f, 0x70, 0x4f, 0x97, 0x11, 0x9b, - 0x01, 0x79, 0x53, 0x8d, 0xc1, 0xa3, 0xde, 0xc6, 0xc5, 0x8d, 0x6f, 0x8b, 0xa4, 0x77, 0x00, 0xa2, - 0x23, 0xa8, 0x2e, 0x2f, 0x66, 0x39, 0x54, 0x3e, 0x4f, 0xe5, 0x95, 0x6f, 0xe8, 0x90, 0xe6, 0xca, - 0xe0, 0xfb, 0x2e, 0x1c, 0xbf, 0x54, 0x72, 0x2a, 0x66, 0x23, 0x26, 0xd9, 0xcc, 0xe7, 0x8c, 0xfd, - 0xce, 0x2e, 0xd0, 0x64, 0x82, 0x23, 0x79, 0x03, 0xcd, 0x33, 0x94, 0x68, 0x98, 0xc3, 0x72, 0xfc, - 0x24, 0x2c, 0xf7, 0xfa, 0xf7, 0xc9, 0xb7, 0xc2, 0x9b, 0x07, 0x9e, 0xb7, 0x18, 0xed, 0x74, 0x03, - 0xf2, 0x16, 0xfe, 0x1b, 0x31, 0xc7, 0xe7, 0xeb, 0xa9, 0x6f, 0x41, 0xb5, 0x4a, 0xcf, 0xcd, 0x1d, - 0x79, 0x18, 0x83, 0x07, 0x67, 0xe8, 0x6e, 0x1f, 0xec, 0x16, 0xec, 0xe3, 0xd2, 0xb3, 0x7d, 0x25, - 0xcb, 0x5f, 0x9c, 0xbe, 0xf8, 0x79, 0xdd, 0x0e, 0x7e, 0x5d, 0xb7, 0x83, 0xdf, 0xd7, 0xed, 0xe0, - 0xe3, 0xe0, 0x1f, 0x4f, 0xc5, 0xfa, 0xc1, 0x61, 0x5a, 0xf0, 0x58, 0xa0, 0x74, 0x97, 0xfb, 0xfe, - 0x79, 0x78, 0xfa, 0x27, 0x00, 0x00, 0xff, 0xff, 0x23, 0x88, 0x8e, 0xd3, 0x8e, 0x04, 0x00, 0x00, + // 650 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x54, 0xc1, 0x6e, 0xd3, 0x4c, + 0x10, 0x8e, 0x9b, 0xb4, 0x4d, 0x26, 0x95, 0xfe, 0x68, 0xf5, 0x53, 0x4c, 0x68, 0x43, 0xf0, 0x01, + 0xe5, 0x82, 0x23, 0x85, 0x5e, 0x91, 0x68, 0x4b, 0x68, 0x05, 0x0a, 0x8a, 0xb6, 0x1c, 0x80, 0x03, + 0xd2, 0xc6, 0x99, 0x24, 0x4b, 0xed, 0xdd, 0x65, 0xbd, 0x8e, 0x14, 0xb8, 0xf0, 0x36, 0xbc, 0x0a, + 0x47, 0x1e, 0x01, 0xf5, 0x35, 0xb8, 0x20, 0xaf, 0xed, 0x24, 0xa2, 0x69, 0x7b, 0xf2, 0xcc, 0x7c, + 0xb3, 0xdf, 0x7e, 0xb3, 0x33, 0x63, 0x38, 0x0c, 0x22, 0x15, 0xa3, 0x9e, 0xa3, 0xee, 0xaa, 0x30, + 0x99, 0x72, 0x91, 0x7f, 0x7c, 0xa5, 0xa5, 0x91, 0x64, 0x27, 0xf3, 0x9a, 0xfd, 0x29, 0x37, 0xb3, + 0x64, 0xe4, 0x07, 0x32, 0xea, 0x32, 0x3d, 0x95, 0x4a, 0xcb, 0xcf, 0xd6, 0x78, 0x1a, 0x8c, 0xbb, + 0xf3, 0x5e, 0x57, 0xa3, 0x92, 0x39, 0x8d, 0x35, 0xb9, 0x91, 0x7a, 0xb1, 0x66, 0x66, 0x74, 0xcd, + 0x87, 0x53, 0x29, 0xa7, 0x21, 0x76, 0xad, 0x37, 0x4a, 0x26, 0x5d, 0x8c, 0x94, 0xc9, 0x41, 0xef, + 0xbb, 0x03, 0x8d, 0x63, 0xa5, 0x2e, 0x8c, 0x46, 0x16, 0x51, 0xfc, 0x92, 0x60, 0x6c, 0xc8, 0x73, + 0xa8, 0x46, 0x68, 0xd8, 0x98, 0x19, 0xe6, 0x3a, 0x6d, 0xa7, 0x53, 0xef, 0x3d, 0xf2, 0x73, 0x85, + 0x03, 0x26, 0xf8, 0x04, 0x63, 0x93, 0xa7, 0x0e, 0xf2, 0xb4, 0xf3, 0x12, 0x5d, 0x1e, 0x21, 0x1e, + 0x54, 0x26, 0x3c, 0x44, 0x77, 0xcb, 0x1e, 0xdd, 0x2b, 0x8e, 0xbe, 0xe2, 0x21, 0x9e, 0x97, 0xa8, + 0xc5, 0x4e, 0x6a, 0xb0, 0xab, 0x33, 0x0a, 0xef, 0x87, 0x03, 0xf7, 0x6f, 0xa0, 0x25, 0x2e, 0xec, + 0x32, 0xa5, 0xde, 0xb2, 0x08, 0xad, 0x90, 0x1a, 0x2d, 0x5c, 0xd2, 0x02, 0x60, 0x4a, 0x51, 0x0c, + 0x87, 0xcc, 0xcc, 0xec, 0x55, 0x35, 0xba, 0x16, 0x21, 0x4d, 0xa8, 0x06, 0x33, 0x0c, 0x2e, 0xe3, + 0x24, 0x72, 0xcb, 0x16, 0x5d, 0xfa, 0x84, 0x40, 0x25, 0xe6, 0x5f, 0xd1, 0xad, 0xb4, 0x9d, 0x4e, + 0x99, 0x5a, 0x9b, 0x78, 0x50, 0x46, 0x31, 0x77, 0xb7, 0xdb, 0xe5, 0x4e, 0xbd, 0xd7, 0x28, 0x34, + 0xf7, 0xc5, 0xbc, 0x2f, 0x8c, 0x5e, 0xd0, 0x14, 0xf4, 0x8e, 0xa0, 0x5a, 0x04, 0x52, 0x0e, 0xb1, + 0x92, 0x65, 0x6d, 0xf2, 0x3f, 0x6c, 0xcf, 0x59, 0x98, 0x60, 0x2e, 0x27, 0x73, 0xbc, 0x21, 0x34, + 0x56, 0xe5, 0xc5, 0x4a, 0x8a, 0x18, 0xc9, 0x01, 0xd4, 0xa2, 0x3c, 0x16, 0xbb, 0x4e, 0xbb, 0xdc, + 0xa9, 0xd1, 0x55, 0x20, 0xad, 0x2d, 0x96, 0x89, 0x0e, 0xf0, 0xdd, 0x42, 0x15, 0x64, 0x6b, 0x11, + 0x6f, 0x02, 0x84, 0x2e, 0xbb, 0xbc, 0xe4, 0x6c, 0x43, 0x9d, 0xc7, 0x17, 0x89, 0x52, 0x52, 0x1b, + 0x1c, 0x5b, 0x61, 0x55, 0xba, 0x1e, 0x22, 0x3e, 0x10, 0x1e, 0xbf, 0xe4, 0x71, 0x20, 0xe7, 0xa8, + 0x17, 0x7d, 0xc1, 0x46, 0x21, 0x8e, 0x2d, 0x7f, 0x95, 0x6e, 0x40, 0xbc, 0x6f, 0xd0, 0x1a, 0x32, + 0xcd, 0x22, 0x34, 0xa8, 0xe3, 0x63, 0x21, 0x64, 0x22, 0x02, 0x8c, 0x50, 0xac, 0xea, 0xf8, 0x00, + 0xfb, 0xaa, 0xc8, 0x58, 0x4f, 0xc8, 0x8a, 0xaa, 0xf7, 0x1e, 0xfb, 0x6b, 0xe3, 0x38, 0xdc, 0x94, + 0x49, 0x6f, 0x20, 0xf0, 0x0e, 0xa0, 0x92, 0x4e, 0x4c, 0xfa, 0xa8, 0xc1, 0x2c, 0x11, 0x97, 0xb6, + 0xa0, 0x3d, 0x9a, 0x39, 0xde, 0x7b, 0x68, 0x9f, 0xa6, 0xed, 0x1c, 0xda, 0x3e, 0x9d, 0x4a, 0x31, + 0xe1, 0xd3, 0x44, 0x33, 0xc3, 0xa5, 0x58, 0x8a, 0x3b, 0x82, 0x7b, 0x6b, 0x45, 0x15, 0x39, 0xcb, + 0xa7, 0xd9, 0x0c, 0xf6, 0xfe, 0x6c, 0xc1, 0x61, 0xe6, 0x0e, 0x98, 0x60, 0x53, 0xab, 0x26, 0xbb, + 0xe5, 0x02, 0xf5, 0x9c, 0x07, 0x48, 0x5e, 0x43, 0xe3, 0x0c, 0x05, 0x6a, 0x66, 0xb0, 0x68, 0x2c, + 0x71, 0x8b, 0x89, 0xf9, 0x77, 0x99, 0x9a, 0xee, 0xf5, 0xd5, 0xc9, 0xf4, 0x79, 0xa5, 0x8e, 0x43, + 0x3e, 0x81, 0x7b, 0x53, 0x1d, 0x64, 0xdf, 0xcf, 0x36, 0xd7, 0x2f, 0x36, 0xd7, 0xef, 0xa7, 0x9b, + 0xdb, 0xec, 0x14, 0x8c, 0x77, 0xbd, 0x80, 0x57, 0x22, 0x6f, 0xe0, 0xbf, 0x01, 0x33, 0xc1, 0x6c, + 0x35, 0x2f, 0xb7, 0x48, 0x6d, 0x16, 0xc8, 0xf5, 0xe9, 0xb2, 0x62, 0x19, 0x3c, 0x38, 0x43, 0xb3, + 0x79, 0x24, 0x6e, 0xa1, 0x7d, 0x52, 0x20, 0xb7, 0x0f, 0x53, 0x7a, 0xc5, 0xc9, 0x8b, 0x9f, 0x57, + 0x2d, 0xe7, 0xd7, 0x55, 0xcb, 0xf9, 0x7d, 0xd5, 0x72, 0x3e, 0xf6, 0xee, 0xf8, 0x03, 0xae, 0xfe, + 0xa3, 0x4c, 0xf1, 0x20, 0xe4, 0x28, 0xcc, 0x68, 0xc7, 0xbe, 0xd6, 0xb3, 0xbf, 0x01, 0x00, 0x00, + 0xff, 0xff, 0xb5, 0x6b, 0xca, 0xa6, 0x65, 0x05, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -534,6 +589,9 @@ type ConfigManagementPluginServiceClient interface { // GenerateManifests receive a stream containing a tgz archive with all required files necessary // to generate manifests GenerateManifest(ctx context.Context, opts ...grpc.CallOption) (ConfigManagementPluginService_GenerateManifestClient, error) + // CheckPluginConfiguration is a pre-flight request to check the plugin configuration + // without sending the whole repo. + CheckPluginConfiguration(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CheckPluginConfigurationResponse, error) // MatchRepository returns whether or not the given application is supported by the plugin MatchRepository(ctx context.Context, opts ...grpc.CallOption) (ConfigManagementPluginService_MatchRepositoryClient, error) // GetParametersAnnouncement gets a list of parameter announcements for the given app @@ -582,6 +640,15 @@ func (x *configManagementPluginServiceGenerateManifestClient) CloseAndRecv() (*M return m, nil } +func (c *configManagementPluginServiceClient) CheckPluginConfiguration(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CheckPluginConfigurationResponse, error) { + out := new(CheckPluginConfigurationResponse) + err := c.cc.Invoke(ctx, "/plugin.ConfigManagementPluginService/CheckPluginConfiguration", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *configManagementPluginServiceClient) MatchRepository(ctx context.Context, opts ...grpc.CallOption) (ConfigManagementPluginService_MatchRepositoryClient, error) { stream, err := c.cc.NewStream(ctx, &_ConfigManagementPluginService_serviceDesc.Streams[1], "/plugin.ConfigManagementPluginService/MatchRepository", opts...) if err != nil { @@ -655,6 +722,9 @@ type ConfigManagementPluginServiceServer interface { // GenerateManifests receive a stream containing a tgz archive with all required files necessary // to generate manifests GenerateManifest(ConfigManagementPluginService_GenerateManifestServer) error + // CheckPluginConfiguration is a pre-flight request to check the plugin configuration + // without sending the whole repo. + CheckPluginConfiguration(context.Context, *emptypb.Empty) (*CheckPluginConfigurationResponse, error) // MatchRepository returns whether or not the given application is supported by the plugin MatchRepository(ConfigManagementPluginService_MatchRepositoryServer) error // GetParametersAnnouncement gets a list of parameter announcements for the given app @@ -668,6 +738,9 @@ type UnimplementedConfigManagementPluginServiceServer struct { func (*UnimplementedConfigManagementPluginServiceServer) GenerateManifest(srv ConfigManagementPluginService_GenerateManifestServer) error { return status.Errorf(codes.Unimplemented, "method GenerateManifest not implemented") } +func (*UnimplementedConfigManagementPluginServiceServer) CheckPluginConfiguration(ctx context.Context, req *emptypb.Empty) (*CheckPluginConfigurationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CheckPluginConfiguration not implemented") +} func (*UnimplementedConfigManagementPluginServiceServer) MatchRepository(srv ConfigManagementPluginService_MatchRepositoryServer) error { return status.Errorf(codes.Unimplemented, "method MatchRepository not implemented") } @@ -705,6 +778,24 @@ func (x *configManagementPluginServiceGenerateManifestServer) Recv() (*AppStream return m, nil } +func _ConfigManagementPluginService_CheckPluginConfiguration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ConfigManagementPluginServiceServer).CheckPluginConfiguration(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/plugin.ConfigManagementPluginService/CheckPluginConfiguration", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ConfigManagementPluginServiceServer).CheckPluginConfiguration(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + func _ConfigManagementPluginService_MatchRepository_Handler(srv interface{}, stream grpc.ServerStream) error { return srv.(ConfigManagementPluginServiceServer).MatchRepository(&configManagementPluginServiceMatchRepositoryServer{stream}) } @@ -760,7 +851,12 @@ func (x *configManagementPluginServiceGetParametersAnnouncementServer) Recv() (* var _ConfigManagementPluginService_serviceDesc = grpc.ServiceDesc{ ServiceName: "plugin.ConfigManagementPluginService", HandlerType: (*ConfigManagementPluginServiceServer)(nil), - Methods: []grpc.MethodDesc{}, + Methods: []grpc.MethodDesc{ + { + MethodName: "CheckPluginConfiguration", + Handler: _ConfigManagementPluginService_CheckPluginConfiguration_Handler, + }, + }, Streams: []grpc.StreamDesc{ { StreamName: "GenerateManifest", @@ -1132,6 +1228,43 @@ func (m *File) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *CheckPluginConfigurationResponse) 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 *CheckPluginConfigurationResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CheckPluginConfigurationResponse) 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.IsDiscoveryConfigured { + i-- + if m.IsDiscoveryConfigured { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintPlugin(dAtA []byte, offset int, v uint64) int { offset -= sovPlugin(v) base := offset @@ -1309,6 +1442,21 @@ func (m *File) Size() (n int) { return n } +func (m *CheckPluginConfigurationResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.IsDiscoveryConfigured { + n += 2 + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func sovPlugin(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2127,6 +2275,77 @@ func (m *File) Unmarshal(dAtA []byte) error { } return nil } +func (m *CheckPluginConfigurationResponse) 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 ErrIntOverflowPlugin + } + 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: CheckPluginConfigurationResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CheckPluginConfigurationResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsDiscoveryConfigured", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlugin + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsDiscoveryConfigured = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipPlugin(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPlugin + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipPlugin(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/cmpserver/plugin/config_test.go b/cmpserver/plugin/config_test.go index 3b5a58a1826a7..db08e92a2f563 100644 --- a/cmpserver/plugin/config_test.go +++ b/cmpserver/plugin/config_test.go @@ -159,9 +159,9 @@ spec: require.NoError(t, err) config, err := ReadPluginConfig(tempDir) if tcc.expectedErr != "" { - assert.EqualError(t, err, tcc.expectedErr) + require.EqualError(t, err, tcc.expectedErr) } else { - assert.NoError(t, err) + require.NoError(t, err) } assert.Equal(t, tcc.expected, config) }) diff --git a/cmpserver/plugin/plugin.go b/cmpserver/plugin/plugin.go index 49c15f7015f9b..ee00f66ad9ecf 100644 --- a/cmpserver/plugin/plugin.go +++ b/cmpserver/plugin/plugin.go @@ -9,18 +9,18 @@ import ( "os" "os/exec" "path/filepath" - "strconv" "strings" "time" - "unicode" "github.com/argoproj/pkg/rand" + "github.com/golang/protobuf/ptypes/empty" "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" @@ -76,7 +76,7 @@ func runCommand(ctx context.Context, command Command, path string, env []string) } logCtx := log.WithFields(log.Fields{"execID": execId}) - argsToLog := getCommandArgsToLog(cmd) + argsToLog := argoexec.GetCommandArgsToLog(cmd) logCtx.WithFields(log.Fields{"dir": cmd.Dir}).Info(argsToLog) var stdout bytes.Buffer @@ -135,28 +135,6 @@ func runCommand(ctx context.Context, command Command, path string, env []string) return strings.TrimSuffix(output, "\n"), nil } -// getCommandArgsToLog represents the given command in a way that we can copy-and-paste into a terminal -func getCommandArgsToLog(cmd *exec.Cmd) string { - var argsToLog []string - for _, arg := range cmd.Args { - containsSpace := false - for _, r := range arg { - if unicode.IsSpace(r) { - containsSpace = true - break - } - } - if containsSpace { - // add quotes and escape any internal quotes - argsToLog = append(argsToLog, strconv.Quote(arg)) - } else { - argsToLog = append(argsToLog, arg) - } - } - args := strings.Join(argsToLog, " ") - return args -} - type CmdError struct { Args string Stderr string @@ -240,6 +218,9 @@ func (s *Service) generateManifestGeneric(stream GenerateManifestStream) error { if err != nil { return fmt.Errorf("error generating manifests: %w", err) } + + log.Tracef("Generated manifests result: %s", response.Manifests) + err = stream.SendAndClose(response) if err != nil { return fmt.Errorf("error sending manifest response: %w", err) @@ -443,3 +424,15 @@ func getParametersAnnouncement(ctx context.Context, appDir string, announcements } return repoResponse, nil } + +func (s *Service) CheckPluginConfiguration(ctx context.Context, _ *empty.Empty) (*apiclient.CheckPluginConfigurationResponse, error) { + isDiscoveryConfigured := s.isDiscoveryConfigured() + response := &apiclient.CheckPluginConfigurationResponse{IsDiscoveryConfigured: isDiscoveryConfigured} + + return response, nil +} + +func (s *Service) isDiscoveryConfigured() (isDiscoveryConfigured bool) { + config := s.initConstants.PluginConfig + return config.Spec.Discover.FileName != "" || config.Spec.Discover.Find.Glob != "" || len(config.Spec.Discover.Find.Command.Command) > 0 +} diff --git a/cmpserver/plugin/plugin.proto b/cmpserver/plugin/plugin.proto index 16d4268d5939f..6f5b0d0cbf7b6 100644 --- a/cmpserver/plugin/plugin.proto +++ b/cmpserver/plugin/plugin.proto @@ -4,6 +4,7 @@ option go_package = "github.com/argoproj/argo-cd/v2/cmpserver/apiclient"; package plugin; 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 // files over a stream. @@ -57,6 +58,11 @@ message File { bytes chunk = 1; } +// CheckPluginConfigurationResponse contains a list of plugin configuration flags. +message CheckPluginConfigurationResponse { + bool isDiscoveryConfigured = 1; +} + // ConfigManagementPlugin Service service ConfigManagementPluginService { // GenerateManifests receive a stream containing a tgz archive with all required files necessary @@ -64,6 +70,11 @@ service ConfigManagementPluginService { rpc GenerateManifest(stream AppStreamRequest) returns (ManifestResponse) { } + // CheckPluginConfiguration is a pre-flight request to check the plugin configuration + // without sending the whole repo. + rpc CheckPluginConfiguration(google.protobuf.Empty) returns (CheckPluginConfigurationResponse) { + } + // MatchRepository returns whether or not the given application is supported by the plugin rpc MatchRepository(stream AppStreamRequest) returns (RepositoryResponse) { } diff --git a/cmpserver/plugin/plugin_test.go b/cmpserver/plugin/plugin_test.go index 51b4b5c4c11d4..05001c31b3837 100644 --- a/cmpserver/plugin/plugin_test.go +++ b/cmpserver/plugin/plugin_test.go @@ -6,12 +6,12 @@ import ( "fmt" "io" "os" - "os/exec" "path" "path/filepath" "testing" "time" + "github.com/golang/protobuf/ptypes/empty" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/grpc/metadata" @@ -103,7 +103,7 @@ func TestMatchRepository(t *testing.T) { match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, match) assert.True(t, discovery) }) @@ -118,7 +118,7 @@ func TestMatchRepository(t *testing.T) { match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, match) assert.True(t, discovery) }) @@ -133,7 +133,7 @@ func TestMatchRepository(t *testing.T) { _, _, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then - assert.ErrorContains(t, err, "syntax error") + require.ErrorContains(t, err, "syntax error") }) t.Run("will match plugin by glob", func(t *testing.T) { // given @@ -148,7 +148,7 @@ func TestMatchRepository(t *testing.T) { match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, match) assert.True(t, discovery) }) @@ -165,7 +165,7 @@ func TestMatchRepository(t *testing.T) { match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, match) assert.True(t, discovery) }) @@ -182,7 +182,7 @@ func TestMatchRepository(t *testing.T) { _, _, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then - assert.ErrorContains(t, err, "error finding glob match for pattern") + require.ErrorContains(t, err, "error finding glob match for pattern") }) t.Run("will match plugin by command when returns any output", func(t *testing.T) { // given @@ -199,7 +199,7 @@ func TestMatchRepository(t *testing.T) { match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, match) assert.True(t, discovery) }) @@ -217,7 +217,7 @@ func TestMatchRepository(t *testing.T) { // when match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, match) assert.True(t, discovery) }) @@ -236,7 +236,7 @@ func TestMatchRepository(t *testing.T) { match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, match) assert.True(t, discovery) }) @@ -256,7 +256,7 @@ func TestMatchRepository(t *testing.T) { match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, match) assert.True(t, discovery) }) @@ -275,7 +275,7 @@ func TestMatchRepository(t *testing.T) { match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then - assert.Error(t, err) + require.Error(t, err) assert.False(t, match) assert.True(t, discovery) }) @@ -288,7 +288,7 @@ func TestMatchRepository(t *testing.T) { match, discovery, err := f.service.matchRepository(context.Background(), f.path, f.env, ".") // then - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, match) assert.False(t, discovery) }) @@ -323,7 +323,7 @@ func TestGenerateManifest(t *testing.T) { service.WithGenerateCommand(Command{Command: []string{"bad-command"}}) res, err := service.generateManifest(context.Background(), "testdata/kustomize", nil) - assert.ErrorContains(t, err, "executable file not found") + require.ErrorContains(t, err, "executable file not found") assert.Nil(t, res.Manifests) }) t.Run("bad yaml output", func(t *testing.T) { @@ -332,7 +332,7 @@ func TestGenerateManifest(t *testing.T) { service.WithGenerateCommand(Command{Command: []string{"echo", "invalid yaml: }"}}) res, err := service.generateManifest(context.Background(), "testdata/kustomize", nil) - assert.ErrorContains(t, err, "failed to unmarshal manifest") + require.ErrorContains(t, err, "failed to unmarshal manifest") assert.Nil(t, res.Manifests) }) } @@ -345,7 +345,7 @@ func TestGenerateManifest_deadline_exceeded(t *testing.T) { expiredCtx, cancel := context.WithTimeout(context.Background(), time.Second*0) defer cancel() _, err = service.generateManifest(expiredCtx, "", nil) - assert.ErrorContains(t, err, "context deadline exceeded") + require.ErrorContains(t, err, "context deadline exceeded") } // TestRunCommandContextTimeout makes sure the command dies at timeout rather than sleeping past the timeout. @@ -360,13 +360,13 @@ func TestRunCommandContextTimeout(t *testing.T) { before := time.Now() _, err := runCommand(ctx, command, "", []string{}) after := time.Now() - assert.Error(t, err) // The command should time out, causing an error. + require.Error(t, err) // The command should time out, causing an error. assert.Less(t, after.Sub(before), 1*time.Second) } func TestRunCommandEmptyCommand(t *testing.T) { _, err := runCommand(context.Background(), Command{}, "", nil) - assert.ErrorContains(t, err, "Command is empty") + require.ErrorContains(t, err, "Command is empty") } // TestRunCommandContextTimeoutWithCleanup makes sure that the process is given enough time to cleanup before sending SIGKILL. @@ -385,7 +385,7 @@ func TestRunCommandContextTimeoutWithCleanup(t *testing.T) { output, err := runCommand(ctx, command, "", []string{}) after := time.Now() - assert.Error(t, err) // The command should time out, causing an error. + require.Error(t, err) // The command should time out, causing an error. assert.Less(t, after.Sub(before), 1*time.Second) // The command should still have completed the cleanup after termination. assert.Contains(t, output, "cleanup completed") @@ -451,7 +451,7 @@ func Test_getParametersAnnouncement_invalid_json(t *testing.T) { Args: []string{`[`}, } _, err := getParametersAnnouncement(context.Background(), "", []*repoclient.ParameterAnnouncement{}, command, []*apiclient.EnvEntry{}) - assert.Error(t, err) + require.Error(t, err) assert.Contains(t, err.Error(), "unexpected end of JSON input") } @@ -461,7 +461,7 @@ func Test_getParametersAnnouncement_bad_command(t *testing.T) { Args: []string{"1"}, } _, err := getParametersAnnouncement(context.Background(), "", []*repoclient.ParameterAnnouncement{}, command, []*apiclient.EnvEntry{}) - assert.Error(t, err) + require.Error(t, err) assert.Contains(t, err.Error(), "error executing dynamic parameter output command") } @@ -472,7 +472,7 @@ func Test_getTempDirMustCleanup(t *testing.T) { err := os.Chmod(tempDir, 0o000) require.NoError(t, err) _, _, err = getTempDirMustCleanup(path.Join(tempDir, "test")) - assert.ErrorContains(t, err, "error creating temp dir") + require.ErrorContains(t, err, "error creating temp dir") err = os.Chmod(tempDir, 0o700) require.NoError(t, err) @@ -500,13 +500,13 @@ func TestService_Init(t *testing.T) { require.NoError(t, err) s := NewService(CMPServerInitConstants{PluginConfig: PluginConfig{}}) err = s.Init(workDir) - assert.ErrorContains(t, err, "error removing workdir", "Init must throw an error if it can't remove the work directory") + require.ErrorContains(t, err, "error removing workdir", "Init must throw an error if it can't remove the work directory") // Make the base directory writable so Init's cleanup succeeds. err = os.Chmod(tempDir, 0o700) require.NoError(t, err) err = s.Init(workDir) - assert.NoError(t, err) + require.NoError(t, err) assert.DirExists(t, workDir) assert.NoFileExists(t, testfile) } @@ -532,6 +532,76 @@ func TestEnviron(t *testing.T) { }) } +func TestIsDiscoveryConfigured(t *testing.T) { + type fixture struct { + service *Service + } + setup := func(t *testing.T, opts ...pluginOpt) *fixture { + t.Helper() + cic := buildPluginConfig(opts...) + s := NewService(*cic) + return &fixture{ + service: s, + } + } + t.Run("discovery is enabled when is configured by FileName", func(t *testing.T) { + // given + d := Discover{ + FileName: "kustomization.yaml", + } + f := setup(t, withDiscover(d)) + + // when + isDiscoveryConfigured := f.service.isDiscoveryConfigured() + + // then + assert.True(t, isDiscoveryConfigured) + }) + t.Run("discovery is enabled when is configured by Glob", func(t *testing.T) { + // given + d := Discover{ + Find: Find{ + Glob: "**/*/plugin.yaml", + }, + } + f := setup(t, withDiscover(d)) + + // when + isDiscoveryConfigured := f.service.isDiscoveryConfigured() + + // then + assert.True(t, isDiscoveryConfigured) + }) + t.Run("discovery is enabled when is configured by Command", func(t *testing.T) { + // given + d := Discover{ + Find: Find{ + Command: Command{ + Command: []string{"echo", "test"}, + }, + }, + } + f := setup(t, withDiscover(d)) + + // when + isDiscoveryConfigured := f.service.isDiscoveryConfigured() + + // then + assert.True(t, isDiscoveryConfigured) + }) + t.Run("discovery is disabled when discover is not configured", func(t *testing.T) { + // given + d := Discover{} + f := setup(t, withDiscover(d)) + + // when + isDiscoveryConfigured := f.service.isDiscoveryConfigured() + + // then + assert.False(t, isDiscoveryConfigured) + }) +} + type MockGenerateManifestStream struct { metadataSent bool fileSent bool @@ -779,29 +849,43 @@ func TestService_GetParametersAnnouncement(t *testing.T) { }) } -func Test_getCommandArgsToLog(t *testing.T) { - testCases := []struct { - name string - args []string - expected string - }{ - { - name: "no spaces", - args: []string{"sh", "-c", "cat"}, - expected: "sh -c cat", - }, - { - name: "spaces", - args: []string{"sh", "-c", `echo "hello world"`}, - expected: `sh -c "echo \"hello world\""`, - }, +func TestService_CheckPluginConfiguration(t *testing.T) { + type fixture struct { + service *Service } - - for _, tc := range testCases { - tcc := tc - t.Run(tcc.name, func(t *testing.T) { - t.Parallel() - assert.Equal(t, tcc.expected, getCommandArgsToLog(exec.Command(tcc.args[0], tcc.args[1:]...))) - }) + setup := func(t *testing.T, opts ...pluginOpt) *fixture { + t.Helper() + cic := buildPluginConfig(opts...) + s := NewService(*cic) + return &fixture{ + service: s, + } } + t.Run("discovery is enabled when is configured", func(t *testing.T) { + // given + d := Discover{ + FileName: "kustomization.yaml", + } + f := setup(t, withDiscover(d)) + + // when + resp, err := f.service.CheckPluginConfiguration(context.Background(), &empty.Empty{}) + + // then + require.NoError(t, err) + assert.True(t, resp.IsDiscoveryConfigured) + }) + + t.Run("discovery is disabled when is not configured", func(t *testing.T) { + // given + d := Discover{} + f := setup(t, withDiscover(d)) + + // when + resp, err := f.service.CheckPluginConfiguration(context.Background(), &empty.Empty{}) + + // then + require.NoError(t, err) + assert.False(t, resp.IsDiscoveryConfigured) + }) } diff --git a/common/common.go b/common/common.go index d984f0caedbb8..79fcdba195eb6 100644 --- a/common/common.go +++ b/common/common.go @@ -1,15 +1,20 @@ package common import ( - "errors" + "context" + "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" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" ) // Component names @@ -41,6 +46,7 @@ const ( ArgoCDGPGKeysConfigMapName = "argocd-gpg-keys-cm" // ArgoCDAppControllerShardConfigMapName contains the application controller to shard mapping ArgoCDAppControllerShardConfigMapName = "argocd-app-controller-shard-cm" + ArgoCDCmdParamsConfigMapName = "argocd-cmd-params-cm" ) // Some default configurables @@ -216,7 +222,7 @@ const ( EnvGitRetryMaxDuration = "ARGOCD_GIT_RETRY_MAX_DURATION" // EnvGitRetryDuration specifies duration of git remote operation retry EnvGitRetryDuration = "ARGOCD_GIT_RETRY_DURATION" - // EnvGitRetryFactor specifies fator of git remote operation retry + // EnvGitRetryFactor specifies factor of git remote operation retry EnvGitRetryFactor = "ARGOCD_GIT_RETRY_FACTOR" // EnvGitSubmoduleEnabled overrides git submodule support, true by default EnvGitSubmoduleEnabled = "ARGOCD_GIT_MODULES_ENABLED" @@ -248,6 +254,8 @@ const ( EnvHelmIndexCacheDuration = "ARGOCD_HELM_INDEX_CACHE_DURATION" // EnvAppConfigPath allows to override the configuration path for repo server EnvAppConfigPath = "ARGOCD_APP_CONF_PATH" + // EnvAuthToken is the environment variable name for the auth token used by the CLI + EnvAuthToken = "ARGOCD_AUTH_TOKEN" // EnvLogFormat log format that is defined by `--logformat` option EnvLogFormat = "ARGOCD_LOG_FORMAT" // EnvLogLevel log level that is defined by `--loglevel` option @@ -414,3 +422,30 @@ const TokenVerificationError = "failed to verify the token" var TokenVerificationErr = errors.New(TokenVerificationError) var PermissionDeniedAPIError = status.Error(codes.PermissionDenied, "permission denied") + +// Redis password consts +const ( + DefaultRedisInitialPasswordSecretName = "argocd-redis" + DefaultRedisInitialPasswordKey = "auth" +) + +/* +SetOptionalRedisPasswordFromKubeConfig sets the optional Redis password if it exists in the k8s namespace's secrets. + +We specify kubeClient as kubernetes.Interface to allow for mocking in tests, but this should be treated as a kubernetes.Clientset param. +*/ +func SetOptionalRedisPasswordFromKubeConfig(ctx context.Context, kubeClient kubernetes.Interface, namespace string, redisOptions *redis.Options) error { + secret, err := kubeClient.CoreV1().Secrets(namespace).Get(ctx, DefaultRedisInitialPasswordSecretName, v1.GetOptions{}) + if err != nil { + return fmt.Errorf("failed to get secret %s/%s: %w", namespace, DefaultRedisInitialPasswordSecretName, err) + } + if secret == nil { + return fmt.Errorf("failed to get secret %s/%s: secret is nil", namespace, DefaultRedisInitialPasswordSecretName) + } + _, ok := secret.Data[DefaultRedisInitialPasswordKey] + if !ok { + return fmt.Errorf("secret %s/%s does not contain key %s", namespace, DefaultRedisInitialPasswordSecretName, DefaultRedisInitialPasswordKey) + } + redisOptions.Password = string(secret.Data[DefaultRedisInitialPasswordKey]) + return nil +} diff --git a/common/common_test.go b/common/common_test.go index 5632c1e7a78cc..1021a30a14f60 100644 --- a/common/common_test.go +++ b/common/common_test.go @@ -1,12 +1,18 @@ package common import ( + "context" "fmt" "os" "testing" "time" + "github.com/redis/go-redis/v9" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kubefake "k8s.io/client-go/kubernetes/fake" ) // Test env var not set for EnvGRPCKeepAliveMin @@ -44,3 +50,63 @@ func Test_GRPCKeepAliveMinIncorrectlySet(t *testing.T) { grpcKeepAliveTime := GetGRPCKeepAliveTime() assert.Equal(t, 2*grpcKeepAliveExpectedMin, grpcKeepAliveTime) } + +func TestSetOptionalRedisPasswordFromKubeConfig(t *testing.T) { + t.Parallel() + testCases := []struct { + name, namespace, expectedPassword, expectedErr string + secret *corev1.Secret + }{ + { + name: "Secret exists with correct key", + namespace: "default", + expectedPassword: "password123", + expectedErr: "", + secret: &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{Name: DefaultRedisInitialPasswordSecretName}, + Data: map[string][]byte{DefaultRedisInitialPasswordKey: []byte("password123")}, + }, + }, + { + name: "Secret does not exist", + namespace: "default", + expectedPassword: "", + expectedErr: fmt.Sprintf("failed to get secret default/%s", DefaultRedisInitialPasswordSecretName), + secret: nil, + }, + { + name: "Secret exists without correct key", + namespace: "default", + expectedPassword: "", + expectedErr: fmt.Sprintf("secret default/%s does not contain key %s", DefaultRedisInitialPasswordSecretName, DefaultRedisInitialPasswordKey), + secret: &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{Name: DefaultRedisInitialPasswordSecretName}, + Data: map[string][]byte{}, + }, + }, + } + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + var ( + ctx = context.TODO() + kubeClient = kubefake.NewSimpleClientset() + redisOptions = &redis.Options{} + ) + if tc.secret != nil { + 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 != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tc.expectedErr) + } else { + require.NoError(t, err) + } + require.Equal(t, tc.expectedPassword, redisOptions.Password) + }) + } +} diff --git a/controller/appcontroller.go b/controller/appcontroller.go index a15628d8b640f..e607771de586d 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -56,6 +56,7 @@ import ( 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" kubeerrors "k8s.io/apimachinery/pkg/api/errors" @@ -115,11 +116,11 @@ type ApplicationController struct { applicationClientset appclientset.Interface auditLogger *argo.AuditLogger // queue contains app namespace/name - appRefreshQueue workqueue.RateLimitingInterface + appRefreshQueue workqueue.TypedRateLimitingInterface[string] // queue contains app namespace/name/comparisonType and used to request app refresh with the predefined comparison type - appComparisonTypeRefreshQueue workqueue.RateLimitingInterface - appOperationQueue workqueue.RateLimitingInterface - projectRefreshQueue workqueue.RateLimitingInterface + appComparisonTypeRefreshQueue workqueue.TypedRateLimitingInterface[string] + appOperationQueue workqueue.TypedRateLimitingInterface[string] + projectRefreshQueue workqueue.TypedRateLimitingInterface[string] appInformer cache.SharedIndexInformer appLister applisters.ApplicationLister projInformer cache.SharedIndexInformer @@ -163,6 +164,7 @@ func NewApplicationController( metricsPort int, metricsCacheExpiration time.Duration, metricsApplicationLabels []string, + metricsApplicationConditions []string, kubectlParallelismLimit int64, persistResourceHealth bool, clusterSharding sharding.ClusterShardingCache, @@ -171,6 +173,7 @@ func NewApplicationController( serverSideDiff bool, dynamicClusterDistributionEnabled bool, ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts, + enableK8sEvent []string, ) (*ApplicationController, error) { log.Infof("appResyncPeriod=%v, appHardResyncPeriod=%v, appResyncJitter=%v", appResyncPeriod, appHardResyncPeriod, appResyncJitter) db := db.NewDB(namespace, settingsMgr, kubeClientset) @@ -185,17 +188,17 @@ func NewApplicationController( kubectl: kubectl, applicationClientset: applicationClientset, repoClientset: repoClientset, - appRefreshQueue: workqueue.NewNamedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), "app_reconciliation_queue"), - appOperationQueue: workqueue.NewNamedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), "app_operation_processing_queue"), - projectRefreshQueue: workqueue.NewNamedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), "project_reconciliation_queue"), - appComparisonTypeRefreshQueue: workqueue.NewRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig)), + appRefreshQueue: workqueue.NewTypedRateLimitingQueueWithConfig(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), workqueue.TypedRateLimitingQueueConfig[string]{Name: "app_reconciliation_queue"}), + appOperationQueue: workqueue.NewTypedRateLimitingQueueWithConfig(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), workqueue.TypedRateLimitingQueueConfig[string]{Name: "app_operation_processing_queue"}), + projectRefreshQueue: workqueue.NewTypedRateLimitingQueueWithConfig(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), workqueue.TypedRateLimitingQueueConfig[string]{Name: "project_reconciliation_queue"}), + appComparisonTypeRefreshQueue: workqueue.NewTypedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig)), db: db, statusRefreshTimeout: appResyncPeriod, statusHardRefreshTimeout: appHardResyncPeriod, statusRefreshJitter: appResyncJitter, refreshRequestedApps: make(map[string]CompareWith), refreshRequestedAppsMutex: &sync.Mutex{}, - auditLogger: argo.NewAuditLogger(namespace, kubeClientset, common.ApplicationController), + auditLogger: argo.NewAuditLogger(namespace, kubeClientset, common.ApplicationController, enableK8sEvent), settingsMgr: settingsMgr, selfHealTimeout: selfHealTimeout, clusterSharding: clusterSharding, @@ -278,7 +281,7 @@ func NewApplicationController( metricsAddr := fmt.Sprintf("0.0.0.0:%d", metricsPort) - ctrl.metricsServer, err = metrics.NewMetricsServer(metricsAddr, appLister, ctrl.canProcessApp, readinessHealthCheck, metricsApplicationLabels) + ctrl.metricsServer, err = metrics.NewMetricsServer(metricsAddr, appLister, ctrl.canProcessApp, readinessHealthCheck, metricsApplicationLabels, metricsApplicationConditions) if err != nil { return nil, err } @@ -453,19 +456,32 @@ 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(a *appv1.Application, comparisonResult *comparisonResult) (*appv1.ApplicationTree, error) { + ts := stats.NewTimingStats() + defer func() { + 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(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(a, managedResources) + ts.AddCheckpoint("get_resource_tree_ms") if err != nil { return nil, fmt.Errorf("error getting resource tree: %w", err) } err = ctrl.cache.SetAppResourcesTree(a.InstanceName(ctrl.namespace), tree) + ts.AddCheckpoint("set_app_resources_tree_ms") if err != nil { return nil, fmt.Errorf("error setting app resource tree: %w", err) } err = ctrl.cache.SetAppManagedResources(a.InstanceName(ctrl.namespace), managedResources) + ts.AddCheckpoint("set_app_managed_resources_ms") if err != nil { return nil, fmt.Errorf("error setting app managed resources: %w", err) } @@ -497,8 +513,18 @@ func isKnownOrphanedResourceExclusion(key kube.ResourceKey, proj *appv1.AppProje } func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managedResources []*appv1.ResourceDiff) (*appv1.ApplicationTree, error) { + ts := stats.NewTimingStats() + defer func() { + 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 resource tree") + }() nodes := make([]appv1.ResourceNode, 0) proj, err := ctrl.getAppProj(a) + ts.AddCheckpoint("get_app_proj_ms") if err != nil { return nil, fmt.Errorf("failed to get project: %w", err) } @@ -512,6 +538,8 @@ func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managed } warnOrphaned = proj.Spec.OrphanedResources.IsWarn() } + ts.AddCheckpoint("get_orphaned_resources_ms") + managedResourcesKeys := make([]kube.ResourceKey, 0) for i := range managedResources { managedResource := managedResources[i] delete(orphanedNodesMap, kube.NewResourceKey(managedResource.Group, managedResource.Kind, managedResource.Namespace, managedResource.Name)) @@ -537,56 +565,61 @@ func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managed }, }) } else { - err := ctrl.stateCache.IterateHierarchy(a.Spec.Destination.Server, kube.GetResourceKey(live), 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) - } - return clusters, nil - }) - if !permitted { - return false - } - nodes = append(nodes, child) - return true - }) + managedResourcesKeys = append(managedResourcesKeys, kube.GetResourceKey(live)) + } + } + 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 iterate resource hierarchy: %w", err) + return nil, fmt.Errorf("failed to get project clusters: %w", err) } + return clusters, nil + }) + if !permitted { + return false } + nodes = append(nodes, child) + return true + }) + if err != nil { + return nil, fmt.Errorf("failed to iterate resource hierarchy v2: %w", err) } + ts.AddCheckpoint("process_managed_resources_ms") orphanedNodes := make([]appv1.ResourceNode, 0) + orphanedNodesKeys := make([]kube.ResourceKey, 0) for k := range orphanedNodesMap { if k.Namespace != "" && proj.IsGroupKindPermitted(k.GroupKind(), true) && !isKnownOrphanedResourceExclusion(k, proj) { - err := ctrl.stateCache.IterateHierarchy(a.Spec.Destination.Server, k, func(child appv1.ResourceNode, appName string) bool { - belongToAnotherApp := false - if appName != "" { - appKey := ctrl.toAppKey(appName) - if _, exists, err := ctrl.appInformer.GetIndexer().GetByKey(appKey); exists && err == nil { - belongToAnotherApp = true - } - } + orphanedNodesKeys = append(orphanedNodesKeys, k) + } + } + err = ctrl.stateCache.IterateHierarchyV2(a.Spec.Destination.Server, orphanedNodesKeys, func(child appv1.ResourceNode, appName string) bool { + belongToAnotherApp := false + if appName != "" { + appKey := ctrl.toAppKey(appName) + if _, exists, err := ctrl.appInformer.GetIndexer().GetByKey(appKey); exists && err == nil { + belongToAnotherApp = true + } + } - if belongToAnotherApp { - return false - } + if belongToAnotherApp { + return false + } - 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) - }) + 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) + }) - if !permitted { - return false - } - orphanedNodes = append(orphanedNodes, child) - return true - }) - if err != nil { - return nil, err - } + if !permitted { + return false } + orphanedNodes = append(orphanedNodes, child) + return true + }) + if err != nil { + return nil, err } + var conditions []appv1.ApplicationCondition if len(orphanedNodes) > 0 && warnOrphaned { conditions = []appv1.ApplicationCondition{{ @@ -598,15 +631,26 @@ func (ctrl *ApplicationController) getResourceTree(a *appv1.Application, managed sort.Slice(orphanedNodes, func(i, j int) bool { return orphanedNodes[i].ResourceRef.String() < orphanedNodes[j].ResourceRef.String() }) + ts.AddCheckpoint("process_orphaned_resources_ms") hosts, err := ctrl.getAppHosts(a, nodes) if err != nil { return nil, fmt.Errorf("failed to get app hosts: %w", err) } + ts.AddCheckpoint("get_app_hosts_ms") return &appv1.ApplicationTree{Nodes: nodes, OrphanedNodes: orphanedNodes, Hosts: hosts}, nil } func (ctrl *ApplicationController) getAppHosts(a *appv1.Application, appNodes []appv1.ResourceNode) ([]appv1.HostInfo, error) { + ts := stats.NewTimingStats() + defer func() { + 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[v1.ResourceName]bool{ v1.ResourceCPU: true, v1.ResourceStorage: true, @@ -636,6 +680,7 @@ func (ctrl *ApplicationController) getAppHosts(a *appv1.Application, appNodes [] } } }) + ts.AddCheckpoint("iterate_resources_ms") if err != nil { return nil, err } @@ -691,6 +736,7 @@ func (ctrl *ApplicationController) getAppHosts(a *appv1.Application, appNodes [] }) hosts = append(hosts, appv1.HostInfo{Name: nodeName, SystemInfo: node.SystemInfo, ResourcesInfo: resourcesInfo}) } + ts.AddCheckpoint("process_app_pods_by_node_ms") return hosts, nil } @@ -866,10 +912,8 @@ func (ctrl *ApplicationController) requestAppRefresh(appName string, compareWith } if after != nil { ctrl.appRefreshQueue.AddAfter(key, *after) - ctrl.appOperationQueue.AddAfter(key, *after) } else { ctrl.appRefreshQueue.AddRateLimited(key) - ctrl.appOperationQueue.AddRateLimited(key) } } } @@ -898,7 +942,7 @@ func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext b ctrl.appOperationQueue.Done(appKey) }() - obj, exists, err := ctrl.appInformer.GetIndexer().GetByKey(appKey.(string)) + obj, exists, err := ctrl.appInformer.GetIndexer().GetByKey(appKey) if err != nil { log.Errorf("Failed to get application '%s' from informer index: %+v", appKey, err) return @@ -913,6 +957,15 @@ func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext b return } app := origApp.DeepCopy() + logCtx := getAppLog(app) + ts := stats.NewTimingStats() + defer func() { + 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 processing app operation queue item") + }() if app.Operation != nil { // If we get here, we are about to process an operation, but we cannot rely on informer since it might have stale data. @@ -920,14 +973,16 @@ func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext b // 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.ObjectMeta.Name, metav1.GetOptions{}) if err != nil { - getAppLog(app).Errorf("Failed to retrieve latest application state: %v", err) + logCtx.Errorf("Failed to retrieve latest application state: %v", err) return } app = freshApp } + ts.AddCheckpoint("get_fresh_app_ms") if app.Operation != nil { ctrl.processRequestedAppOperation(app) + ts.AddCheckpoint("process_requested_app_operation_ms") } else if app.DeletionTimestamp != nil { if err = ctrl.finalizeApplicationDeletion(app, func(project string) ([]*appv1.Cluster, error) { return ctrl.db.GetProjectClusters(context.Background(), project) @@ -937,8 +992,9 @@ func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext b Message: err.Error(), }) message := fmt.Sprintf("Unable to delete application resources: %v", err.Error()) - ctrl.auditLogger.LogAppEvent(app, argo.EventInfo{Reason: argo.EventReasonStatusRefreshed, Type: v1.EventTypeWarning}, message, "") + ctrl.logAppEvent(app, argo.EventInfo{Reason: argo.EventReasonStatusRefreshed, Type: v1.EventTypeWarning}, message, context.TODO()) } + ts.AddCheckpoint("finalize_application_deletion_ms") } return } @@ -958,8 +1014,8 @@ func (ctrl *ApplicationController) processAppComparisonTypeQueueItem() (processN return } - if parts := strings.Split(key.(string), "/"); len(parts) != 3 { - log.Warnf("Unexpected key format in appComparisonTypeRefreshTypeQueue. Key should consists of namespace/name/comparisonType but got: %s", key.(string)) + 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 { if compareWith, err := strconv.Atoi(parts[2]); err != nil { log.Warnf("Unable to parse comparison type: %v", err) @@ -985,7 +1041,7 @@ func (ctrl *ApplicationController) processProjectQueueItem() (processNext bool) processNext = false return } - obj, exists, err := ctrl.projInformer.GetIndexer().GetByKey(key.(string)) + obj, exists, err := ctrl.projInformer.GetIndexer().GetByKey(key) if err != nil { log.Errorf("Failed to get project '%s' from informer index: %+v", key, err) return @@ -1271,6 +1327,14 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli ctrl.setOperationState(app, state) } }() + ts := stats.NewTimingStats() + defer func() { + 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 processing requested app operation") + }() terminating := false if isOperationInProgress(app) { state = app.Status.OperationState.DeepCopy() @@ -1305,6 +1369,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli ctrl.setOperationState(app, state) logCtx.Infof("Initialized new operation: %v", *app.Operation) } + ts.AddCheckpoint("initial_operation_stage_ms") if err := argo.ValidateDestination(context.Background(), &app.Spec.Destination, ctrl.db); err != nil { state.Phase = synccommon.OperationFailed @@ -1312,9 +1377,11 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli } else { ctrl.appStateManager.SyncAppState(app, state) } + ts.AddCheckpoint("validate_and_sync_app_state_ms") // Check whether application is allowed to use project _, err := ctrl.getAppProj(app) + ts.AddCheckpoint("get_app_proj_ms") if err != nil { state.Phase = synccommon.OperationError state.Message = err.Error() @@ -1357,6 +1424,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli } ctrl.setOperationState(app, state) + ts.AddCheckpoint("final_set_operation_state") if state.Phase.Completed() && (app.Operation.Sync != nil && !app.Operation.Sync.DryRun) { // if we just completed an operation, force a refresh so that UI will report up-to-date // sync/health information @@ -1367,6 +1435,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli logCtx.Warnf("Fails to requeue application: %v", err) } } + ts.AddCheckpoint("request_app_refresh_ms") } func (ctrl *ApplicationController) setOperationState(app *appv1.Application, state *appv1.OperationState) { @@ -1440,7 +1509,7 @@ func (ctrl *ApplicationController) setOperationState(app *appv1.Application, sta eventInfo.Type = v1.EventTypeWarning messages = append(messages, "failed:", state.Message) } - ctrl.auditLogger.LogAppEvent(app, eventInfo, strings.Join(messages, " "), "") + ctrl.logAppEvent(app, eventInfo, strings.Join(messages, " "), context.TODO()) ctrl.metricsServer.IncSync(app, state) } } @@ -1479,9 +1548,12 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo if r := recover(); r != nil { log.Errorf("Recovered from panic: %+v\n%s", r, debug.Stack()) } + // We want to have app operation update happen after the sync, so there's no race condition + // and app updates not proceeding. See https://github.com/argoproj/argo-cd/issues/18500. + ctrl.appOperationQueue.AddRateLimited(appKey) ctrl.appRefreshQueue.Done(appKey) }() - obj, exists, err := ctrl.appInformer.GetIndexer().GetByKey(appKey.(string)) + obj, exists, err := ctrl.appInformer.GetIndexer().GetByKey(appKey) if err != nil { log.Errorf("Failed to get application '%s' from informer index: %+v", appKey, err) return @@ -1510,9 +1582,13 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo }) startTime := time.Now() + ts := stats.NewTimingStats() defer func() { reconcileDuration := time.Since(startTime) ctrl.metricsServer.IncReconcile(origApp, reconcileDuration) + for k, v := range ts.Timings() { + logCtx = logCtx.WithField(k, v.Milliseconds()) + } logCtx.WithFields(log.Fields{ "time_ms": reconcileDuration.Milliseconds(), "patch_ms": patchMs.Milliseconds(), @@ -1538,8 +1614,10 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo return } } + ts.AddCheckpoint("comparison_with_nothing_ms") project, hasErrors := ctrl.refreshAppConditions(app) + ts.AddCheckpoint("refresh_app_conditions_ms") if hasErrors { app.Status.Sync.Status = appv1.SyncStatusCodeUnknown app.Status.Health.Status = health.HealthStatusUnknown @@ -1551,6 +1629,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo if err := ctrl.cache.SetAppManagedResources(app.InstanceName(ctrl.namespace), nil); err != nil { logCtx.Warnf("failed to set app managed resources tree: %v", err) } + ts.AddCheckpoint("process_refresh_app_conditions_errors_ms") return } @@ -1590,6 +1669,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo compareResult, err := ctrl.appStateManager.CompareAppState(app, project, revisions, sources, refreshType == appv1.RefreshTypeHard, comparisonLevel == CompareWithLatestForceResolve, localManifests, hasMultipleSources, false) + ts.AddCheckpoint("compare_app_state_ms") if goerrors.Is(err, CompareStateRepoError) { logCtx.Warnf("Ignoring temporary failed attempt to compare app state against repo: %v", err) @@ -1601,8 +1681,10 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo } ctrl.normalizeApplication(origApp, app) + ts.AddCheckpoint("normalize_application_ms") 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) } else { @@ -1610,7 +1692,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo } if project.Spec.SyncWindows.Matches(app).CanSync(false) { - syncErrCond, opMS := ctrl.autoSync(app, compareResult.syncStatus, compareResult.resources) + syncErrCond, opMS := ctrl.autoSync(app, compareResult.syncStatus, compareResult.resources, compareResult.revisionUpdated) setOpMs = opMS if syncErrCond != nil { app.Status.SetConditions( @@ -1626,6 +1708,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo } else { logCtx.Info("Sync prevented by sync window") } + ts.AddCheckpoint("auto_sync_ms") if app.Status.ReconciledAt == nil || comparisonLevel >= CompareWithLatest { app.Status.ReconciledAt = &now @@ -1639,7 +1722,10 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo app.Status.SourceType = compareResult.appSourceType app.Status.SourceTypes = compareResult.appSourceTypes app.Status.ControllerNamespace = ctrl.namespace + ts.AddCheckpoint("app_status_update_ms") 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")) && app.GetDeletionTimestamp() == nil { if compareResult.hasPostDeleteHooks { @@ -1654,6 +1740,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo logCtx.Errorf("Failed to update finalizers: %v", err) } } + ts.AddCheckpoint("process_finalizers_ms") return } @@ -1767,16 +1854,32 @@ func (ctrl *ApplicationController) normalizeApplication(orig, app *appv1.Applica } } +func createMergePatch(orig, new interface{}) ([]byte, bool, error) { + origBytes, err := json.Marshal(orig) + if err != nil { + return nil, false, err + } + newBytes, err := json.Marshal(new) + if err != nil { + return nil, false, err + } + patch, err := jsonpatch.CreateMergePatch(origBytes, newBytes) + if err != nil { + return nil, false, err + } + return patch, string(patch) != "{}", nil +} + // 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) (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.auditLogger.LogAppEvent(orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: v1.EventTypeNormal}, message, "") + ctrl.logAppEvent(orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: v1.EventTypeNormal}, message, context.TODO()) } if orig.Status.Health.Status != newStatus.Health.Status { message := fmt.Sprintf("Updated health status: %s -> %s", orig.Status.Health.Status, newStatus.Health.Status) - ctrl.auditLogger.LogAppEvent(orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: v1.EventTypeNormal}, message, "") + ctrl.logAppEvent(orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: v1.EventTypeNormal}, message, context.TODO()) } var newAnnotations map[string]string if orig.GetAnnotations() != nil { @@ -1786,9 +1889,9 @@ func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, new } delete(newAnnotations, appv1.AnnotationKeyRefresh) } - patch, modified, err := diff.CreateTwoWayMergePatch( + patch, modified, err := createMergePatch( &appv1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: orig.GetAnnotations()}, Status: orig.Status}, - &appv1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: newAnnotations}, Status: *newStatus}, appv1.Application{}) + &appv1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: newAnnotations}, Status: *newStatus}) if err != nil { logCtx.Errorf("Error constructing app status patch: %v", err) return @@ -1812,11 +1915,19 @@ func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, new } // 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) (*appv1.ApplicationCondition, time.Duration) { +func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus *appv1.SyncStatus, resources []appv1.ResourceStatus, revisionUpdated bool) (*appv1.ApplicationCondition, time.Duration) { + logCtx := getAppLog(app) + ts := stats.NewTimingStats() + defer func() { + 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 auto sync") + }() if app.Spec.SyncPolicy == nil || app.Spec.SyncPolicy.Automated == nil { return nil, 0 } - logCtx := getAppLog(app) if app.Operation != nil { logCtx.Infof("Skipping auto-sync: another operation is in progress") @@ -1848,10 +1959,18 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * } } + selfHeal := app.Spec.SyncPolicy.Automated.SelfHeal + // Multi-Source Apps with selfHeal disabled should not trigger an autosync if + // the last sync revision and the new sync revision is the same. + if app.Spec.HasMultipleSources() && !selfHeal && reflect.DeepEqual(app.Status.Sync.Revisions, syncStatus.Revisions) { + logCtx.Infof("Skipping auto-sync: selfHeal disabled and sync caused by object update") + return nil, 0 + } + desiredCommitSHA := syncStatus.Revision desiredCommitSHAsMS := syncStatus.Revisions - alreadyAttempted, attemptPhase := alreadyAttemptedSync(app, desiredCommitSHA, desiredCommitSHAsMS, app.Spec.HasMultipleSources()) - selfHeal := app.Spec.SyncPolicy.Automated.SelfHeal + alreadyAttempted, attemptPhase := alreadyAttemptedSync(app, desiredCommitSHA, desiredCommitSHAsMS, app.Spec.HasMultipleSources(), revisionUpdated) + ts.AddCheckpoint("already_attempted_sync_ms") op := appv1.Operation{ Sync: &appv1.SyncOperation{ Revision: desiredCommitSHA, @@ -1894,6 +2013,7 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * return nil, 0 } } + ts.AddCheckpoint("already_attempted_check_ms") if app.Spec.SyncPolicy.Automated.Prune && !app.Spec.SyncPolicy.Automated.AllowEmpty { bAllNeedPrune := true @@ -1904,14 +2024,16 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * } if bAllNeedPrune { message := fmt.Sprintf("Skipping sync attempt to %s: auto-sync will wipe out all resources", desiredCommitSHA) - logCtx.Warnf(message) + logCtx.Warn(message) return &appv1.ApplicationCondition{Type: appv1.ApplicationConditionSyncError, Message: message}, 0 } } appIf := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace) + ts.AddCheckpoint("get_applications_ms") start := time.Now() updatedApp, err := argo.SetAppOperation(appIf, app.Name, &op) + ts.AddCheckpoint("set_app_operation_ms") setOpTime := time.Since(start) if err != nil { if goerrors.Is(err, argo.ErrAnotherOperationInProgress) { @@ -1926,6 +2048,7 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * } else { ctrl.writeBackToInformer(updatedApp) } + ts.AddCheckpoint("write_back_to_informer_ms") var target string if updatedApp.Spec.HasMultipleSources() { @@ -1934,25 +2057,33 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * target = desiredCommitSHA } message := fmt.Sprintf("Initiated automated sync to '%s'", target) - - ctrl.auditLogger.LogAppEvent(app, argo.EventInfo{Reason: argo.EventReasonOperationStarted, Type: v1.EventTypeNormal}, message, "") + ctrl.logAppEvent(app, argo.EventInfo{Reason: argo.EventReasonOperationStarted, Type: v1.EventTypeNormal}, message, context.TODO()) logCtx.Info(message) return nil, setOpTime } // alreadyAttemptedSync returns whether the most recent sync was performed against the // commitSHA and with the same app source config which are currently set in the app -func alreadyAttemptedSync(app *appv1.Application, commitSHA string, commitSHAsMS []string, hasMultipleSources bool) (bool, synccommon.OperationPhase) { +func alreadyAttemptedSync(app *appv1.Application, commitSHA string, commitSHAsMS []string, hasMultipleSources bool, revisionUpdated bool) (bool, synccommon.OperationPhase) { if app.Status.OperationState == nil || app.Status.OperationState.Operation.Sync == nil || app.Status.OperationState.SyncResult == nil { return false, "" } if hasMultipleSources { - if !reflect.DeepEqual(app.Status.OperationState.SyncResult.Revisions, commitSHAsMS) { - return false, "" + if revisionUpdated { + if !reflect.DeepEqual(app.Status.OperationState.SyncResult.Revisions, commitSHAsMS) { + return false, "" + } + } else { + log.WithField("application", app.Name).Debugf("Skipping auto-sync: commitSHA %s has no changes", commitSHA) } } else { - if app.Status.OperationState.SyncResult.Revision != commitSHA { - return false, "" + if revisionUpdated { + 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.WithField("application", app.Name).Debugf("Skipping auto-sync: commitSHA %s has no changes", commitSHA) } } @@ -1996,7 +2127,7 @@ func (ctrl *ApplicationController) shouldSelfHeal(app *appv1.Application) (bool, // isAppNamespaceAllowed returns whether the application is allowed in the // namespace it's residing in. func (ctrl *ApplicationController) isAppNamespaceAllowed(app *appv1.Application) bool { - return app.Namespace == ctrl.namespace || glob.MatchStringInList(ctrl.applicationNamespaces, app.Namespace, false) + return app.Namespace == ctrl.namespace || glob.MatchStringInList(ctrl.applicationNamespaces, app.Namespace, glob.REGEXP) } func (ctrl *ApplicationController) canProcessApp(obj interface{}) bool { @@ -2125,7 +2256,6 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar key, err := cache.MetaNamespaceKeyFunc(obj) if err == nil { ctrl.appRefreshQueue.AddRateLimited(key) - ctrl.appOperationQueue.AddRateLimited(key) } newApp, newOK := obj.(*appv1.Application) if err == nil && newOK { @@ -2160,7 +2290,9 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar } ctrl.requestAppRefresh(newApp.QualifiedName(), compareWith, delay) - ctrl.appOperationQueue.AddRateLimited(key) + if !newOK || (delay != nil && *delay != time.Duration(0)) { + ctrl.appOperationQueue.AddRateLimited(key) + } ctrl.clusterSharding.UpdateApp(newApp) }, DeleteFunc: func(obj interface{}) { @@ -2275,4 +2407,9 @@ func (ctrl *ApplicationController) getAppList(options metav1.ListOptions) (*appv return appList, nil } +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) +} + type ClusterFilterFunction func(c *appv1.Cluster, distributionFunction sharding.DistributionFunction) bool diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index 1833d28c2bd4f..50fb08042719d 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -43,12 +43,15 @@ import ( "github.com/argoproj/argo-cd/v2/reposerver/apiclient" mockrepoclient "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" "github.com/argoproj/argo-cd/v2/test" + "github.com/argoproj/argo-cd/v2/util/argo" "github.com/argoproj/argo-cd/v2/util/argo/normalizers" cacheutil "github.com/argoproj/argo-cd/v2/util/cache" appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" "github.com/argoproj/argo-cd/v2/util/settings" ) +var testEnableEventList []string = argo.DefaultEnableEventList() + type namespacedResource struct { v1alpha1.ResourceNode AppName string @@ -155,6 +158,7 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { common.DefaultPortArgoCDMetrics, data.metricsCacheExpiration, []string{}, + []string{}, 0, true, nil, @@ -163,6 +167,7 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { false, false, normalizers.IgnoreNormalizerOpts{}, + testEnableEventList, ) db := &dbmocks.ArgoDB{} db.On("GetApplicationControllerReplicas").Return(1) @@ -193,14 +198,16 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { mockStateCache.On("GetNamespaceTopLevelResources", mock.Anything, mock.Anything).Return(response, nil) mockStateCache.On("IterateResources", mock.Anything, mock.Anything).Return(nil) mockStateCache.On("GetClusterCache", mock.Anything).Return(&clusterCacheMock, nil) - mockStateCache.On("IterateHierarchy", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { - key := args[1].(kube.ResourceKey) + mockStateCache.On("IterateHierarchyV2", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { + keys := args[1].([]kube.ResourceKey) action := args[2].(func(child v1alpha1.ResourceNode, appName string) bool) - appName := "" - if res, ok := data.namespacedResources[key]; ok { - appName = res.AppName + for _, key := range keys { + appName := "" + if res, ok := data.namespacedResources[key]; ok { + appName = res.AppName + } + _ = action(v1alpha1.ResourceNode{ResourceRef: v1alpha1.ResourceRef{Kind: key.Kind, Group: key.Group, Namespace: key.Namespace, Name: key.Name}}, appName) } - _ = action(v1alpha1.ResourceNode{ResourceRef: v1alpha1.ResourceRef{Kind: key.Kind, Group: key.Group, Namespace: key.Namespace, Name: key.Name}}, appName) }).Return(nil) return ctrl } @@ -374,8 +381,8 @@ data: var fakePostDeleteHook = ` { - "apiVersion": "v1", - "kind": "Pod", + "apiVersion": "batch/v1", + "kind": "Job", "metadata": { "name": "post-delete-hook", "namespace": "default", @@ -388,22 +395,93 @@ var fakePostDeleteHook = ` } }, "spec": { - "containers": [ - { - "name": "post-delete-hook", - "image": "busybox", - "restartPolicy": "Never", - "command": [ - "/bin/sh", - "-c", - "sleep 5 && echo hello from the post-delete-hook pod" - ] + "template": { + "metadata": { + "name": "post-delete-hook" + }, + "spec": { + "containers": [ + { + "name": "post-delete-hook", + "image": "busybox", + "command": [ + "/bin/sh", + "-c", + "sleep 5 && echo hello from the post-delete-hook job" + ] + } + ], + "restartPolicy": "Never" } - ] + } + } +} +` + +var fakeServiceAccount = ` +{ + "apiVersion": "v1", + "kind": "ServiceAccount", + "metadata": { + "name": "hook-serviceaccount", + "namespace": "default", + "annotations": { + "argocd.argoproj.io/hook": "PostDelete", + "argocd.argoproj.io/hook-delete-policy": "BeforeHookCreation,HookSucceeded" + } } } ` +var fakeRole = ` +{ + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "Role", + "metadata": { + "name": "hook-role", + "namespace": "default", + "annotations": { + "argocd.argoproj.io/hook": "PostDelete", + "argocd.argoproj.io/hook-delete-policy": "BeforeHookCreation,HookSucceeded" + } + }, + "rules": [ + { + "apiGroups": [""], + "resources": ["secrets"], + "verbs": ["get", "delete", "list"] + } + ] +} +` + +var fakeRoleBinding = ` +{ + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "RoleBinding", + "metadata": { + "name": "hook-rolebinding", + "namespace": "default", + "annotations": { + "argocd.argoproj.io/hook": "PostDelete", + "argocd.argoproj.io/hook-delete-policy": "BeforeHookCreation,HookSucceeded" + } + }, + "roleRef": { + "apiGroup": "rbac.authorization.k8s.io", + "kind": "Role", + "name": "hook-role" + }, + "subjects": [ + { + "kind": "ServiceAccount", + "name": "hook-serviceaccount", + "namespace": "default" + } + ] +} +` + func newFakeApp() *v1alpha1.Application { return createFakeApp(fakeApp) } @@ -439,12 +517,39 @@ func newFakeCM() map[string]interface{} { } func newFakePostDeleteHook() map[string]interface{} { - var cm map[string]interface{} - err := yaml.Unmarshal([]byte(fakePostDeleteHook), &cm) + var hook map[string]interface{} + err := yaml.Unmarshal([]byte(fakePostDeleteHook), &hook) if err != nil { panic(err) } - return cm + return hook +} + +func newFakeRoleBinding() map[string]interface{} { + var roleBinding map[string]interface{} + err := yaml.Unmarshal([]byte(fakeRoleBinding), &roleBinding) + if err != nil { + panic(err) + } + return roleBinding +} + +func newFakeRole() map[string]interface{} { + var role map[string]interface{} + err := yaml.Unmarshal([]byte(fakeRole), &role) + if err != nil { + panic(err) + } + return role +} + +func newFakeServiceAccount() map[string]interface{} { + var serviceAccount map[string]interface{} + err := yaml.Unmarshal([]byte(fakeServiceAccount), &serviceAccount) + if err != nil { + panic(err) + } + return serviceAccount } func TestAutoSync(t *testing.T) { @@ -454,15 +559,51 @@ func TestAutoSync(t *testing.T) { Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", } - cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{{Name: "guestbook", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync}}) + 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(context.Background(), "my-app", metav1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, app.Operation) assert.NotNil(t, app.Operation.Sync) assert.False(t, app.Operation.Sync.Prune) } +func TestMultiSourceSelfHeal(t *testing.T) { + // Simulate OutOfSync caused by object change in cluster + // So our Sync Revisions and SyncStatus Revisions should deep equal + t.Run("ClusterObjectChangeShouldNotTriggerAutoSync", func(t *testing.T) { + app := newFakeMultiSourceApp() + app.Spec.SyncPolicy.Automated.SelfHeal = false + app.Status.Sync.Revisions = []string{"z", "x", "v"} + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) + syncStatus := v1alpha1.SyncStatus{ + Status: v1alpha1.SyncStatusCodeOutOfSync, + Revisions: []string{"z", "x", "v"}, + } + 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(context.Background(), "my-app", metav1.GetOptions{}) + require.NoError(t, err) + assert.Nil(t, app.Operation) + }) + + t.Run("NewRevisionChangeShouldTriggerAutoSync", func(t *testing.T) { + app := newFakeMultiSourceApp() + app.Spec.SyncPolicy.Automated.SelfHeal = false + app.Status.Sync.Revisions = []string{"a", "b", "c"} + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) + syncStatus := v1alpha1.SyncStatus{ + Status: v1alpha1.SyncStatusCodeOutOfSync, + Revisions: []string{"z", "x", "v"}, + } + 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(context.Background(), "my-app", metav1.GetOptions{}) + require.NoError(t, err) + assert.NotNil(t, app.Operation) + }) +} + func TestAutoSyncNotAllowEmpty(t *testing.T) { app := newFakeApp() app.Spec.SyncPolicy.Automated.Prune = true @@ -471,7 +612,7 @@ func TestAutoSyncNotAllowEmpty(t *testing.T) { Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", } - cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}) + cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}, true) assert.NotNil(t, cond) } @@ -484,7 +625,7 @@ func TestAutoSyncAllowEmpty(t *testing.T) { Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", } - cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}) + cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}, true) assert.Nil(t, cond) } @@ -498,10 +639,10 @@ func TestSkipAutoSync(t *testing.T) { Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", } - cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}) + cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}, true) assert.Nil(t, cond) app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, app.Operation) }) @@ -513,10 +654,10 @@ func TestSkipAutoSync(t *testing.T) { Status: v1alpha1.SyncStatusCodeSynced, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", } - cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}) + cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}, true) assert.Nil(t, cond) app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, app.Operation) }) @@ -529,10 +670,10 @@ func TestSkipAutoSync(t *testing.T) { Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", } - cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}) + cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}, true) assert.Nil(t, cond) app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, app.Operation) }) @@ -546,10 +687,10 @@ func TestSkipAutoSync(t *testing.T) { Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", } - cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}) + cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{}, true) assert.Nil(t, cond) app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, app.Operation) }) @@ -572,10 +713,10 @@ func TestSkipAutoSync(t *testing.T) { Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", } - cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{{Name: "guestbook", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync}}) + 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(context.Background(), "my-app", metav1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, app.Operation) }) @@ -588,10 +729,10 @@ func TestSkipAutoSync(t *testing.T) { } cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{ {Name: "guestbook", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync, RequiresPruning: true}, - }) + }, true) assert.Nil(t, cond) app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(test.FakeArgoCDNamespace).Get(context.Background(), "my-app", metav1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, app.Operation) }) } @@ -624,10 +765,10 @@ func TestAutoSyncIndicateError(t *testing.T) { Source: *app.Spec.Source.DeepCopy(), }, } - cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{{Name: "guestbook", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync}}) + 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(context.Background(), "my-app", metav1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, app.Operation) } @@ -667,10 +808,10 @@ func TestAutoSyncParameterOverrides(t *testing.T) { Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", }, } - cond, _ := ctrl.autoSync(app, &syncStatus, []v1alpha1.ResourceStatus{{Name: "guestbook", Kind: kube.DeploymentKind, Status: v1alpha1.SyncStatusCodeOutOfSync}}) + 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(context.Background(), "my-app", metav1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, app.Operation) } @@ -715,13 +856,13 @@ func TestFinalizeAppDeletion(t *testing.T) { err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, patched) }) // Ensure any stray resources irregularly labeled with instance label of app are not deleted upon deleting, // when app project restriction is in place - t.Run("ProjectRestrictionEnforced", func(*testing.T) { + t.Run("ProjectRestrictionEnforced", func(t *testing.T) { restrictedProj := v1alpha1.AppProject{ ObjectMeta: metav1.ObjectMeta{ Name: "restricted", @@ -766,11 +907,11 @@ func TestFinalizeAppDeletion(t *testing.T) { err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, patched) objsMap, err := ctrl.stateCache.GetManagedLiveObjs(app, []*unstructured.Unstructured{}) if err != nil { - assert.NoError(t, err) + require.NoError(t, err) } // Managed objects must be empty assert.Empty(t, objsMap) @@ -802,7 +943,7 @@ func TestFinalizeAppDeletion(t *testing.T) { err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, patched) }) @@ -826,7 +967,7 @@ func TestFinalizeAppDeletion(t *testing.T) { err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) - assert.NoError(t, err) + require.NoError(t, err) } app1 := appTemplate.DeepCopy() @@ -869,7 +1010,7 @@ func TestFinalizeAppDeletion(t *testing.T) { err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) - assert.NoError(t, err) + require.NoError(t, err) // finalizer is not deleted assert.False(t, patched) // post-delete hook is created @@ -882,7 +1023,13 @@ func TestFinalizeAppDeletion(t *testing.T) { app.SetPostDeleteFinalizer() app.Spec.Destination.Namespace = test.FakeArgoCDNamespace liveHook := &unstructured.Unstructured{Object: newFakePostDeleteHook()} - require.NoError(t, unstructured.SetNestedField(liveHook.Object, "Succeeded", "status", "phase")) + conditions := []interface{}{ + map[string]interface{}{ + "type": "Complete", + "status": "True", + }, + } + require.NoError(t, unstructured.SetNestedField(liveHook.Object, conditions, "status", "conditions")) ctrl := newFakeController(&fakeData{ manifestResponses: []*apiclient.ManifestResponse{{ Manifests: []string{fakePostDeleteHook}, @@ -907,7 +1054,7 @@ func TestFinalizeAppDeletion(t *testing.T) { err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) - assert.NoError(t, err) + require.NoError(t, err) // finalizer is removed assert.True(t, patched) }) @@ -916,15 +1063,27 @@ func TestFinalizeAppDeletion(t *testing.T) { app := newFakeApp() app.SetPostDeleteFinalizer("cleanup") app.Spec.Destination.Namespace = test.FakeArgoCDNamespace + liveRoleBinding := &unstructured.Unstructured{Object: newFakeRoleBinding()} + liveRole := &unstructured.Unstructured{Object: newFakeRole()} + liveServiceAccount := &unstructured.Unstructured{Object: newFakeServiceAccount()} liveHook := &unstructured.Unstructured{Object: newFakePostDeleteHook()} - require.NoError(t, unstructured.SetNestedField(liveHook.Object, "Succeeded", "status", "phase")) + conditions := []interface{}{ + map[string]interface{}{ + "type": "Complete", + "status": "True", + }, + } + require.NoError(t, unstructured.SetNestedField(liveHook.Object, conditions, "status", "conditions")) ctrl := newFakeController(&fakeData{ manifestResponses: []*apiclient.ManifestResponse{{ - Manifests: []string{fakePostDeleteHook}, + Manifests: []string{fakeRoleBinding, fakeRole, fakeServiceAccount, fakePostDeleteHook}, }}, apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ - kube.GetResourceKey(liveHook): liveHook, + kube.GetResourceKey(liveRoleBinding): liveRoleBinding, + kube.GetResourceKey(liveRole): liveRole, + kube.GetResourceKey(liveServiceAccount): liveServiceAccount, + kube.GetResourceKey(liveHook): liveHook, }, }, nil) @@ -942,10 +1101,15 @@ func TestFinalizeAppDeletion(t *testing.T) { err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) - assert.NoError(t, err) - // post-delete hook is deleted - require.Len(t, ctrl.kubectl.(*MockKubectl).DeletedResources, 1) - require.Equal(t, "post-delete-hook", ctrl.kubectl.(*MockKubectl).DeletedResources[0].Name) + require.NoError(t, err) + // post-delete hooks are deleted + require.Len(t, ctrl.kubectl.(*MockKubectl).DeletedResources, 4) + deletedResources := []string{} + for _, res := range ctrl.kubectl.(*MockKubectl).DeletedResources { + deletedResources = append(deletedResources, res.Name) + } + expectedNames := []string{"hook-rolebinding", "hook-role", "hook-serviceaccount", "post-delete-hook"} + require.ElementsMatch(t, expectedNames, deletedResources, "Deleted resources should match expected names") // finalizer is not removed assert.False(t, patched) }) @@ -992,7 +1156,7 @@ func TestNormalizeApplication(t *testing.T) { normalized := false fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { if patchAction, ok := action.(kubetesting.PatchAction); ok { - if string(patchAction.GetPatch()) == `{"spec":{"project":"default"},"status":{"sync":{"comparedTo":{"destination":{},"source":{"repoURL":""}}}}}` { + if string(patchAction.GetPatch()) == `{"spec":{"project":"default"}}` { normalized = true } } @@ -1103,7 +1267,7 @@ func TestGetResourceTree_HasOrphanedResources(t *testing.T) { TargetState: test.DeploymentManifest, }}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []v1alpha1.ResourceNode{managedDeploy}, tree.Nodes) assert.Equal(t, []v1alpha1.ResourceNode{orphanedDeploy1, orphanedDeploy2}, tree.OrphanedNodes) } @@ -1463,7 +1627,7 @@ func TestUpdateReconciledAt(t *testing.T) { 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 { - assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) + require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } return true, &v1alpha1.Application{}, nil }) @@ -1476,11 +1640,11 @@ func TestUpdateReconciledAt(t *testing.T) { ctrl.processAppRefreshQueueItem() _, updated, err := unstructured.NestedString(receivedPatch, "status", "reconciledAt") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, updated) _, updated, err = unstructured.NestedString(receivedPatch, "status", "observedAt") - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, updated) }) @@ -1492,11 +1656,11 @@ func TestUpdateReconciledAt(t *testing.T) { ctrl.processAppRefreshQueueItem() _, updated, err := unstructured.NestedString(receivedPatch, "status", "reconciledAt") - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, updated) _, updated, err = unstructured.NestedString(receivedPatch, "status", "observedAt") - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, updated) }) } @@ -1522,7 +1686,7 @@ func TestProjectErrorToCondition(t *testing.T) { obj, ok, err := ctrl.appInformer.GetIndexer().GetByKey(key) assert.True(t, ok) - assert.NoError(t, err) + require.NoError(t, err) updatedApp := obj.(*v1alpha1.Application) assert.Equal(t, v1alpha1.ApplicationConditionInvalidSpecError, updatedApp.Status.Conditions[0].Type) assert.Equal(t, "Application referencing project wrong project which does not exist", updatedApp.Status.Conditions[0].Message) @@ -1542,7 +1706,7 @@ func TestFinalizeProjectDeletion_HasApplications(t *testing.T) { }) err := ctrl.finalizeProjectDeletion(proj) - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, patched) } @@ -1554,13 +1718,13 @@ func TestFinalizeProjectDeletion_DoesNotHaveApplications(t *testing.T) { 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 { - assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) + require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } return true, &v1alpha1.AppProject{}, nil }) err := ctrl.finalizeProjectDeletion(proj) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, map[string]interface{}{ "metadata": map[string]interface{}{ "finalizers": nil, @@ -1579,7 +1743,7 @@ func TestProcessRequestedAppOperation_FailedNoRetries(t *testing.T) { 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 { - assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) + require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } return true, &v1alpha1.Application{}, nil }) @@ -1607,7 +1771,7 @@ func TestProcessRequestedAppOperation_InvalidDestination(t *testing.T) { defer fakeAppCs.Unlock() fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { if patchAction, ok := action.(kubetesting.PatchAction); ok { - assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) + require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } return true, &v1alpha1.Application{}, nil }) @@ -1633,7 +1797,7 @@ func TestProcessRequestedAppOperation_FailedHasRetries(t *testing.T) { 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 { - assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) + require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } return true, &v1alpha1.Application{}, nil }) @@ -1645,7 +1809,7 @@ func TestProcessRequestedAppOperation_FailedHasRetries(t *testing.T) { message, _, _ := unstructured.NestedString(receivedPatch, "status", "operationState", "message") assert.Contains(t, message, "Retrying attempt #1") retryCount, _, _ := unstructured.NestedFloat64(receivedPatch, "status", "operationState", "retryCount") - assert.Equal(t, float64(1), retryCount) + assert.InEpsilon(t, float64(1), retryCount, 0.0001) } func TestProcessRequestedAppOperation_RunningPreviouslyFailed(t *testing.T) { @@ -1676,7 +1840,7 @@ func TestProcessRequestedAppOperation_RunningPreviouslyFailed(t *testing.T) { 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 { - assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) + require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } return true, &v1alpha1.Application{}, nil }) @@ -1709,7 +1873,7 @@ func TestProcessRequestedAppOperation_HasRetriesTerminated(t *testing.T) { 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 { - assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) + require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } return true, &v1alpha1.Application{}, nil }) @@ -1736,7 +1900,7 @@ func TestProcessRequestedAppOperation_Successful(t *testing.T) { 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 { - assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) + require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } return true, &v1alpha1.Application{}, nil }) @@ -1799,7 +1963,7 @@ func TestGetAppHosts(t *testing.T) { }}, }}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []v1alpha1.HostInfo{{ Name: "minikube", SystemInfo: corev1.NodeSystemInfo{OSImage: "debian"}, @@ -1926,7 +2090,7 @@ func TestAddControllerNamespace(t *testing.T) { ctrl.processAppRefreshQueueItem() updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(ctrl.namespace).Get(context.Background(), app.Name, metav1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, test.FakeArgoCDNamespace, updatedApp.Status.ControllerNamespace) }) t.Run("set controllerNamespace when the app is in another namespace than the controller", func(t *testing.T) { @@ -1945,7 +2109,82 @@ func TestAddControllerNamespace(t *testing.T) { ctrl.processAppRefreshQueueItem() updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(appNamespace).Get(context.Background(), app.Name, metav1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, test.FakeArgoCDNamespace, updatedApp.Status.ControllerNamespace) }) } + +func TestHelmValuesObjectHasReplaceStrategy(t *testing.T) { + app := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{Sync: v1alpha1.SyncStatus{ComparedTo: v1alpha1.ComparedTo{ + Source: v1alpha1.ApplicationSource{ + Helm: &v1alpha1.ApplicationSourceHelm{ + ValuesObject: &runtime.RawExtension{ + Object: &unstructured.Unstructured{Object: map[string]interface{}{"key": []string{"value"}}}, + }, + }, + }, + }}}, + } + + appModified := v1alpha1.Application{ + Status: v1alpha1.ApplicationStatus{Sync: v1alpha1.SyncStatus{ComparedTo: v1alpha1.ComparedTo{ + Source: v1alpha1.ApplicationSource{ + Helm: &v1alpha1.ApplicationSourceHelm{ + ValuesObject: &runtime.RawExtension{ + Object: &unstructured.Unstructured{Object: map[string]interface{}{"key": []string{"value-modified1"}}}, + }, + }, + }, + }}}, + } + + patch, _, err := createMergePatch( + app, + appModified) + require.NoError(t, err) + assert.Equal(t, `{"status":{"sync":{"comparedTo":{"source":{"helm":{"valuesObject":{"key":["value-modified1"]}}}}}}}`, string(patch)) +} + +func TestAppStatusIsReplaced(t *testing.T) { + original := &v1alpha1.ApplicationStatus{Sync: v1alpha1.SyncStatus{ + ComparedTo: v1alpha1.ComparedTo{ + Destination: v1alpha1.ApplicationDestination{ + Server: "https://mycluster", + }, + }, + }} + + updated := &v1alpha1.ApplicationStatus{Sync: v1alpha1.SyncStatus{ + ComparedTo: v1alpha1.ComparedTo{ + Destination: v1alpha1.ApplicationDestination{ + Name: "mycluster", + }, + }, + }} + + patchData, ok, err := createMergePatch(original, updated) + + require.NoError(t, err) + require.True(t, ok) + patchObj := map[string]interface{}{} + require.NoError(t, json.Unmarshal(patchData, &patchObj)) + + val, has, err := unstructured.NestedFieldNoCopy(patchObj, "sync", "comparedTo", "destination", "server") + require.NoError(t, err) + require.True(t, has) + require.Nil(t, val) +} + +func TestAlreadyAttemptSync(t *testing.T) { + app := newFakeApp() + t.Run("same manifest with sync result", func(t *testing.T) { + attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false, false) + assert.True(t, attempted) + }) + + t.Run("different manifest with sync result", func(t *testing.T) { + attempted, _ := alreadyAttemptedSync(app, "sha", []string{}, false, true) + assert.False(t, attempted) + }) +} diff --git a/controller/cache/cache.go b/controller/cache/cache.go index bc4c9725f9608..170f5118b521a 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -9,6 +9,7 @@ import ( "net/url" "os/exec" "reflect" + "strconv" "strings" "sync" "syscall" @@ -41,8 +42,6 @@ import ( "github.com/argoproj/argo-cd/v2/util/settings" ) -//go:generate go run github.com/vektra/mockery/v2@v2.40.2 --name=LiveStateCache - const ( // EnvClusterCacheResyncDuration is the env variable that holds cluster cache re-sync duration EnvClusterCacheResyncDuration = "ARGOCD_CLUSTER_CACHE_RESYNC_DURATION" @@ -69,6 +68,10 @@ const ( // EnvClusterCacheRetryUseBackoff is the env variable to control whether to use a backoff strategy with the retry during cluster cache sync EnvClusterCacheRetryUseBackoff = "ARGOCD_CLUSTER_CACHE_RETRY_USE_BACKOFF" + + // AnnotationIgnoreResourceUpdates when set to true on an untracked resource, + // argo will apply `ignoreResourceUpdates` configuration on it. + AnnotationIgnoreResourceUpdates = "argocd.argoproj.io/ignore-resource-updates" ) // GitOps engine cluster cache tuning options @@ -122,6 +125,8 @@ type LiveStateCache interface { GetClusterCache(server string) (clustercache.ClusterCache, error) // Executes give callback against resource specified by the key and all its children 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 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(a *appv1.Application, targetObjs []*unstructured.Unstructured) (map[kube.ResourceKey]*unstructured.Unstructured, error) // IterateResources iterates all resource stored in cache @@ -353,13 +358,30 @@ func skipResourceUpdate(oldInfo, newInfo *ResourceInfo) bool { // shouldHashManifest validates if the API resource needs to be hashed. // If there's an app name from resource tracking, or if this is itself an app, we should generate a hash. // Otherwise, the hashing should be skipped to save CPU time. -func shouldHashManifest(appName string, gvk schema.GroupVersionKind) bool { - // Only hash if the resource belongs to an app. +func shouldHashManifest(appName string, gvk schema.GroupVersionKind, un *unstructured.Unstructured) bool { + // Only hash if the resource belongs to an app OR argocd.argoproj.io/ignore-resource-updates is present and set to true // Best - Only hash for resources that are part of an app or their dependencies // (current) - Only hash for resources that are part of an app + all apps that might be from an ApplicationSet // Orphan - If orphan is enabled, hash should be made on all resource of that namespace and a config to disable it // Worst - Hash all resources watched by Argo - return appName != "" || (gvk.Group == application.Group && gvk.Kind == application.ApplicationKind) + isTrackedResource := appName != "" || (gvk.Group == application.Group && gvk.Kind == application.ApplicationKind) + + // If the resource is not a tracked resource, we will look up argocd.argoproj.io/ignore-resource-updates and decide + // whether we generate hash or not. + // If argocd.argoproj.io/ignore-resource-updates is presented and is true, return true + // Else return false + if !isTrackedResource { + if val, ok := un.GetAnnotations()[AnnotationIgnoreResourceUpdates]; ok { + applyResourcesUpdate, err := strconv.ParseBool(val) + if err != nil { + applyResourcesUpdate = false + } + return applyResourcesUpdate + } + return false + } + + return isTrackedResource } // isRetryableError is a helper method to see whether an error @@ -508,7 +530,7 @@ func (c *liveStateCache) getCluster(server string) (clustercache.ClusterCache, e gvk := un.GroupVersionKind() - if cacheSettings.ignoreResourceUpdatesEnabled && shouldHashManifest(appName, gvk) { + if cacheSettings.ignoreResourceUpdatesEnabled && shouldHashManifest(appName, gvk, un) { hash, err := generateManifestHash(un, nil, cacheSettings.resourceOverrides, c.ignoreNormalizerOpts) if err != nil { log.Errorf("Failed to generate manifest hash: %v", err) @@ -627,6 +649,17 @@ func (c *liveStateCache) IterateHierarchy(server string, key kube.ResourceKey, a return nil } +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 + } + clusterInfo.IterateHierarchyV2(keys, func(resource *clustercache.Resource, namespaceResources map[kube.ResourceKey]*clustercache.Resource) bool { + return action(asResourceNode(resource), getApp(resource, namespaceResources)) + }) + return nil +} + func (c *liveStateCache) IterateResources(server string, callback func(res *clustercache.Resource, info *ResourceInfo)) error { clusterInfo, err := c.getSyncedCluster(server) if err != nil { diff --git a/controller/cache/cache_test.go b/controller/cache/cache_test.go index 09064883223f1..63935a1e453f4 100644 --- a/controller/cache/cache_test.go +++ b/controller/cache/cache_test.go @@ -9,6 +9,8 @@ import ( "testing" "time" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "github.com/stretchr/testify/assert" v1 "k8s.io/api/core/v1" apierr "k8s.io/apimachinery/pkg/api/errors" @@ -25,6 +27,7 @@ import ( "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" @@ -653,3 +656,79 @@ func TestSkipResourceUpdate(t *testing.T) { })) }) } + +func TestShouldHashManifest(t *testing.T) { + tests := []struct { + name string + appName string + gvk schema.GroupVersionKind + un *unstructured.Unstructured + annotations map[string]string + want bool + }{ + { + name: "appName not empty gvk matches", + appName: "MyApp", + gvk: schema.GroupVersionKind{Group: application.Group, Kind: application.ApplicationKind}, + un: &unstructured.Unstructured{}, + want: true, + }, + { + name: "appName empty", + appName: "", + gvk: schema.GroupVersionKind{Group: application.Group, Kind: application.ApplicationKind}, + un: &unstructured.Unstructured{}, + want: true, + }, + { + name: "appName empty group not match", + appName: "", + gvk: schema.GroupVersionKind{Group: "group1", Kind: application.ApplicationKind}, + un: &unstructured.Unstructured{}, + want: false, + }, + { + name: "appName empty kind not match", + appName: "", + gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, + un: &unstructured.Unstructured{}, + want: false, + }, + { + name: "argocd.argoproj.io/ignore-resource-updates=true", + appName: "", + gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, + un: &unstructured.Unstructured{}, + annotations: map[string]string{"argocd.argoproj.io/ignore-resource-updates": "true"}, + want: true, + }, + { + name: "argocd.argoproj.io/ignore-resource-updates=invalid", + appName: "", + gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, + un: &unstructured.Unstructured{}, + annotations: map[string]string{"argocd.argoproj.io/ignore-resource-updates": "invalid"}, + want: false, + }, + { + name: "argocd.argoproj.io/ignore-resource-updates=false", + appName: "", + gvk: schema.GroupVersionKind{Group: application.Group, Kind: "kind1"}, + un: &unstructured.Unstructured{}, + annotations: map[string]string{"argocd.argoproj.io/ignore-resource-updates": "false"}, + want: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if test.annotations != nil { + test.un.SetAnnotations(test.annotations) + } + got := shouldHashManifest(test.appName, test.gvk, test.un) + if test.want != got { + t.Fatalf("test=%v want %v got %v", test.name, test.want, got) + } + }) + } +} diff --git a/controller/cache/mocks/LiveStateCache.go b/controller/cache/mocks/LiveStateCache.go index fa15794356ce8..85a4a298ba4c2 100644 --- a/controller/cache/mocks/LiveStateCache.go +++ b/controller/cache/mocks/LiveStateCache.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.40.2. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks @@ -236,6 +236,24 @@ func (_m *LiveStateCache) IterateHierarchy(server string, key kube.ResourceKey, 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) diff --git a/controller/clusterinfoupdater_test.go b/controller/clusterinfoupdater_test.go index b0a873f4ef587..989ac630d528a 100644 --- a/controller/clusterinfoupdater_test.go +++ b/controller/clusterinfoupdater_test.go @@ -23,6 +23,7 @@ import ( clustercache "github.com/argoproj/gitops-engine/pkg/cache" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/tools/cache" ) @@ -76,7 +77,7 @@ func TestClusterSecretUpdater(t *testing.T) { appCache := appstate.NewCache(cacheutil.NewCache(cacheutil.NewInMemoryCache(time.Minute)), time.Minute) cluster, err := argoDB.CreateCluster(ctx, &v1alpha1.Cluster{Server: "http://minikube"}) - assert.NoError(t, err, "Test prepare test data create cluster failed") + require.NoError(t, err, "Test prepare test data create cluster failed") for _, test := range tests { info := &clustercache.ClusterInfo{ @@ -90,11 +91,11 @@ func TestClusterSecretUpdater(t *testing.T) { updater := NewClusterInfoUpdater(nil, argoDB, lister, appCache, nil, nil, fakeNamespace) err = updater.updateClusterInfo(context.Background(), *cluster, info) - assert.NoError(t, err, "Invoking updateClusterInfo failed.") + require.NoError(t, err, "Invoking updateClusterInfo failed.") var clusterInfo v1alpha1.ClusterInfo err = appCache.GetClusterInfo(cluster.Server, &clusterInfo) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, updatedK8sVersion, clusterInfo.ServerVersion) assert.Equal(t, test.ExpectedStatus, clusterInfo.ConnectionState.Status) } @@ -103,7 +104,7 @@ func TestClusterSecretUpdater(t *testing.T) { func TestUpdateClusterLabels(t *testing.T) { shouldNotBeInvoked := func(ctx context.Context, cluster *v1alpha1.Cluster) (*v1alpha1.Cluster, error) { shouldNotHappen := errors.New("if an error happens here, something's wrong") - assert.NoError(t, shouldNotHappen) + require.NoError(t, shouldNotHappen) return nil, shouldNotHappen } tests := []struct { diff --git a/controller/health_test.go b/controller/health_test.go index ed2358bcbdfee..efaf4b2a8fc80 100644 --- a/controller/health_test.go +++ b/controller/health_test.go @@ -8,6 +8,7 @@ import ( 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/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" @@ -53,7 +54,7 @@ func TestSetApplicationHealth(t *testing.T) { resourceStatuses := initStatuses(resources) healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, health.HealthStatusDegraded, healthStatus.Status) assert.Equal(t, health.HealthStatusHealthy, resourceStatuses[0].Health.Status) @@ -62,7 +63,7 @@ func TestSetApplicationHealth(t *testing.T) { // 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) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status) } @@ -75,7 +76,7 @@ func TestSetApplicationHealth_ResourceHealthNotPersisted(t *testing.T) { resourceStatuses := initStatuses(resources) healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, false) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, health.HealthStatusDegraded, healthStatus.Status) assert.Nil(t, resourceStatuses[0].Health) @@ -90,7 +91,7 @@ func TestSetApplicationHealth_MissingResource(t *testing.T) { resourceStatuses := initStatuses(resources) healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, health.HealthStatusMissing, healthStatus.Status) } @@ -104,7 +105,7 @@ func TestSetApplicationHealth_MissingResourceNoBuiltHealthCheck(t *testing.T) { t.Run("NoOverride", func(t *testing.T) { healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status) assert.Equal(t, health.HealthStatusMissing, resourceStatuses[0].Health.Status) }) @@ -115,7 +116,7 @@ func TestSetApplicationHealth_MissingResourceNoBuiltHealthCheck(t *testing.T) { HealthLua: "some health check", }, }, app, true) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, health.HealthStatusMissing, healthStatus.Status) }) } @@ -166,7 +167,7 @@ return hs`, resourceStatuses := initStatuses(resources) healthStatus, err := setApplicationHealth(resources, resourceStatuses, overrides, app, true) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, health.HealthStatusDegraded, healthStatus.Status) }) @@ -178,7 +179,7 @@ return hs`, resourceStatuses := initStatuses(resources) healthStatus, err := setApplicationHealth(resources, resourceStatuses, overrides, app, true) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status) }) } diff --git a/controller/hook.go b/controller/hook.go index 6192de7603002..5c391114ab9bb 100644 --- a/controller/hook.go +++ b/controller/hook.go @@ -51,7 +51,7 @@ func (ctrl *ApplicationController) executePostDeleteHooks(app *v1alpha1.Applicat revisions = append(revisions, src.TargetRevision) } - targets, _, err := ctrl.appStateManager.GetRepoObjs(app, app.Spec.GetSources(), appLabelKey, revisions, false, false, false, proj, false) + targets, _, _, err := ctrl.appStateManager.GetRepoObjs(app, app.Spec.GetSources(), appLabelKey, revisions, false, false, false, proj, false) if err != nil { return false, err } @@ -98,6 +98,18 @@ func (ctrl *ApplicationController) executePostDeleteHooks(app *v1alpha1.Applicat if err != nil { return false, err } + if hookHealth == nil { + logCtx.WithFields(log.Fields{ + "group": obj.GroupVersionKind().Group, + "version": obj.GroupVersionKind().Version, + "kind": obj.GetKind(), + "name": obj.GetName(), + "namespace": obj.GetNamespace(), + }).Info("No health check defined for resource, considering it healthy") + hookHealth = &health.HealthStatus{ + Status: health.HealthStatusHealthy, + } + } if hookHealth.Status == health.HealthStatusProgressing { progressingHooksCnt++ } @@ -128,6 +140,11 @@ func (ctrl *ApplicationController) cleanupPostDeleteHooks(liveObjs map[kube.Reso if err != nil { return false, err } + if hookHealth == nil { + hookHealth = &health.HealthStatus{ + Status: health.HealthStatusHealthy, + } + } if health.IsWorse(aggregatedHealth, hookHealth.Status) { aggregatedHealth = hookHealth.Status } diff --git a/controller/metrics/metrics.go b/controller/metrics/metrics.go index 3e7e70ae05da5..a9df75aff8015 100644 --- a/controller/metrics/metrics.go +++ b/controller/metrics/metrics.go @@ -6,7 +6,7 @@ import ( "fmt" "net/http" "os" - "regexp" + "slices" "strconv" "time" @@ -22,6 +22,7 @@ import ( 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" @@ -54,7 +55,8 @@ const ( var ( descAppDefaultLabels = []string{"namespace", "name", "project"} - descAppLabels *prometheus.Desc + descAppLabels *prometheus.Desc + descAppConditions *prometheus.Desc descAppInfo = prometheus.NewDesc( "argocd_app_info", @@ -62,6 +64,7 @@ var ( append(descAppDefaultLabels, "autosync_enabled", "repo", "dest_server", "dest_namespace", "sync_status", "health_status", "operation"), nil, ) + // Deprecated descAppCreated = prometheus.NewDesc( "argocd_app_created_time", @@ -144,14 +147,14 @@ var ( ) // NewMetricsServer returns a new prometheus server which collects application metrics -func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFilter func(obj interface{}) bool, healthCheck func(r *http.Request) error, appLabels []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 } if len(appLabels) > 0 { - normalizedLabels := normalizeLabels("label", appLabels) + normalizedLabels := metricsutil.NormalizeLabels("label", appLabels) descAppLabels = prometheus.NewDesc( "argocd_app_labels", "Argo Application labels converted to Prometheus labels", @@ -160,8 +163,17 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFil ) } + if len(appConditions) > 0 { + descAppConditions = prometheus.NewDesc( + "argocd_app_condition", + "Report application conditions.", + append(descAppDefaultLabels, "condition"), + nil, + ) + } + mux := http.NewServeMux() - registry := NewAppRegistry(appLister, appFilter, appLabels) + registry := NewAppRegistry(appLister, appFilter, appLabels, appConditions) mux.Handle(MetricsPath, promhttp.HandlerFor(prometheus.Gatherers{ // contains app controller specific metrics @@ -203,20 +215,6 @@ func NewMetricsServer(addr string, appLister applister.ApplicationLister, appFil }, nil } -// Prometheus invalid labels, more info: https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels. -var invalidPromLabelChars = regexp.MustCompile(`[^a-zA-Z0-9_]`) - -func normalizeLabels(prefix string, appLabels []string) []string { - results := []string{} - for _, label := range appLabels { - // prometheus labels don't accept dash in their name - curr := invalidPromLabelChars.ReplaceAllString(label, "_") - result := fmt.Sprintf("%s_%s", prefix, curr) - results = append(results, result) - } - return results -} - func (m *MetricsServer) RegisterClustersInfoSource(ctx context.Context, source HasClustersInfo) { collector := &clusterCollector{infoSource: source} go collector.Run(ctx) @@ -307,24 +305,26 @@ func (m *MetricsServer) SetExpiration(cacheExpiration time.Duration) error { } type appCollector struct { - store applister.ApplicationLister - appFilter func(obj interface{}) bool - appLabels []string + store applister.ApplicationLister + 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 interface{}) bool, appLabels []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, - appLabels: appLabels, + store: appLister, + appFilter: appFilter, + appLabels: appLabels, + appConditions: appConditions, } } // NewAppRegistry creates a new prometheus registry that collects applications -func NewAppRegistry(appLister applister.ApplicationLister, appFilter func(obj interface{}) bool, appLabels []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)) + registry.MustRegister(NewAppCollector(appLister, appFilter, appLabels, appConditions)) return registry } @@ -333,6 +333,9 @@ func (c *appCollector) Describe(ch chan<- *prometheus.Desc) { if len(c.appLabels) > 0 { ch <- descAppLabels } + if len(c.appConditions) > 0 { + ch <- descAppConditions + } ch <- descAppInfo ch <- descAppSyncStatusCode ch <- descAppHealthStatus @@ -397,6 +400,19 @@ func (c *appCollector) collectApps(ch chan<- prometheus.Metric, app *argoappv1.A addGauge(descAppLabels, 1, labelValues...) } + if len(c.appConditions) > 0 { + conditionCount := make(map[string]int) + for _, condition := range app.Status.Conditions { + if slices.Contains(c.appConditions, condition.Type) { + conditionCount[condition.Type]++ + } + } + + for conditionType, count := range conditionCount { + addGauge(descAppConditions, float64(count), conditionType) + } + } + // Deprecated controller metrics if os.Getenv(EnvVarLegacyControllerMetrics) == "true" { addGauge(descAppCreated, float64(app.CreationTimestamp.Unix())) diff --git a/controller/metrics/metrics_test.go b/controller/metrics/metrics_test.go index a1977fe888de9..44a6524ed7d85 100644 --- a/controller/metrics/metrics_test.go +++ b/controller/metrics/metrics_test.go @@ -12,6 +12,7 @@ import ( gitopsCache "github.com/argoproj/gitops-engine/pkg/cache" "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/tools/cache" @@ -115,6 +116,41 @@ status: status: Degraded ` +const fakeApp4 = ` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: my-app-4 + namespace: argocd + labels: + team-name: my-team + team-bu: bu-id + argoproj.io/cluster: test-cluster +spec: + destination: + namespace: dummy-namespace + server: https://localhost:6443 + project: important-project + source: + path: some/path + repoURL: https://github.com/argoproj/argocd-example-apps.git +status: + sync: + status: OutOfSync + health: + status: Degraded + conditions: + - lastTransitionTime: "2024-08-07T12:25:40Z" + message: Application has 1 orphaned resources + type: OrphanedResourceWarning + - lastTransitionTime: "2024-08-07T12:25:40Z" + message: Resource Pod standalone-pod is excluded in the settings + type: ExcludedResourceWarning + - lastTransitionTime: "2024-08-07T12:25:40Z" + message: Resource Endpoint raw-endpoint is excluded in the settings + type: ExcludedResourceWarning +` + const fakeDefaultApp = ` apiVersion: argoproj.io/v1alpha1 kind: Application @@ -178,7 +214,7 @@ func newFakeLister(fakeAppYAMLs ...string) (context.CancelFunc, applister.Applic func testApp(t *testing.T, fakeAppYAMLs []string, expectedResponse string) { t.Helper() - testMetricServer(t, fakeAppYAMLs, expectedResponse, []string{}) + testMetricServer(t, fakeAppYAMLs, expectedResponse, []string{}, []string{}) } type fakeClusterInfo struct { @@ -193,15 +229,17 @@ type TestMetricServerConfig struct { FakeAppYAMLs []string ExpectedResponse string AppLabels []string + AppConditions []string ClustersInfo []gitopsCache.ClusterInfo } -func testMetricServer(t *testing.T, fakeAppYAMLs []string, expectedResponse string, appLabels []string) { +func testMetricServer(t *testing.T, fakeAppYAMLs []string, expectedResponse string, appLabels []string, appConditions []string) { t.Helper() cfg := TestMetricServerConfig{ FakeAppYAMLs: fakeAppYAMLs, ExpectedResponse: expectedResponse, AppLabels: appLabels, + AppConditions: appConditions, ClustersInfo: []gitopsCache.ClusterInfo{}, } runTest(t, cfg) @@ -211,8 +249,8 @@ func runTest(t *testing.T, cfg TestMetricServerConfig) { t.Helper() cancel, appLister := newFakeLister(cfg.FakeAppYAMLs...) defer cancel() - metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, cfg.AppLabels) - assert.NoError(t, err) + metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, cfg.AppLabels, cfg.AppConditions) + require.NoError(t, err) if len(cfg.ClustersInfo) > 0 { ci := &fakeClusterInfo{clustersInfo: cfg.ClustersInfo} @@ -224,7 +262,7 @@ func runTest(t *testing.T, cfg TestMetricServerConfig) { } req, err := http.NewRequest(http.MethodGet, "/metrics", nil) - assert.NoError(t, err) + require.NoError(t, err) rr := httptest.NewRecorder() metricsServ.Handler.ServeHTTP(rr, req) assert.Equal(t, http.StatusOK, rr.Code) @@ -302,7 +340,61 @@ argocd_app_labels{label_non_existing="",name="my-app-3",namespace="argocd",proje for _, c := range cases { c := c t.Run(c.description, func(t *testing.T) { - testMetricServer(t, c.applications, c.responseContains, c.metricLabels) + testMetricServer(t, c.applications, c.responseContains, c.metricLabels, []string{}) + }) + } +} + +func TestMetricConditions(t *testing.T) { + type testCases struct { + testCombination + description string + metricConditions []string + } + cases := []testCases{ + { + description: "metric will only output OrphanedResourceWarning", + metricConditions: []string{"OrphanedResourceWarning"}, + testCombination: testCombination{ + applications: []string{fakeApp4}, + responseContains: ` +# HELP argocd_app_condition Report application conditions. +# TYPE argocd_app_condition gauge +argocd_app_condition{condition="OrphanedResourceWarning",name="my-app-4",namespace="argocd",project="important-project"} 1 +`, + }, + }, + { + description: "metric will only output ExcludedResourceWarning", + metricConditions: []string{"ExcludedResourceWarning"}, + testCombination: testCombination{ + applications: []string{fakeApp4}, + responseContains: ` +# HELP argocd_app_condition Report application conditions. +# TYPE argocd_app_condition gauge +argocd_app_condition{condition="ExcludedResourceWarning",name="my-app-4",namespace="argocd",project="important-project"} 2 +`, + }, + }, + { + description: "metric will only output both OrphanedResourceWarning and ExcludedResourceWarning", + metricConditions: []string{"ExcludedResourceWarning", "OrphanedResourceWarning"}, + testCombination: testCombination{ + applications: []string{fakeApp4}, + responseContains: ` +# HELP argocd_app_condition Report application conditions. +# TYPE argocd_app_condition gauge +argocd_app_condition{condition="OrphanedResourceWarning",name="my-app-4",namespace="argocd",project="important-project"} 1 +argocd_app_condition{condition="ExcludedResourceWarning",name="my-app-4",namespace="argocd",project="important-project"} 2 +`, + }, + }, + } + + for _, c := range cases { + c := c + t.Run(c.description, func(t *testing.T) { + testMetricServer(t, c.applications, c.responseContains, []string{}, c.metricConditions) }) } } @@ -334,8 +426,8 @@ argocd_app_sync_status{name="my-app",namespace="argocd",project="important-proje func TestMetricsSyncCounter(t *testing.T) { cancel, appLister := newFakeLister() defer cancel() - metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}) - assert.NoError(t, err) + metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{}) + require.NoError(t, err) appSyncTotal := ` # HELP argocd_app_sync_total Number of application syncs. @@ -353,7 +445,7 @@ argocd_app_sync_total{dest_server="https://localhost:6443",name="my-app",namespa metricsServ.IncSync(fakeApp, &argoappv1.OperationState{Phase: common.OperationSucceeded}) req, err := http.NewRequest(http.MethodGet, "/metrics", nil) - assert.NoError(t, err) + require.NoError(t, err) rr := httptest.NewRecorder() metricsServ.Handler.ServeHTTP(rr, req) assert.Equal(t, http.StatusOK, rr.Code) @@ -379,15 +471,15 @@ func assertMetricsNotPrinted(t *testing.T, expectedLines, body string) { if line == "" { continue } - assert.False(t, strings.Contains(body, expectedLines)) + assert.NotContains(t, body, expectedLines) } } func TestReconcileMetrics(t *testing.T) { cancel, appLister := newFakeLister() defer cancel() - metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}) - assert.NoError(t, err) + metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{}) + require.NoError(t, err) appReconcileMetrics := ` # HELP argocd_app_reconcile Application reconciliation performance in seconds. @@ -407,7 +499,7 @@ argocd_app_reconcile_count{dest_server="https://localhost:6443",namespace="argoc metricsServ.IncReconcile(fakeApp, 5*time.Second) req, err := http.NewRequest(http.MethodGet, "/metrics", nil) - assert.NoError(t, err) + require.NoError(t, err) rr := httptest.NewRecorder() metricsServ.Handler.ServeHTTP(rr, req) assert.Equal(t, http.StatusOK, rr.Code) @@ -419,8 +511,8 @@ argocd_app_reconcile_count{dest_server="https://localhost:6443",namespace="argoc func TestMetricsReset(t *testing.T) { cancel, appLister := newFakeLister() defer cancel() - metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}) - assert.NoError(t, err) + metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{}) + require.NoError(t, err) appSyncTotal := ` # HELP argocd_app_sync_total Number of application syncs. @@ -431,7 +523,7 @@ argocd_app_sync_total{dest_server="https://localhost:6443",name="my-app",namespa ` req, err := http.NewRequest(http.MethodGet, "/metrics", nil) - assert.NoError(t, err) + require.NoError(t, err) rr := httptest.NewRecorder() metricsServ.Handler.ServeHTTP(rr, req) assert.Equal(t, http.StatusOK, rr.Code) @@ -439,10 +531,10 @@ argocd_app_sync_total{dest_server="https://localhost:6443",name="my-app",namespa assertMetricsPrinted(t, appSyncTotal, body) err = metricsServ.SetExpiration(time.Second) - assert.NoError(t, err) + require.NoError(t, err) time.Sleep(2 * time.Second) req, err = http.NewRequest(http.MethodGet, "/metrics", nil) - assert.NoError(t, err) + require.NoError(t, err) rr = httptest.NewRecorder() metricsServ.Handler.ServeHTTP(rr, req) assert.Equal(t, http.StatusOK, rr.Code) @@ -450,36 +542,36 @@ argocd_app_sync_total{dest_server="https://localhost:6443",name="my-app",namespa log.Println(body) assertMetricsNotPrinted(t, appSyncTotal, body) err = metricsServ.SetExpiration(time.Second) - assert.Error(t, err) + require.Error(t, err) } func TestWorkqueueMetrics(t *testing.T) { cancel, appLister := newFakeLister() defer cancel() - metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}) - assert.NoError(t, err) + metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{}) + require.NoError(t, err) expectedMetrics := ` # TYPE workqueue_adds_total counter -workqueue_adds_total{name="test"} +workqueue_adds_total{controller="test",name="test"} # TYPE workqueue_depth gauge -workqueue_depth{name="test"} +workqueue_depth{controller="test",name="test"} # TYPE workqueue_longest_running_processor_seconds gauge -workqueue_longest_running_processor_seconds{name="test"} +workqueue_longest_running_processor_seconds{controller="test",name="test"} # TYPE workqueue_queue_duration_seconds histogram # TYPE workqueue_unfinished_work_seconds gauge -workqueue_unfinished_work_seconds{name="test"} +workqueue_unfinished_work_seconds{controller="test",name="test"} # TYPE workqueue_work_duration_seconds histogram ` workqueue.NewNamed("test") req, err := http.NewRequest(http.MethodGet, "/metrics", nil) - assert.NoError(t, err) + require.NoError(t, err) rr := httptest.NewRecorder() metricsServ.Handler.ServeHTTP(rr, req) assert.Equal(t, http.StatusOK, rr.Code) @@ -491,8 +583,8 @@ workqueue_unfinished_work_seconds{name="test"} func TestGoMetrics(t *testing.T) { cancel, appLister := newFakeLister() defer cancel() - metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}) - assert.NoError(t, err) + metricsServ, err := NewMetricsServer("localhost:8082", appLister, appFilter, noOpHealthCheck, []string{}, []string{}) + require.NoError(t, err) expectedMetrics := ` # TYPE go_gc_duration_seconds summary @@ -511,7 +603,7 @@ go_threads ` req, err := http.NewRequest(http.MethodGet, "/metrics", nil) - assert.NoError(t, err) + require.NoError(t, err) rr := httptest.NewRecorder() metricsServ.Handler.ServeHTTP(rr, req) assert.Equal(t, http.StatusOK, rr.Code) diff --git a/controller/sharding/sharding_test.go b/controller/sharding/sharding_test.go index ca44b638961cc..ebd212062b199 100644 --- a/controller/sharding/sharding_test.go +++ b/controller/sharding/sharding_test.go @@ -12,6 +12,7 @@ import ( "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/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -410,16 +411,16 @@ func TestInferShard(t *testing.T) { osHostnameError := errors.New("cannot resolve hostname") osHostnameFunction = func() (string, error) { return "exampleshard", osHostnameError } _, err := InferShard() - assert.Error(t, err) + require.Error(t, err) assert.Equal(t, err, osHostnameError) osHostnameFunction = func() (string, error) { return "exampleshard", nil } _, err = InferShard() - assert.NoError(t, err) + require.NoError(t, err) osHostnameFunction = func() (string, error) { return "example-shard", nil } _, err = InferShard() - assert.NoError(t, err) + require.NoError(t, err) } func createTestClusters() (clusterAccessor, *dbmocks.ArgoDB, v1alpha1.Cluster, v1alpha1.Cluster, v1alpha1.Cluster, v1alpha1.Cluster, v1alpha1.Cluster) { @@ -494,7 +495,7 @@ func Test_generateDefaultShardMappingCM_NoPredefinedShard(t *testing.T) { } expectedMappingCM, err := json.Marshal(expectedMapping) - assert.NoError(t, err) + require.NoError(t, err) expectedShadingCM := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ @@ -508,7 +509,7 @@ func Test_generateDefaultShardMappingCM_NoPredefinedShard(t *testing.T) { heartbeatCurrentTime = func() metav1.Time { return expectedTime } osHostnameFunction = func() (string, error) { return "test-example", nil } shardingCM, err := generateDefaultShardMappingCM("test", "test-example", replicas, -1) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedShadingCM, shardingCM) } @@ -529,7 +530,7 @@ func Test_generateDefaultShardMappingCM_PredefinedShard(t *testing.T) { } expectedMappingCM, err := json.Marshal(expectedMapping) - assert.NoError(t, err) + require.NoError(t, err) expectedShadingCM := &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ @@ -543,7 +544,7 @@ func Test_generateDefaultShardMappingCM_PredefinedShard(t *testing.T) { heartbeatCurrentTime = func() metav1.Time { return expectedTime } osHostnameFunction = func() (string, error) { return "test-example", nil } shardingCM, err := generateDefaultShardMappingCM("test", "test-example", replicas, 1) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedShadingCM, shardingCM) } @@ -970,7 +971,7 @@ func TestGetClusterSharding(t *testing.T) { t.Errorf("Expected error %v but got nil", tc.expectedErr) } } else { - assert.NoError(t, err) + require.NoError(t, err) } }) } diff --git a/controller/state.go b/controller/state.go index a9a3be4bdd6b8..5b59f411dafb1 100644 --- a/controller/state.go +++ b/controller/state.go @@ -70,7 +70,7 @@ type managedResource struct { type AppStateManager interface { CompareAppState(app *v1alpha1.Application, project *v1alpha1.AppProject, revisions []string, sources []v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localObjects []string, hasMultipleSources bool, rollback bool) (*comparisonResult, error) SyncAppState(app *v1alpha1.Application, state *v1alpha1.OperationState) - GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject, rollback bool) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, error) + GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject, rollback bool) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, bool, error) } // comparisonResult holds the state of an application after the reconciliation @@ -88,6 +88,7 @@ type comparisonResult struct { timings map[string]time.Duration diffResultList *diff.DiffResultList hasPostDeleteHooks bool + revisionUpdated bool } func (res *comparisonResult) GetSyncStatus() *v1alpha1.SyncStatus { @@ -123,51 +124,51 @@ type appStateManager struct { // task to the repo-server. It returns the list of generated manifests as unstructured // objects. It also returns the full response from all calls to the repo server as the // second argument. -func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject, rollback bool) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, error) { +func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject, rollback bool) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, bool, error) { ts := stats.NewTimingStats() helmRepos, err := m.db.ListHelmRepositories(context.Background()) if err != nil { - return nil, nil, fmt.Errorf("failed to list Helm repositories: %w", err) + return nil, nil, false, fmt.Errorf("failed to list Helm repositories: %w", err) } permittedHelmRepos, err := argo.GetPermittedRepos(proj, helmRepos) if err != nil { - return nil, nil, fmt.Errorf("failed to get permitted Helm repositories for project %q: %w", proj.Name, err) + return nil, nil, false, fmt.Errorf("failed to get permitted Helm repositories for project %q: %w", proj.Name, err) } ts.AddCheckpoint("repo_ms") helmRepositoryCredentials, err := m.db.GetAllHelmRepositoryCredentials(context.Background()) if err != nil { - return nil, nil, fmt.Errorf("failed to get Helm credentials: %w", err) + return nil, nil, false, fmt.Errorf("failed to get Helm credentials: %w", err) } permittedHelmCredentials, err := argo.GetPermittedReposCredentials(proj, helmRepositoryCredentials) if err != nil { - return nil, nil, fmt.Errorf("failed to get permitted Helm credentials for project %q: %w", proj.Name, err) + return nil, nil, false, fmt.Errorf("failed to get permitted Helm credentials for project %q: %w", proj.Name, err) } enabledSourceTypes, err := m.settingsMgr.GetEnabledSourceTypes() if err != nil { - return nil, nil, fmt.Errorf("failed to get enabled source types: %w", err) + return nil, nil, false, fmt.Errorf("failed to get enabled source types: %w", err) } ts.AddCheckpoint("plugins_ms") kustomizeSettings, err := m.settingsMgr.GetKustomizeSettings() if err != nil { - return nil, nil, fmt.Errorf("failed to get Kustomize settings: %w", err) + return nil, nil, false, fmt.Errorf("failed to get Kustomize settings: %w", err) } helmOptions, err := m.settingsMgr.GetHelmSettings() if err != nil { - return nil, nil, fmt.Errorf("failed to get Helm settings: %w", err) + return nil, nil, false, fmt.Errorf("failed to get Helm settings: %w", err) } ts.AddCheckpoint("build_options_ms") serverVersion, apiResources, err := m.liveStateCache.GetVersionsInfo(app.Spec.Destination.Server) if err != nil { - return nil, nil, fmt.Errorf("failed to get cluster version for cluster %q: %w", app.Spec.Destination.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, fmt.Errorf("failed to connect to repo server: %w", err) + return nil, nil, false, fmt.Errorf("failed to connect to repo server: %w", err) } defer io.Close(conn) @@ -179,21 +180,26 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp // revisions for the rollback refSources, err := argo.GetRefSources(context.Background(), sources, app.Spec.Project, m.db.GetRepository, revisions, rollback) if err != nil { - return nil, nil, fmt.Errorf("failed to get ref sources: %w", err) + return nil, nil, false, fmt.Errorf("failed to get ref sources: %w", err) } + revisionUpdated := false + + atLeastOneRevisionIsNotPossibleToBeUpdated := false + + keyManifestGenerateAnnotationVal, keyManifestGenerateAnnotationExists := app.Annotations[v1alpha1.AnnotationKeyManifestGeneratePaths] + for i, source := range sources { if len(revisions) < len(sources) || revisions[i] == "" { revisions[i] = source.TargetRevision } - ts.AddCheckpoint("helm_ms") repo, err := m.db.GetRepository(context.Background(), source.RepoURL, proj.Name) if err != nil { - return nil, nil, fmt.Errorf("failed to get repo %q: %w", source.RepoURL, err) + return nil, nil, false, fmt.Errorf("failed to get repo %q: %w", source.RepoURL, err) } kustomizeOptions, err := kustomizeSettings.GetOptions(source) if err != nil { - return nil, nil, fmt.Errorf("failed to get Kustomize options for source %d of %d: %w", i+1, len(sources), err) + return nil, nil, false, fmt.Errorf("failed to get Kustomize options for source %d of %d: %w", i+1, len(sources), err) } syncedRevision := app.Status.Sync.Revision @@ -205,13 +211,15 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp } } - val, ok := app.Annotations[v1alpha1.AnnotationKeyManifestGeneratePaths] - if !source.IsHelm() && syncedRevision != "" && ok && val != "" { + revision := revisions[i] + + if !source.IsHelm() && syncedRevision != "" && keyManifestGenerateAnnotationExists && keyManifestGenerateAnnotationVal != "" { // Validate the manifest-generate-path annotation to avoid generating manifests if it has not changed. - _, err = repoClient.UpdateRevisionForPaths(context.Background(), &apiclient.UpdateRevisionForPathsRequest{ + updateRevisionResult, err := repoClient.UpdateRevisionForPaths(context.Background(), &apiclient.UpdateRevisionForPathsRequest{ Repo: repo, - Revision: revisions[i], + Revision: revision, SyncedRevision: syncedRevision, + NoRevisionCache: noRevisionCache, Paths: path.GetAppRefreshPaths(app), AppLabelKey: appLabelKey, AppName: app.InstanceName(m.namespace), @@ -224,55 +232,72 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp HasMultipleSources: app.Spec.HasMultipleSources(), }) if err != nil { - return nil, nil, fmt.Errorf("failed to compare revisions for source %d of %d: %w", i+1, len(sources), err) + return nil, nil, false, fmt.Errorf("failed to compare revisions for source %d of %d: %w", i+1, len(sources), err) + } + if updateRevisionResult.Changes { + revisionUpdated = true + } + + // Generate manifests should use same revision as updateRevisionForPaths, because HEAD revision may be different between these two calls + if updateRevisionResult.Revision != "" { + revision = updateRevisionResult.Revision } + } else { + // revisionUpdated is set to true if at least one revision is not possible to be updated, + atLeastOneRevisionIsNotPossibleToBeUpdated = true } - ts.AddCheckpoint("version_ms") - log.Debugf("Generating Manifest for source %s revision %s", source, revisions[i]) + log.Debugf("Generating Manifest for source %s revision %s", source, revision) manifestInfo, err := repoClient.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ - Repo: repo, - Repos: permittedHelmRepos, - Revision: revisions[i], - NoCache: noCache, - NoRevisionCache: noRevisionCache, - AppLabelKey: appLabelKey, - AppName: app.InstanceName(m.namespace), - Namespace: app.Spec.Destination.Namespace, - ApplicationSource: &source, - KustomizeOptions: kustomizeOptions, - KubeVersion: serverVersion, - ApiVersions: argo.APIResourcesToStrings(apiResources, true), - VerifySignature: verifySignature, - HelmRepoCreds: permittedHelmCredentials, - TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)), - EnabledSourceTypes: enabledSourceTypes, - HelmOptions: helmOptions, - HasMultipleSources: app.Spec.HasMultipleSources(), - RefSources: refSources, - ProjectName: proj.Name, - ProjectSourceRepos: proj.Spec.SourceRepos, + Repo: repo, + Repos: permittedHelmRepos, + Revision: revision, + NoCache: noCache, + NoRevisionCache: noRevisionCache, + AppLabelKey: appLabelKey, + AppName: app.InstanceName(m.namespace), + Namespace: app.Spec.Destination.Namespace, + ApplicationSource: &source, + KustomizeOptions: kustomizeOptions, + KubeVersion: serverVersion, + ApiVersions: argo.APIResourcesToStrings(apiResources, true), + VerifySignature: verifySignature, + HelmRepoCreds: permittedHelmCredentials, + TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)), + EnabledSourceTypes: enabledSourceTypes, + HelmOptions: helmOptions, + HasMultipleSources: app.Spec.HasMultipleSources(), + RefSources: refSources, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, + AnnotationManifestGeneratePaths: app.GetAnnotation(v1alpha1.AnnotationKeyManifestGeneratePaths), }) if err != nil { - return nil, nil, fmt.Errorf("failed to generate manifest for source %d of %d: %w", i+1, len(sources), err) + return nil, nil, false, fmt.Errorf("failed to generate manifest for source %d of %d: %w", i+1, len(sources), err) } targetObj, err := unmarshalManifests(manifestInfo.Manifests) if err != nil { - return nil, nil, fmt.Errorf("failed to unmarshal manifests for source %d of %d: %w", i+1, len(sources), err) + return nil, nil, false, fmt.Errorf("failed to unmarshal manifests for source %d of %d: %w", i+1, len(sources), err) } targetObjs = append(targetObjs, targetObj...) manifestInfos = append(manifestInfos, manifestInfo) } - ts.AddCheckpoint("unmarshal_ms") + ts.AddCheckpoint("manifests_ms") logCtx := log.WithField("application", app.QualifiedName()) for k, v := range ts.Timings() { logCtx = logCtx.WithField(k, v.Milliseconds()) } logCtx = logCtx.WithField("time_ms", time.Since(ts.StartTime).Milliseconds()) logCtx.Info("GetRepoObjs stats") - return targetObjs, manifestInfos, nil + + // in case if annotation not exists, we should always execute selfheal if manifests changed + if atLeastOneRevisionIsNotPossibleToBeUpdated { + revisionUpdated = true + } + + return targetObjs, manifestInfos, revisionUpdated, nil } func unmarshalManifests(manifests []string) ([]*unstructured.Unstructured, error) { @@ -422,7 +447,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 // When signature keys are defined in the project spec, we need to verify the signature on the Git revision verifySignature := false - if project.Spec.SignatureKeys != nil && len(project.Spec.SignatureKeys) > 0 && gpg.IsGPGEnabled() { + if len(project.Spec.SignatureKeys) > 0 && gpg.IsGPGEnabled() { verifySignature = true } @@ -439,6 +464,8 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 var manifestInfos []*apiclient.ManifestResponse targetNsExists := false + var revisionUpdated bool + if len(localManifests) == 0 { // If the length of revisions is not same as the length of sources, // we take the revisions from the sources directly for all the sources. @@ -449,7 +476,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 } } - targetObjs, manifestInfos, err = m.GetRepoObjs(app, sources, appLabelKey, revisions, noCache, noRevisionCache, verifySignature, project, rollback) + targetObjs, manifestInfos, revisionUpdated, err = m.GetRepoObjs(app, sources, appLabelKey, revisions, noCache, noRevisionCache, verifySignature, project, rollback) if err != nil { targetObjs = make([]*unstructured.Unstructured, 0) msg := fmt.Sprintf("Failed to load target state: %s", err.Error()) @@ -591,7 +618,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 } // No need to care about the return value here, we just want the modified managedNs - _, err = syncNamespace(m.resourceTracking, appLabelKey, trackingMethod, app.Name, app.Spec.SyncPolicy)(managedNs, liveObj) + _, err = syncNamespace(app.Spec.SyncPolicy)(managedNs, liveObj) if err != nil { conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: err.Error(), LastTransitionTime: &now}) failedToLoadObjs = true @@ -840,6 +867,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 diffConfig: diffConfig, diffResultList: diffResults, hasPostDeleteHooks: hasPostDeleteHooks, + revisionUpdated: revisionUpdated, } if hasMultipleSources { diff --git a/controller/state_test.go b/controller/state_test.go index 95dba246a72cf..a3b7cb195a94e 100644 --- a/controller/state_test.go +++ b/controller/state_test.go @@ -15,6 +15,7 @@ import ( "github.com/sirupsen/logrus" logrustest "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" @@ -50,7 +51,7 @@ func TestCompareAppStateEmpty(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -69,18 +70,18 @@ func TestCompareAppStateRepoError(t *testing.T) { revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) assert.Nil(t, compRes) - assert.EqualError(t, err, CompareStateRepoError.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) - assert.EqualError(t, err, CompareStateRepoError.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) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status) } @@ -114,7 +115,7 @@ func TestCompareAppStateNamespaceMetadataDiffers(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) @@ -163,7 +164,7 @@ func TestCompareAppStateNamespaceMetadataDiffersToManifest(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) @@ -173,7 +174,7 @@ func TestCompareAppStateNamespaceMetadataDiffersToManifest(t *testing.T) { assert.Len(t, compRes.diffResultList.Diffs, 1) result := NewNamespace() - assert.NoError(t, json.Unmarshal(compRes.diffResultList.Diffs[0].PredictedLive, result)) + require.NoError(t, json.Unmarshal(compRes.diffResultList.Diffs[0].PredictedLive, result)) labels := result.GetLabels() delete(labels, "kubernetes.io/metadata.name") @@ -221,7 +222,7 @@ func TestCompareAppStateNamespaceMetadata(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) @@ -231,7 +232,7 @@ func TestCompareAppStateNamespaceMetadata(t *testing.T) { assert.Len(t, compRes.diffResultList.Diffs, 1) result := NewNamespace() - assert.NoError(t, json.Unmarshal(compRes.diffResultList.Diffs[0].PredictedLive, result)) + require.NoError(t, json.Unmarshal(compRes.diffResultList.Diffs[0].PredictedLive, result)) labels := result.GetLabels() delete(labels, "kubernetes.io/metadata.name") @@ -280,7 +281,7 @@ func TestCompareAppStateNamespaceMetadataIsTheSame(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -308,7 +309,7 @@ func TestCompareAppStateMissing(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) @@ -340,7 +341,7 @@ func TestCompareAppStateExtra(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) assert.Len(t, compRes.resources, 1) @@ -371,7 +372,7 @@ func TestCompareAppStateHook(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Empty(t, compRes.resources) @@ -403,7 +404,7 @@ func TestCompareAppStateSkipHook(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Len(t, compRes.resources, 1) @@ -434,7 +435,7 @@ func TestCompareAppStateCompareOptionIgnoreExtraneous(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -467,7 +468,7 @@ func TestCompareAppStateExtraHook(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -496,7 +497,7 @@ func TestAppRevisionsSingleSource(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, app.Spec.GetSources(), false, false, nil, app.Spec.HasMultipleSources(), false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.NotEmpty(t, compRes.syncStatus.Revision) @@ -536,7 +537,7 @@ func TestAppRevisionsMultiSource(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, app.Spec.GetSources(), false, false, nil, app.Spec.HasMultipleSources(), false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Empty(t, compRes.syncStatus.Revision) @@ -548,7 +549,7 @@ func TestAppRevisionsMultiSource(t *testing.T) { func toJSON(t *testing.T, obj *unstructured.Unstructured) string { data, err := json.Marshal(obj) - assert.NoError(t, err) + require.NoError(t, err) return string(data) } @@ -584,7 +585,7 @@ func TestCompareAppStateDuplicatedNamespacedResources(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.Len(t, app.Status.Conditions, 1) @@ -621,7 +622,7 @@ func TestCompareAppStateManagedNamespaceMetadataWithLiveNsDoesNotGetPruned(t *te } ctrl := newFakeController(&data, nil) compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, []string{}, app.Spec.Sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.Empty(t, app.Status.Conditions) @@ -675,7 +676,7 @@ func TestCompareAppStateWithManifestGeneratePath(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "abc123") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, app.Spec.GetSources(), false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Equal(t, "abc123", compRes.syncStatus.Revision) @@ -712,7 +713,7 @@ func TestSetHealth(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status) } @@ -749,7 +750,7 @@ func TestSetHealthSelfReferencedApp(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status) } @@ -773,7 +774,7 @@ func TestSetManagedResourcesWithOrphanedResources(t *testing.T) { tree, err := ctrl.setAppManagedResources(app, &comparisonResult{managedResources: make([]managedResource, 0)}) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, tree.OrphanedNodes, 1) assert.Equal(t, "guestbook", tree.OrphanedNodes[0].Name) assert.Equal(t, app.Namespace, tree.OrphanedNodes[0].Namespace) @@ -802,7 +803,7 @@ func TestSetManagedResourcesWithResourcesOfAnotherApp(t *testing.T) { tree, err := ctrl.setAppManagedResources(app1, &comparisonResult{managedResources: make([]managedResource, 0)}) - assert.NoError(t, err) + require.NoError(t, err) assert.Empty(t, tree.OrphanedNodes) } @@ -824,7 +825,7 @@ func TestReturnUnknownComparisonStateOnSettingLoadError(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, health.HealthStatusUnknown, compRes.healthStatus.Status) assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status) @@ -855,7 +856,7 @@ func TestSetManagedResourcesKnownOrphanedResourceExceptions(t *testing.T) { tree, err := ctrl.setAppManagedResources(app, &comparisonResult{managedResources: make([]managedResource, 0)}) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, tree.OrphanedNodes, 1) assert.Equal(t, "guestbook", tree.OrphanedNodes[0].Name) } @@ -872,7 +873,7 @@ func Test_appStateManager_persistRevisionHistory(t *testing.T) { } addHistory := func() { err := manager.persistRevisionHistory(app, "my-revision", argoappv1.ApplicationSource{}, []string{}, []argoappv1.ApplicationSource{}, false, metav1.Time{}, v1alpha1.OperationInitiator{}) - assert.NoError(t, err) + require.NoError(t, err) } addHistory() assert.Len(t, app.Status.History, 1) @@ -908,7 +909,7 @@ func Test_appStateManager_persistRevisionHistory(t *testing.T) { metav1NowTime := metav1.NewTime(time.Now()) err := manager.persistRevisionHistory(app, "my-revision", argoappv1.ApplicationSource{}, []string{}, []argoappv1.ApplicationSource{}, false, metav1NowTime, v1alpha1.OperationInitiator{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, app.Status.History.LastRevisionHistory().DeployStartedAt, &metav1NowTime) } @@ -965,7 +966,7 @@ func TestSignedResponseNoSignatureRequired(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -992,7 +993,7 @@ func TestSignedResponseNoSignatureRequired(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -1024,7 +1025,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "") compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -1051,7 +1052,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "abc123") compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -1078,7 +1079,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "abc123") compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -1105,7 +1106,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "abc123") compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -1135,7 +1136,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "abc123") compRes, err := ctrl.appStateManager.CompareAppState(app, &testProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -1165,7 +1166,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "abc123") compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, localManifests, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status) @@ -1195,7 +1196,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "abc123") compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -1225,7 +1226,7 @@ func TestSignedResponseSignatureRequired(t *testing.T) { revisions := make([]string, 0) revisions = append(revisions, "abc123") compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, localManifests, false, false) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -1709,3 +1710,49 @@ func TestUseDiffCache(t *testing.T) { }) } } + +func TestCompareAppStateDefaultRevisionUpdated(t *testing.T) { + app := newFakeApp() + data := fakeData{ + manifestResponse: &apiclient.ManifestResponse{ + Manifests: []string{}, + Namespace: test.FakeDestNamespace, + Server: test.FakeClusterURL, + Revision: "abc123", + }, + managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), + } + ctrl := newFakeController(&data, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) + require.NoError(t, err) + assert.NotNil(t, compRes) + assert.NotNil(t, compRes.syncStatus) + assert.True(t, compRes.revisionUpdated) +} + +func TestCompareAppStateRevisionUpdatedWithHelmSource(t *testing.T) { + app := newFakeMultiSourceApp() + data := fakeData{ + manifestResponse: &apiclient.ManifestResponse{ + Manifests: []string{}, + Namespace: test.FakeDestNamespace, + Server: test.FakeClusterURL, + Revision: "abc123", + }, + managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), + } + ctrl := newFakeController(&data, nil) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false, false) + require.NoError(t, err) + assert.NotNil(t, compRes) + assert.NotNil(t, compRes.syncStatus) + assert.True(t, compRes.revisionUpdated) +} diff --git a/controller/sync.go b/controller/sync.go index 9cd4b1f0c6e93..5f896a522f942 100644 --- a/controller/sync.go +++ b/controller/sync.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "strconv" + "strings" "sync/atomic" "time" @@ -23,6 +24,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/managedfields" "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" "k8s.io/kubectl/pkg/util/openapi" "github.com/argoproj/argo-cd/v2/controller/metrics" @@ -30,6 +32,7 @@ import ( 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" 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" @@ -284,6 +287,23 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha } trackingMethod := argo.GetTrackingMethod(m.settingsMgr) + if m.settingsMgr.IsImpersonationEnabled() { + serviceAccountToImpersonate, err := deriveServiceAccountName(proj, app) + if err != nil { + state.Phase = common.OperationError + state.Message = fmt.Sprintf("failed to find a matching service account to impersonate: %v", err) + return + } + logEntry = logEntry.WithFields(log.Fields{"impersonationEnabled": "true", "serviceAccount": serviceAccountToImpersonate}) + // set the impersonation headers. + rawConfig.Impersonate = rest.ImpersonationConfig{ + UserName: serviceAccountToImpersonate, + } + restConfig.Impersonate = rest.ImpersonationConfig{ + UserName: serviceAccountToImpersonate, + } + } + opts := []sync.SyncOpt{ sync.WithLogr(logutils.NewLogrusLogger(logEntry)), sync.WithHealthOverride(lua.ResourceHealthOverrides(resourceOverrides)), @@ -324,7 +344,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha } if syncOp.SyncOptions.HasOption("CreateNamespace=true") { - opts = append(opts, sync.WithNamespaceModifier(syncNamespace(m.resourceTracking, appLabelKey, trackingMethod, app.Name, app.Spec.SyncPolicy))) + opts = append(opts, sync.WithNamespaceModifier(syncNamespace(app.Spec.SyncPolicy))) } syncCtx, cleanup, err := sync.NewSyncContext( @@ -536,3 +556,31 @@ func syncWindowPreventsSync(app *v1alpha1.Application, proj *v1alpha1.AppProject } return !window.CanSync(isManual) } + +// deriveServiceAccountName determines the service account to be used for impersonation for the sync operation. +// The returned service account will be fully qualified including namespace and the service account name in the format system:serviceaccount:: +func deriveServiceAccountName(project *v1alpha1.AppProject, application *v1alpha1.Application) (string, error) { + // spec.Destination.Namespace is optional. If not specified, use the Application's + // namespace + serviceAccountNamespace := application.Spec.Destination.Namespace + if serviceAccountNamespace == "" { + serviceAccountNamespace = application.Namespace + } + // Loop through the destinationServiceAccounts and see if there is any destination that is a candidate. + // if so, return the service account specified for that destination. + for _, item := range project.Spec.DestinationServiceAccounts { + dstServerMatched := glob.Match(item.Server, application.Spec.Destination.Server) + dstNamespaceMatched := glob.Match(item.Namespace, application.Spec.Destination.Namespace) + if dstServerMatched && dstNamespaceMatched { + if strings.Contains(item.DefaultServiceAccount, ":") { + // service account is specified along with its namespace. + 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 + } + } + } + // if there is no match found in the AppProject.Spec.DestinationServiceAccounts, use the default service account of the destination namespace. + return "", fmt.Errorf("no matching service account found for destination server %s and namespace %s", application.Spec.Destination.Server, serviceAccountNamespace) +} diff --git a/controller/sync_namespace.go b/controller/sync_namespace.go index 9578dc8651322..43e0dc6170f48 100644 --- a/controller/sync_namespace.go +++ b/controller/sync_namespace.go @@ -5,12 +5,11 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - "github.com/argoproj/argo-cd/v2/util/argo" ) // syncNamespace determine if Argo CD should create and/or manage the namespace // where the application will be deployed. -func syncNamespace(resourceTracking argo.ResourceTracking, appLabelKey string, trackingMethod v1alpha1.TrackingMethod, appName string, syncPolicy *v1alpha1.SyncPolicy) func(m, l *unstructured.Unstructured) (bool, error) { +func syncNamespace(syncPolicy *v1alpha1.SyncPolicy) func(m *unstructured.Unstructured, l *unstructured.Unstructured) (bool, error) { // This function must return true for the managed namespace to be synced. return func(managedNs, liveNs *unstructured.Unstructured) (bool, error) { if managedNs == nil { diff --git a/controller/sync_namespace_test.go b/controller/sync_namespace_test.go index 5d3ed4299db5a..0124d99532b91 100644 --- a/controller/sync_namespace_test.go +++ b/controller/sync_namespace_test.go @@ -4,12 +4,11 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/types" - "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" ) func createFakeNamespace(uid string, resourceVersion string, labels map[string]string, annotations map[string]string) *unstructured.Unstructured { @@ -249,8 +248,8 @@ func Test_shouldNamespaceSync(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - actual, err := syncNamespace(argo.NewResourceTracking(), common.LabelKeyAppInstance, argo.TrackingMethodAnnotation, "some-app", tt.syncPolicy)(tt.managedNs, tt.liveNs) - assert.NoError(t, err) + actual, err := syncNamespace(tt.syncPolicy)(tt.managedNs, tt.liveNs) + require.NoError(t, err) if tt.managedNs != nil { assert.Equal(t, tt.expectedLabels, tt.managedNs.GetLabels()) diff --git a/controller/sync_test.go b/controller/sync_test.go index 59095d5d40e35..1dbfa2ff9e1a5 100644 --- a/controller/sync_test.go +++ b/controller/sync_test.go @@ -53,7 +53,7 @@ func TestPersistRevisionHistory(t *testing.T) { assert.Equal(t, app.Spec.GetSource(), opState.SyncResult.Source) updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(context.Background(), app.Name, v1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, updatedApp.Status.History, 1) assert.Equal(t, app.Spec.GetSource(), updatedApp.Status.History[0].Source) assert.Equal(t, "abc123", updatedApp.Status.History[0].Revision) @@ -142,7 +142,7 @@ func TestPersistRevisionHistoryRollback(t *testing.T) { assert.Equal(t, source, opState.SyncResult.Source) updatedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(context.Background(), app.Name, v1.GetOptions{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, updatedApp.Status.History, 1) assert.Equal(t, source, updatedApp.Status.History[0].Source) assert.Equal(t, "abc123", updatedApp.Status.History[0].Revision) diff --git a/docs/assets/okta-auth-policy-edit.png b/docs/assets/okta-auth-policy-edit.png new file mode 100644 index 0000000000000..91395dcf5b074 Binary files /dev/null and b/docs/assets/okta-auth-policy-edit.png differ diff --git a/docs/assets/versions.js b/docs/assets/versions.js index 7a2392a392dc8..b9f0b13e8d013 100644 --- a/docs/assets/versions.js +++ b/docs/assets/versions.js @@ -1,48 +1,77 @@ -setTimeout(function() { - const callbackName = 'callback_' + new Date().getTime(); - window[callbackName] = function (response) { - const div = document.createElement('div'); - div.innerHTML = response.html; - document.querySelector(".md-header__inner > .md-header__title").appendChild(div); - const container = div.querySelector('.rst-versions'); - var caret = document.createElement('div'); - caret.innerHTML = "" - caret.classList.add('dropdown-caret') - div.querySelector('.rst-current-version').appendChild(caret); +const targetNode = document.querySelector('.md-header__inner'); +const observerOptions = { + childList: true, + subtree: true +}; + +const observerCallback = function(mutationsList, observer) { + for (let mutation of mutationsList) { + if (mutation.type === 'childList') { + const titleElement = document.querySelector('.md-header__inner > .md-header__title'); + if (titleElement) { + initializeVersionDropdown(); + observer.disconnect(); + } + } + } +}; + +const observer = new MutationObserver(observerCallback); +observer.observe(targetNode, observerOptions); + +function getCurrentVersion() { + const currentVersion = window.location.href.match(/\/en\/(release-(?:v\d+|[\d\.]+|\w+)|latest|stable)\//); + if (currentVersion && currentVersion.length > 1) { + return currentVersion[1]; } + return null; +} + +function initializeVersionDropdown() { + const callbackName = 'callback_' + new Date().getTime(); + window[callbackName] = function(response) { + const div = document.createElement('div'); + div.innerHTML = response.html; + document.querySelector(".md-header__inner > .md-header__title").appendChild(div); + const container = div.querySelector('.rst-versions'); + var caret = document.createElement('div'); + caret.innerHTML = ""; + caret.classList.add('dropdown-caret'); + div.querySelector('.rst-current-version').appendChild(caret); + + div.querySelector('.rst-current-version').addEventListener('click', function() { + container.classList.toggle('shift-up'); + }); + }; var CSSLink = document.createElement('link'); - CSSLink.rel='stylesheet'; + CSSLink.rel = 'stylesheet'; CSSLink.href = '/assets/versions.css'; document.getElementsByTagName('head')[0].appendChild(CSSLink); var script = document.createElement('script'); - script.src = 'https://argo-cd.readthedocs.io/_/api/v2/footer_html/?'+ - 'callback=' + callbackName + '&project=argo-cd&page=&theme=mkdocs&format=jsonp&docroot=docs&source_suffix=.md&version=' + (window['READTHEDOCS_DATA'] || { version: 'latest' }).version; + const currentVersion = getCurrentVersion(); + script.src = 'https://argo-cd.readthedocs.io/_/api/v2/footer_html/?' + + 'callback=' + callbackName + '&project=argo-cd&page=&theme=mkdocs&format=jsonp&docroot=docs&source_suffix=.md&version=' + (currentVersion || 'latest'); document.getElementsByTagName('head')[0].appendChild(script); -}, 0); +} // VERSION WARNINGS window.addEventListener("DOMContentLoaded", function() { - var rtdData = window['READTHEDOCS_DATA'] || { version: 'latest' }; var margin = 30; - var headerHeight = document.getElementsByClassName("md-header")[0].offsetHeight; - if (rtdData.version === "latest") { - document.querySelector("div[data-md-component=announce]").innerHTML = "
You are viewing the docs for an unreleased version of Argo CD, click here to go to the latest stable version.
" - var bannerHeight = document.getElementById('announce-msg').offsetHeight + margin - document.querySelector("header.md-header").style.top = bannerHeight +"px"; - document.querySelector('style').textContent += - "@media screen and (min-width: 76.25em){ .md-sidebar { height: 0; top:"+ (bannerHeight+headerHeight)+"px !important; }}" - document.querySelector('style').textContent += - "@media screen and (min-width: 60em){ .md-sidebar--secondary { height: 0; top:"+ (bannerHeight+headerHeight)+"px !important; }}" - } - else if (rtdData.version !== "stable") { - document.querySelector("div[data-md-component=announce]").innerHTML = "
You are viewing the docs for a previous version of Argo CD, click here to go to the latest stable version.
" - var bannerHeight = document.getElementById('announce-msg').offsetHeight + margin - document.querySelector("header.md-header").style.top = bannerHeight +"px"; + var headerHeight = document.getElementsByClassName("md-header")[0].offsetHeight; + const currentVersion = getCurrentVersion(); + if (currentVersion && currentVersion !== "stable") { + if (currentVersion === "latest") { + document.querySelector("div[data-md-component=announce]").innerHTML = "
You are viewing the docs for an unreleased version of Argo CD, click here to go to the latest stable version.
"; + } else { + document.querySelector("div[data-md-component=announce]").innerHTML = "
You are viewing the docs for a previous version of Argo CD, click here to go to the latest stable version.
"; + } + var bannerHeight = document.getElementById('announce-msg').offsetHeight + margin; + document.querySelector("header.md-header").style.top = bannerHeight + "px"; document.querySelector('style').textContent += - "@media screen and (min-width: 76.25em){ .md-sidebar { height: 0; top:"+ (bannerHeight+headerHeight)+"px !important; }}" + "@media screen and (min-width: 76.25em){ .md-sidebar { height: 0; top:" + (bannerHeight + headerHeight) + "px !important; }}"; document.querySelector('style').textContent += - "@media screen and (min-width: 60em){ .md-sidebar--secondary { height: 0; top:"+ (bannerHeight+headerHeight)+"px !important; }}" + "@media screen and (min-width: 60em){ .md-sidebar--secondary { height: 0; top:" + (bannerHeight + headerHeight) + "px !important; }}"; } }); diff --git a/docs/developer-guide/debugging-remote-environment.md b/docs/developer-guide/debugging-remote-environment.md index 5548d3444af8c..f87d1a0bb009d 100644 --- a/docs/developer-guide/debugging-remote-environment.md +++ b/docs/developer-guide/debugging-remote-environment.md @@ -21,7 +21,7 @@ curl -sSfL https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/i Connect to one of the services, for example, to debug the main ArgoCD server run: ```shell kubectl config set-context --current --namespace argocd -telepresence helm install # Installs telepresence into your cluster +telepresence helm install --set agent.securityContext={} # Installs telepresence into your cluster telepresence connect # Starts the connection to your cluster (bound to the current namespace) telepresence intercept argocd-server --port 8080:http --env-file .envrc.remote # Starts the interception ``` diff --git a/docs/developer-guide/site.md b/docs/developer-guide/docs-site.md similarity index 70% rename from docs/developer-guide/site.md rename to docs/developer-guide/docs-site.md index 33106cd5fa939..43b3fba747186 100644 --- a/docs/developer-guide/site.md +++ b/docs/developer-guide/docs-site.md @@ -1,8 +1,8 @@ -# Site +# Documentation Site ## Developing And Testing -The website is built using `mkdocs` and `mkdocs-material`. +The [documentation website](https://argo-cd.readthedocs.io/) is built using `mkdocs` and `mkdocs-material`. To test: @@ -10,7 +10,7 @@ To test: make serve-docs ``` Once running, you can view your locally built documentation at [http://0.0.0.0:8000/](http://0.0.0.0:8000/). -Make a change to documentation and the website will rebuild and refresh the view. +Making changes to documentation will automatically rebuild and refresh the view. Before submitting a PR build the website, to verify that there are no errors building the site ```bash diff --git a/docs/developer-guide/extensions/proxy-extensions.md b/docs/developer-guide/extensions/proxy-extensions.md index 5d561657eb873..ab4d89c7f8e32 100644 --- a/docs/developer-guide/extensions/proxy-extensions.md +++ b/docs/developer-guide/extensions/proxy-extensions.md @@ -264,6 +264,14 @@ Note that additional pre-configured headers can be added to outgoing request. See [backend service headers](#extensionsbackendservicesheaders-list) section for more details. +#### `Argocd-Username` + +Will be populated with the username logged in Argo CD. + +#### `Argocd-User-Groups` + +Will be populated with the 'groups' claim from the user logged in Argo CD. + ### Multi Backend Use-Case In some cases when Argo CD is configured to sync with multiple remote diff --git a/docs/developer-guide/extensions/ui-extensions.md b/docs/developer-guide/extensions/ui-extensions.md index 8d3d9dc4a3882..ffe4ba936cc74 100644 --- a/docs/developer-guide/extensions/ui-extensions.md +++ b/docs/developer-guide/extensions/ui-extensions.md @@ -6,7 +6,7 @@ in the `argocd-server` Pods that are placed in the `/tmp/extensions` directory a ``` /tmp/extensions ├── example1 -│   └── extension-1.js +│ └── extension-1.js └── example2 └── extension-2.js ``` @@ -73,7 +73,7 @@ registerSystemLevelExtension(component: ExtensionComponent, title: string, optio Below is an example of a simple system level extension: -```typescript +```javascript ((window) => { const component = () => { return React.createElement( @@ -106,7 +106,7 @@ registerStatusPanelExtension(component: StatusPanelExtensionComponent, title: st Below is an example of a simple extension: -```typescript +```javascript ((window) => { const component = () => { return React.createElement( @@ -129,32 +129,95 @@ It is also possible to add an optional flyout widget to your extension. It can b Below is an example of an extension using the flyout widget: -```typescript + +```javascript ((window) => { const component = (props: { - openFlyout: () => any - }) => { + openFlyout: () => any + }) => { return React.createElement( - "div", - { - style: { padding: "10px" }, - onClick: () => props.openFlyout() - }, - "Hello World" + "div", + { + style: { padding: "10px" }, + onClick: () => props.openFlyout() + }, + "Hello World" ); }; const flyout = () => { return React.createElement( - "div", - { style: { padding: "10px" } }, - "This is a flyout" + "div", + { style: { padding: "10px" } }, + "This is a flyout" ); }; window.extensionsAPI.registerStatusPanelExtension( - component, - "My Extension", - "my_extension", - flyout + component, + "My Extension", + "my_extension", + flyout ); })(window); ``` + +## Top Bar Action Menu Extensions + +The top bar panel is the action menu at the top of the application view where the action buttons are displayed like Details, Sync, Refresh. Argo CD allows you to add new button to the top bar action menu of an application. +When the extension button is clicked, the custom widget will be rendered in a flyout panel. + +The extension should be registered using the `extensionsAPI.registerTopBarActionMenuExt` method: + +```typescript +registerTopBarActionMenuExt( + component: TopBarActionMenuExtComponent, + title: string, + id: string, + flyout?: ExtensionComponent, + shouldDisplay: (app?: Application) => boolean = () => true, + iconClassName?: string, + isMiddle = false +) +``` + +The callback function `shouldDisplay` should return true if the extension should be displayed and false otherwise: + +```typescript +const shouldDisplay = (app: Application) => { + return application.metadata?.labels?.['application.environmentLabelKey'] === "prd"; +}; +``` + +Below is an example of a simple extension with a flyout widget: + +```javascript +((window) => { + const shouldDisplay = () => { + return true; + }; + const flyout = () => { + return React.createElement( + "div", + { style: { padding: "10px" } }, + "This is a flyout" + ); + }; + const component = () => { + return React.createElement( + "div", + { + onClick: () => flyout() + }, + "Toolbar Extension Test" + ); + }; + window.extensionsAPI.registerTopBarActionMenuExt( + component, + "Toolbar Extension Test", + "Toolbar_Extension_Test", + flyout, + shouldDisplay, + '', + true + ); +})(window); +``` \ No newline at end of file diff --git a/docs/developer-guide/index.md b/docs/developer-guide/index.md index c0405c5e0803b..08578c0fd0707 100644 --- a/docs/developer-guide/index.md +++ b/docs/developer-guide/index.md @@ -1,10 +1,26 @@ # Overview !!! warning "You probably don't want to be reading this section of the docs." - This part of the manual is aimed at people wanting to develop third-party applications that interact with Argo CD, e.g. + This part of the manual is aimed at helping people contribute to Argo CD, the documentation, or to develop third-party applications that interact with Argo CD, e.g. * A chat bot * A Slack integration -!!! note - Please make sure you've completed the [getting started guide](../getting_started.md). + +## Contributing to Argo CD +* [Code Contribution Guide](code-contributions/) +* [Contributors Quickstart](contributors-quickstart/) +* [Running Argo CD Locally](running-locally/) + +Need help? Start with the [Contributors FAQ](faq/) + +## Contributing to the Documentation +* [Building and Running Documentation Site Locally](docs-site/) + +## Extensions and Third-Party Applications +* [UI Extensions](ui-extensions/) +* [Proxy Extensions](proxy-extensions/) +* [Config Management Plugins](../operator-manual/config-management-plugins/) + +## Contributing to Argo Website +The Argo website is maintained in the [argo-site](https://github.com/argoproj/argo-site) repository. \ No newline at end of file diff --git a/docs/developer-guide/release-process-and-cadence.md b/docs/developer-guide/release-process-and-cadence.md index 36bbba0270e50..2db177eb90984 100644 --- a/docs/developer-guide/release-process-and-cadence.md +++ b/docs/developer-guide/release-process-and-cadence.md @@ -14,7 +14,10 @@ These are the upcoming releases dates: | v2.9 | Monday, Sep. 18, 2023 | Monday, Nov. 6, 2023 | [Leonardo Almeida](https://github.com/leoluz) | [Leonardo Almeida](https://github.com/leoluz) | [checklist](https://github.com/argoproj/argo-cd/issues/14078) | | v2.10 | Monday, Dec. 18, 2023 | Monday, Feb. 5, 2024 | [Katie Lamkin](https://github.com/kmlamkin9) | | [checklist](https://github.com/argoproj/argo-cd/issues/16339) | | v2.11 | Friday, Apr. 5, 2024 | Monday, May 6, 2024 | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/17726) | -| v2.12 | Monday, Jun. 17, 2024 | Monday, Aug. 5, 2024 | +| v2.12 | Monday, Jun. 17, 2024 | Monday, Aug. 5, 2024 | [Ishita Sequeira](https://github.com/ishitasequeira) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/19063) | +| v2.13 | Monday, Sep. 16, 2024 | Monday, Nov. 4, 2024 | [Regina Voloshin](https://github.com/reggie-k) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/19513) | +| v2.14 | Monday, Dec. 16, 2024 | Monday, Feb. 3, 2025 | | | | +| v2.15 | Monday, Mar. 17, 2025 | Monday, May 5, 2025 | | | | Actual release dates might differ from the plan by a few days. diff --git a/docs/faq.md b/docs/faq.md index 9dcbc7e8f1e0e..e98ca95f556b6 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -323,3 +323,46 @@ You can config your secret provider to generate Kubernetes secret accordingly. Doing a hard refresh (ignoring the cached error) can overcome transient issues. But if there's an ongoing reason manifest generation is failing, a hard refresh will not help. Instead, try searching the repo-server logs for the app name in order to identify the error that is causing manifest generation to fail. + +## How do I fix `field not declared in schema`? + +For certain features, Argo CD relies on a static (hard-coded) set of schemas for built-in Kubernetes resource types. + +If your manifests use fields which are not present in the hard-coded schemas, you may get an error like `field not +declared in schema`. + +The schema version is based on the Kubernetes libraries version that Argo CD is built against. To find the Kubernetes +version for a given Argo CD version, navigate to this page, where `X.Y.Z` is the Argo CD version: + +``` +https://github.com/argoproj/argo-cd/blob/vX.Y.Z/go.mod +``` + +Then find the Kubernetes version in the `go.mod` file. For example, for Argo CD v2.11.4, the Kubernetes libraries +version is v0.26.11 + +``` + k8s.io/api => k8s.io/api v0.26.11 +``` + +### How do I fix the issue? + +To completely resolve the issue, upgrade to an Argo CD version which contains a static schema supporting all the needed +fields. + +### How do I work around the issue? + +As mentioned above, only certain Argo CD features rely on the static schema: 1) `ignoreDifferences` with +`managedFieldManagers`, 2) server-side apply _without_ server-side diff, and 3) server-side diff _with_ mutation +webhooks. + +If you can avoid using these features, you can avoid triggering the error. The options are as follows: + +1. **Disable `ignoreDifferences` which have `managedFieldsManagers`**: see [diffing docs](user-guide/diffing.md) for + details about that feature. Removing this config could cause undesired diffing behavior. +2. **Disable server-side apply**: see [server-side apply docs](user-guide/sync-options.md#server-side-apply) for details about that + feature. Disabling server-side apply may have undesired effects on sync behavior. Note that you can bypass this issue + if you use server-side diff and [exclude mutation webhooks from the diff](user-guide/diff-strategies.md#mutation-webhooks). + Excluding mutation webhooks from the diff could cause undesired diffing behavior. +3. **Disable mutation webhooks when using server-side diff**: see [server-side diff docs](user-guide/diff-strategies.md#mutation-webhooks) + for details about that feature. Disabling mutation webhooks may have undesired effects on sync behavior. diff --git a/docs/operator-manual/app-any-namespace.md b/docs/operator-manual/app-any-namespace.md index dfd24f75b65f3..09df16e061314 100644 --- a/docs/operator-manual/app-any-namespace.md +++ b/docs/operator-manual/app-any-namespace.md @@ -42,8 +42,11 @@ In order for an application to be managed and reconciled outside the Argo CD's c In order to enable this feature, the Argo CD administrator must reconfigure the `argocd-server` and `argocd-application-controller` workloads to add the `--application-namespaces` parameter to the container's startup command. -The `--application-namespaces` parameter takes a comma-separated list of namespaces where `Applications` are to be allowed in. Each entry of the list supports shell-style wildcards such as `*`, so for example the entry `app-team-*` would match `app-team-one` and `app-team-two`. To enable all namespaces on the cluster where Argo CD is running on, you can just specify `*`, i.e. `--application-namespaces=*`. +The `--application-namespaces` parameter takes a comma-separated list of namespaces where `Applications` are to be allowed in. Each entry of the list supports: +- shell-style wildcards such as `*`, so for example the entry `app-team-*` would match `app-team-one` and `app-team-two`. To enable all namespaces on the cluster where Argo CD is running on, you can just specify `*`, i.e. `--application-namespaces=*`. +- regex, requires wrapping the string in ```/```, example to allow all namespaces except a particular one: ```/^((?!not-allowed).)*$/```. + The startup parameters for both, the `argocd-server` and the `argocd-application-controller` can also be conveniently set up and kept in sync by specifying the `application.namespaces` settings in the `argocd-cmd-params-cm` ConfigMap _instead_ of changing the manifests for the respective workloads. For example: ```yaml diff --git a/docs/operator-manual/app-sync-using-impersonation.md b/docs/operator-manual/app-sync-using-impersonation.md new file mode 100644 index 0000000000000..9314f0b376b8e --- /dev/null +++ b/docs/operator-manual/app-sync-using-impersonation.md @@ -0,0 +1,131 @@ +# Application Sync using impersonation + +!!! warning "Alpha Feature" + This is an experimental, alpha-quality feature that allows you to control the service account used for the sync operation. The configured service account, could have lesser privileges required for creating resources compared to the highly privileged access required for the control plane operations. + +!!! warning + Please read this documentation carefully before you enable this feature. Misconfiguration could lead to potential security issues. + +## Introduction + +Argo CD supports syncing `Application` resources using the same service account used for its control plane operations. This feature enables users to decouple service account used for application sync from the service account used for control plane operations. + +By default, application syncs in Argo CD have the same privileges as the Argo CD control plane. As a consequence, in a multi-tenant setup, the Argo CD control plane privileges needs to match the tenant that needs the highest privileges. As an example, if an Argo CD instance has 10 Applications and only one of them requires admin privileges, then the Argo CD control plane must have admin privileges in order to be able to sync that one Application. This provides an opportunity for malicious tenants to gain admin level access. Argo CD provides a multi-tenancy model to restrict what each `Application` is authorized to do using `AppProjects`, however it is not secure enough and if Argo CD is compromised, attackers will easily gain `cluster-admin` access to the cluster. + +Some manual steps will need to be performed by the Argo CD administrator in order to enable this feature, as it is disabled by default. + +!!! note + This feature is considered alpha as of now. Some of the implementation details may change over the course of time until it is promoted to a stable status. We will be happy if early adopters use this feature and provide us with bug reports and feedback. + +### What is Impersonation + +Impersonation is a feature in Kubernetes and enabled in the `kubectl` CLI client, using which, a user can act as another user through impersonation headers. For example, an admin could use this feature to debug an authorization policy by temporarily impersonating another user and seeing if a request was denied. + +Impersonation requests first authenticate as the requesting user, then switch to the impersonated user info. + +## Prerequisites + +In a multi-team/multi-tenant environment, a team/tenant is typically granted access to a target namespace to self-manage their kubernetes resources in a declarative way. +A typical tenant onboarding process looks like below: +1. The platform admin creates a tenant namespace and the service account to be used for creating the resources is also created in the same tenant namespace. +2. The platform admin creates one or more Role(s) to manage kubernetes resources in the tenant namespace +3. The platform admin creates one or more RoleBinding(s) to map the service account to the role(s) created in the previous steps. +4. The platform admin can choose to use either the [apps-in-any-namespace](./app-any-namespace.md) feature or provide access to tenants to create applications in the ArgoCD control plane namespace. +5. If the platform admin chooses apps-in-any-namespace feature, tenants can self-service their Argo applications in their respective tenant namespaces and no additional access needs to be provided for the control plane namespace. + +## Implementation details + +### Overview + +In order for an application to use a different service account for the application sync operation, the following steps needs to be performed: + +1. The impersonation feature flag should be enabled. Please refer the steps provided in [Enable application sync with impersonation feature](#enable-application-sync-with-impersonation-feature) + +2. The `AppProject` referenced by the `.spec.project` field of the `Application` must have the `DestinationServiceAccounts` mapping the destination server and namespace to a service account to be used for the sync operation. Please refer the steps provided in [Configuring destination service accounts](#configuring-destination-service-accounts) + + +### Enable application sync with impersonation feature + +In order to enable this feature, the Argo CD administrator must reconfigure the `application.sync.impersonation.enabled` settings in the `argocd-cm` ConfigMap as below: + +```yaml +data: + application.sync.impersonation.enabled: "true" +``` + +### Disable application sync with impersonation feature + +In order to disable this feature, the Argo CD administrator must reconfigure the `application.sync.impersonation.enabled` settings in the `argocd-cm` ConfigMap as below: + +```yaml +data: + application.sync.impersonation.enabled: "false" +``` + +!!! note + This feature is disabled by default. + +!!! note + This feature can be enabled/disabled only at the system level and once enabled/disabled it is applicable to all Applications managed by ArgoCD. + +## Configuring destination service accounts + +Destination service accounts can be added to the `AppProject` under `.spec.destinationServiceAccounts`. Specify the target destination `server` and `namespace` and provide the service account to be used for the sync operation using `defaultServiceAccount` field. Applications that refer this `AppProject` will use the corresponding service account configured for its destination. + +During the application sync operation, the controller loops through the available `destinationServiceAccounts` in the mapped `AppProject` and tries to find a matching candidate. If there are multiple matches for a destination server and namespace combination, then the first valid match will be considered. If there are no matches, then an error is reported during the sync operation. In order to avoid such sync errors, it is highly recommended that a valid service account may be configured as a catch-all configuration, for all target destinations and kept in lowest order of priority. + +It is possible to specify service accounts along with its namespace. eg: `tenant1-ns:guestbook-deployer`. If no namespace is provided for the service account, then the Application's `spec.destination.namespace` will be used. If no namespace is provided for the service account and the optional `spec.destination.namespace` field is also not provided in the `Application`, then the Application's namespace will be used. + +`DestinationServiceAccounts` associated to a `AppProject` can be created and managed, either declaratively or through the Argo CD API (e.g. using the CLI, the web UI, the REST API, etc). + +### Using declarative yaml + +For declaratively configuring destination service accounts, create an yaml file for the `AppProject` as below and apply the changes using `kubectl apply` command. + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: my-project + namespace: argocd +spec: + description: Example Project + # Allow manifests to deploy from any Git repos + sourceRepos: + - '*' + destinations: + - * + destinationServiceAccounts: + - server: https://kubernetes.default.svc + namespace: guestbook + defaultServiceAccount: guestbook-deployer + - server: https://kubernetes.default.svc + namespace: guestbook-dev + defaultServiceAccount: guestbook-dev-deployer + - server: https://kubernetes.default.svc + namespace: guestbook-stage + defaultServiceAccount: guestbook-stage-deployer + - server: https://kubernetes.default.svc # catch-all configuration + namespace: '*' + defaultServiceAccount: default +``` + +### Using the CLI + +Destination service accounts can be added to an `AppProject` using the ArgoCD CLI. + +For example, to add a destination service account for `in-cluster` and `guestbook` namespace, you can use the following CLI command: + +```shell +argocd proj add-destination-service-account my-project https://kubernetes.default.svc guestbook guestbook-sa +``` + +Likewise, to remove the destination service account from an `AppProject`, you can use the following CLI command: + +```shell +argocd proj remove-destination-service-account my-project https://kubernetes.default.svc guestbook +``` + +### Using the UI + +Similar to the CLI, you can add destination service account when creating or updating an `AppProject` from the UI diff --git a/docs/operator-manual/application.yaml b/docs/operator-manual/application.yaml index 864a293ce6890..051ca6a1755e3 100644 --- a/docs/operator-manual/application.yaml +++ b/docs/operator-manual/application.yaml @@ -90,6 +90,19 @@ spec: # and decide which Helm binary to use automatically. This field can be either 'v2' or 'v3'. version: v2 + # You can specify the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses + # the Kubernetes version of the target cluster. The value must be semver formatted. Do not prefix with `v`. + kubeVersion: 1.30.0 + + # You can specify 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: + - traefik.io/v1alpha1/TLSOption + - v1/Service + + # Optional namespace to template with. If left empty, defaults to the app's destination namespace. + namespace: custom-namespace + # kustomize specific config kustomize: # Optional kustomize version. Note: version must be configured in argocd-cm ConfigMap @@ -103,6 +116,8 @@ spec: beep: boop-${ARGOCD_APP_REVISION} # Toggle which enables/disables env variables substitution in commonAnnotations commonAnnotationsEnvsubst: true + forceCommonLabels: false + forceCommonAnnotations: false images: - gcr.io/heptio-images/ks-guestbook-demo:0.2 - my-app=gcr.io/my-repo/my-app:0.1 @@ -110,6 +125,27 @@ spec: replicas: - name: kustomize-guestbook-ui count: 4 + components: + - ../component # relative to the kustomization.yaml (`source.path`). + patches: + - target: + kind: Deployment + name: guestbook-ui + patch: |- + - op: add # Add new element to manifest + path: /spec/template/spec/nodeSelector/ + value: + env: "pro" + + # You can specify the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses + # the Kubernetes version of the target cluster. The value must be semver formatted. Do not prefix with `v`. + kubeVersion: 1.30.0 + + # You can specify 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: + - traefik.io/v1alpha1/TLSOption + - v1/Service # directory directory: diff --git a/docs/operator-manual/applicationset/Appset-Any-Namespace.md b/docs/operator-manual/applicationset/Appset-Any-Namespace.md index 4e28bc3a8172d..f6124f098cb6d 100644 --- a/docs/operator-manual/applicationset/Appset-Any-Namespace.md +++ b/docs/operator-manual/applicationset/Appset-Any-Namespace.md @@ -25,7 +25,9 @@ This feature can only be enabled and used when your Argo CD ApplicationSet contr ### SCM Providers secrets consideration -By allowing ApplicationSet in any namespace you must be aware that any secrets can be exfiltrated using `scmProvider` or `pullRequest` generators. +By allowing ApplicationSet in any namespace you must be aware that any secrets can be exfiltrated using `scmProvider` or `pullRequest` generators. This means if ApplicationSet controller is configured to allow namespace `appNs` and some user is allowed to create +an ApplicationSet in `appNs` namespace, then the user can install a malicious Pod into the `appNs` namespace as described below +and read out the content of the secret indirectly, thus exfiltrating the secret value. Here is an example: @@ -34,6 +36,7 @@ apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: myapps + namespace: appNs spec: goTemplate: true goTemplateOptions: ["missingkey=error"] @@ -43,7 +46,7 @@ spec: # The Gitea owner to scan. owner: myorg # With this malicious setting, user can send all request to a Pod that will log incoming requests including headers with tokens - api: http://my-service.my-namespace.svc.cluster.local + api: http://my-service.appNs.svc.cluster.local # If true, scan every branch of every repository. If false, scan only the default branch. Defaults to false. allBranches: true # By changing this token reference, user can exfiltrate any secrets @@ -53,7 +56,7 @@ spec: template: ``` -Therefore administrator must restrict the urls of the allowed SCM Providers (example: `https://git.mydomain.com/,https://gitlab.mydomain.com/`) by setting the environment variable `ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS` to argocd-cmd-params-cm `applicationsetcontroller.allowed.scm.providers`. If another url is used, it will be rejected by the applicationset controller. +In order to prevent the scenario above administrator must restrict the urls of the allowed SCM Providers (example: `https://git.mydomain.com/,https://gitlab.mydomain.com/`) by setting the environment variable `ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS` to argocd-cmd-params-cm `applicationsetcontroller.allowed.scm.providers`. If another url is used, it will be rejected by the applicationset controller. For example: ```yaml diff --git a/docs/operator-manual/applicationset/Controlling-Resource-Modification.md b/docs/operator-manual/applicationset/Controlling-Resource-Modification.md index ae65fa3462e5b..1636d348cb009 100644 --- a/docs/operator-manual/applicationset/Controlling-Resource-Modification.md +++ b/docs/operator-manual/applicationset/Controlling-Resource-Modification.md @@ -343,3 +343,15 @@ metadata: data: applicationsetcontroller.log.level: debug ``` + +## Previewing changes + +To preview changes that the ApplicationSet controller would make to Applications, you can create the AppSet in dry-run +mode. This works whether the AppSet already exists or not. + +```shell +argocd appset create --dry-run ./appset.yaml -o json | jq -r '.status.resources[].name' +``` + +The dry-run will populate the returned ApplicationSet's status with the Applications which would be managed with the +given config. You can compare to the existing Applications to see what would change. diff --git a/docs/operator-manual/applicationset/Generators-Git.md b/docs/operator-manual/applicationset/Generators-Git.md index 7e4aa5fdb1c24..19564970749a6 100644 --- a/docs/operator-manual/applicationset/Generators-Git.md +++ b/docs/operator-manual/applicationset/Generators-Git.md @@ -7,6 +7,8 @@ The Git generator contains two subtypes: the Git directory generator, and Git fi If the `project` field in your ApplicationSet is templated, developers may be able to create Applications under Projects with excessive permissions. For ApplicationSets with a templated `project` field, [the source of truth _must_ be controlled by admins](./Security.md#templated-project-field) - in the case of git generators, PRs must require admin approval. + - Git generator does not support Signature Verification For ApplicationSets with a templated `project` field. + ## Git Generator: Directories @@ -326,7 +328,7 @@ As with other generators, clusters *must* already be defined within Argo CD, in In addition to the flattened key/value pairs from the configuration file, the following generator parameters are provided: - `{{.path.path}}`: The path to the directory containing matching configuration file within the Git repository. Example: `/clusters/clusterA`, if the config file was `/clusters/clusterA/config.json` -- `{{index .path n}}`: The path to the matching configuration file within the Git repository, split into array elements (`n` - array index). Example: `index .path 0: clusters`, `index .path 1: clusterA` +- `{{index .path.segments n}}`: The path to the matching configuration file within the Git repository, split into array elements (`n` - array index). Example: `index .path.segments 0: clusters`, `index .path.segments 1: clusterA` - `{{.path.basename}}`: Basename of the path to the directory containing the configuration file (e.g. `clusterA`, with the above example.) - `{{.path.basenameNormalized}}`: This field is the same as `.path.basename` with unsupported characters replaced with `-` (e.g. a `path` of `/directory/directory_2`, and `.path.basename` of `directory_2` would produce `directory-2` here). - `{{.path.filename}}`: The matched filename. e.g., `config.json` in the above example. @@ -360,7 +362,7 @@ spec: files: - path: "applicationset/examples/git-generator-files-discovery/cluster-config/**/config.json" values: - base_dir: "{{index .path 0}}/{{index .path 1}}/{{index .path 2}}" + base_dir: "{{index .path.segments 0}}/{{index .path.segments 1}}/{{index .path.segments 2}}" template: metadata: name: '{{.cluster.name}}-guestbook' diff --git a/docs/operator-manual/applicationset/Generators-Matrix.md b/docs/operator-manual/applicationset/Generators-Matrix.md index 0396b8c0e06d3..91b1bb3abb778 100644 --- a/docs/operator-manual/applicationset/Generators-Matrix.md +++ b/docs/operator-manual/applicationset/Generators-Matrix.md @@ -22,8 +22,8 @@ As an example, imagine that we have two clusters: And our application YAMLs are defined in a Git repository: -- Argo Workflows controller (examples/git-generator-directory/cluster-addons/argo-workflows) -- Prometheus operator (/examples/git-generator-directory/cluster-addons/prometheus-operator) +- [Argo Workflows controller](https://github.com/argoproj/argo-cd/tree/master/applicationset/examples/git-generator-directory/cluster-addons/argo-workflows) +- [Prometheus operator](https://github.com/argoproj/argo-cd/tree/master/applicationset/examples/git-generator-directory/cluster-addons/prometheus-operator) Our goal is to deploy both applications onto both clusters, and, more generally, in the future to automatically deploy new applications in the Git repository, and to new clusters defined within Argo CD, as well. diff --git a/docs/operator-manual/applicationset/Generators-Post-Selector.md b/docs/operator-manual/applicationset/Generators-Post-Selector.md index bcfe7f280ce8d..5a07cf1db425c 100644 --- a/docs/operator-manual/applicationset/Generators-Post-Selector.md +++ b/docs/operator-manual/applicationset/Generators-Post-Selector.md @@ -1,6 +1,6 @@ # Post Selector all generators -The `selector` field on a generator allows an `ApplciationSet` to post-filter results using [the Kubernetes common labelSelector format](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) and the generated values. +The `selector` field on a generator allows an `ApplicationSet` to post-filter results using [the Kubernetes common labelSelector format](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) and the generated values. `matchLabels` is a map of `{key,value}` pairs. This `list` generator generates a set of two `Applications`, which is then filtered using `matchLabels` to only the list element containing the key `env` with value `staging`: ``` diff --git a/docs/operator-manual/applicationset/Generators-Pull-Request.md b/docs/operator-manual/applicationset/Generators-Pull-Request.md index a213c1dbb23bb..2e6dffaaf5f32 100644 --- a/docs/operator-manual/applicationset/Generators-Pull-Request.md +++ b/docs/operator-manual/applicationset/Generators-Pull-Request.md @@ -99,6 +99,10 @@ spec: pullRequestState: opened # If true, skips validating the SCM provider's TLS certificate - useful for self-signed certificates. insecure: false + # Reference to a ConfigMap containing trusted CA certs - useful for self-signed certificates. (optional) + caRef: + configMapName: argocd-tls-certs-cm + key: gitlab-ca requeueAfterSeconds: 1800 template: # ... @@ -110,6 +114,7 @@ spec: * `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. 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. As a preferable alternative to setting `insecure` to true, you can configure self-signed TLS certificates for Gitlab by [mounting self-signed certificate to the applicationset controller](./Generators-SCM-Provider.md#self-signed-tls-certificates). @@ -170,7 +175,8 @@ spec: repo: myrepository # URL of the Bitbucket Server. Required. api: https://mycompany.bitbucket.org - # Credentials for Basic authentication. Required for private repositories. + # Credentials for Basic authentication (App Password). Either basicAuth or bearerToken + # authentication is required to access private repositories basicAuth: # The username to authenticate with username: myuser @@ -178,6 +184,19 @@ spec: passwordRef: secretName: mypassword key: password + # Credentials for Bearer Token (App Token) authentication. Either basicAuth or bearerToken + # authentication is required to access private repositories + bearerToken: + # Reference to a Secret containing the bearer token. + tokenRef: + secretName: repotoken + key: token + # If true, skips validating the SCM provider's TLS certificate - useful for self-signed certificates. + insecure: true + # Reference to a ConfigMap containing trusted CA certs - useful for self-signed certificates. (optional) + caRef: + configMapName: argocd-tls-certs-cm + key: bitbucket-ca # Labels are not supported by Bitbucket Server, so filtering by label is not possible. # Filter PRs using the source branch name. (optional) filters: @@ -195,6 +214,13 @@ If you want to access a private repository, you must also provide the credential * `username`: The username to authenticate with. It only needs read access to the relevant repo. * `passwordRef`: A `Secret` name and key containing the password or personal access token to use for requests. +In case of Bitbucket App Token, go with `bearerToken` section. +* `tokenRef`: A `Secret` name and key containing the app token to use for requests. + +In case self-signed BitBucket Server certificates, the following options can be usefully: +* `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 BitBucket server certificates to trust - useful for self-signed TLS certificates. Possibly reference the ArgoCD CM holding the trusted certs. + ## Bitbucket Cloud Fetch pull requests from a repo hosted on a Bitbucket Cloud. @@ -228,6 +254,7 @@ spec: # Credentials for Bearer Token (App Token) authentication. Either basicAuth or bearerToken # authentication is required to access private repositories bearerToken: + # Reference to a Secret containing the bearer token. tokenRef: secretName: repotoken key: token @@ -351,7 +378,7 @@ spec: helm: parameters: - name: "image.tag" - value: "pull-{{.head_sha}}" + value: "pull-{{.author}}-{{.head_sha}}" project: "my-project" destination: server: https://kubernetes.default.svc @@ -384,7 +411,7 @@ spec: commonLabels: app.kubernetes.io/instance: '{{.branch}}-{{.number}}' images: - - 'ghcr.io/myorg/myrepo:{{.head_sha}}' + - 'ghcr.io/myorg/myrepo:{{.author}}-{{.head_sha}}' project: "my-project" destination: server: https://kubernetes.default.svc @@ -392,6 +419,7 @@ spec: ``` * `number`: The ID number of the pull request. +* `title`: The title of the pull request. * `branch`: The name of the branch of the pull request head. * `branch_slug`: The branch name will be cleaned to be conform to the DNS label standard as defined in [RFC 1123](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-label-names), and truncated to 50 characters to give room to append/suffix-ing it with 13 more characters. * `target_branch`: The name of the target branch of the pull request. @@ -400,6 +428,7 @@ spec: * `head_short_sha`: This is the short SHA of the head of the pull request (8 characters long or the length of the head SHA if it's shorter). * `head_short_sha_7`: This is the short SHA of the head of the pull request (7 characters long or the length of the head SHA if it's shorter). * `labels`: The array of pull request labels. (Supported only for Go Template ApplicationSet manifests.) +* `author`: The author/creator of the pull request. ## Webhook Configuration diff --git a/docs/operator-manual/applicationset/Generators-SCM-Provider.md b/docs/operator-manual/applicationset/Generators-SCM-Provider.md index 40c8e552fe573..d48c07403573a 100644 --- a/docs/operator-manual/applicationset/Generators-SCM-Provider.md +++ b/docs/operator-manual/applicationset/Generators-SCM-Provider.md @@ -98,6 +98,10 @@ spec: key: token # If true, skips validating the SCM provider's TLS certificate - useful for self-signed certificates. insecure: false + # Reference to a ConfigMap containing trusted CA certs - useful for self-signed certificates. (optional) + caRef: + configMapName: argocd-tls-certs-cm + key: gitlab-ca template: # ... ``` @@ -110,6 +114,7 @@ spec: * `topic`: filter projects by topic. A single topic is supported by Gitlab API. Defaults to "" (all topics). * `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. * `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. For label filtering, the repository topics are used. @@ -178,7 +183,8 @@ spec: api: https://mycompany.bitbucket.org # If true, scan every branch of every repository. If false, scan only the default branch. Defaults to false. allBranches: true - # Credentials for Basic authentication. Required for private repositories. + # Credentials for Basic authentication (App Password). Either basicAuth or bearerToken + # authentication is required to access private repositories basicAuth: # The username to authenticate with username: myuser @@ -186,6 +192,19 @@ spec: passwordRef: secretName: mypassword key: password + # Credentials for Bearer Token (App Token) authentication. Either basicAuth or bearerToken + # authentication is required to access private repositories + bearerToken: + # Reference to a Secret containing the bearer token. + tokenRef: + secretName: repotoken + key: token + # If true, skips validating the SCM provider's TLS certificate - useful for self-signed certificates. + insecure: true + # Reference to a ConfigMap containing trusted CA certs - useful for self-signed certificates. (optional) + caRef: + configMapName: argocd-tls-certs-cm + key: bitbucket-ca # Support for filtering by labels is TODO. Bitbucket server labels are not supported for PRs, but they are for repos template: # ... @@ -199,6 +218,13 @@ If you want to access a private repository, you must also provide the credential * `username`: The username to authenticate with. It only needs read access to the relevant repo. * `passwordRef`: A `Secret` name and key containing the password or personal access token to use for requests. +In case of Bitbucket App Token, go with `bearerToken` section. +* `tokenRef`: A `Secret` name and key containing the app token to use for requests. + +In case self-signed BitBucket Server certificates, the following options can be usefully: +* `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 BitBucket server certificates to trust - useful for self-signed TLS certificates. Possibly reference the ArgoCD CM holding the trusted certs. + Available clone protocols are `ssh` and `https`. ## Azure DevOps diff --git a/docs/operator-manual/applicationset/GoTemplate.md b/docs/operator-manual/applicationset/GoTemplate.md index 55ecfc171e517..022e5f6584238 100644 --- a/docs/operator-manual/applicationset/GoTemplate.md +++ b/docs/operator-manual/applicationset/GoTemplate.md @@ -100,6 +100,17 @@ possible with Go text templates: - name: throw-away value: "{{end}}" +- Signature verification is not supported for the templated `project` field when using the Git generator. + + ::yaml + apiVersion: argoproj.io/v1alpha1 + kind: ApplicationSet + spec: + goTemplate: true + template: + spec: + project: {{.project}} + ## Migration guide diff --git a/docs/operator-manual/applicationset/Template.md b/docs/operator-manual/applicationset/Template.md index d96fb39252fed..6bc6f24dc0310 100644 --- a/docs/operator-manual/applicationset/Template.md +++ b/docs/operator-manual/applicationset/Template.md @@ -9,21 +9,24 @@ ApplicationSet is using [fasttemplate](https://github.com/valyala/fasttemplate) An Argo CD Application is created by combining the parameters from the generator with fields of the template (via `{{values}}`), and from that a concrete `Application` resource is produced and applied to the cluster. Here is the template subfield from a Cluster generator: + ```yaml # (...) template: metadata: - name: '{{cluster}}-guestbook' + name: '{{ .nameNormalized }}-guestbook' spec: source: repoURL: https://github.com/infra-team/cluster-deployments.git targetRevision: HEAD - path: guestbook/{{cluster}} + path: guestbook/{{ .nameNormalized }} destination: - server: '{{url}}' + server: '{{ .server }}' namespace: guestbook ``` +For details on all available parameters (like `.name`, `.nameNormalized`, etc.) please refer to the [Cluster Generator docs](./Generators-Cluster.md). + The template subfields correspond directly to [the spec of an Argo CD `Application` resource](../../declarative-setup/#applications): - `project` refers to the [Argo CD Project](../../user-guide/projects.md) in use (`default` may be used here to utilize the default Argo CD Project) @@ -40,6 +43,7 @@ Note: - Referenced clusters must already be defined in Argo CD, for the ApplicationSet controller to use them - Only **one** of `name` or `server` may be specified: if both are specified, an error is returned. +- Signature Verification does not work with the templated `project` field when using git generator. The `metadata` field of template may also be used to set an Application `name`, or to add labels or annotations to the Application. @@ -53,7 +57,7 @@ template as a Helm string literal. For example: ```yaml metadata: - name: '{{`{{.cluster}}`}}-guestbook' + name: '{{`{{ .nameNormalized }}`}}-guestbook' ``` This _only_ applies if you use Helm to deploy your ApplicationSet resources. @@ -88,12 +92,12 @@ spec: targetRevision: HEAD repoURL: https://github.com/argoproj/argo-cd.git # New path value is generated here: - path: 'applicationset/examples/template-override/{{cluster}}-override' + path: 'applicationset/examples/template-override/{{ .nameNormalized }}-override' destination: {} template: metadata: - name: '{{cluster}}-guestbook' + name: '{{ .nameNormalized }}-guestbook' spec: project: "default" source: @@ -102,7 +106,7 @@ spec: # This 'default' value is not used: it is replaced by the generator's template path, above path: applicationset/examples/template-override/default destination: - server: '{{url}}' + server: '{{ .server }}' namespace: guestbook ``` (*The full example can be found [here](https://github.com/argoproj/argo-cd/tree/master/applicationset/examples/template-override).*) @@ -140,15 +144,15 @@ spec: - values.debug.yaml template: metadata: - name: '{{.cluster}}-deployment' + name: '{{ .nameNormalized }}-deployment' spec: project: "default" source: repoURL: https://github.com/infra-team/cluster-deployments.git targetRevision: HEAD - path: guestbook/{{ .cluster }} + path: guestbook/{{ .nameNormalized }} destination: - server: '{{.url}}' + server: '{{ .server }}' namespace: guestbook templatePatch: | spec: diff --git a/docs/operator-manual/argocd-cm.yaml b/docs/operator-manual/argocd-cm.yaml index 88daa86c64334..a8d3be645bcfb 100644 --- a/docs/operator-manual/argocd-cm.yaml +++ b/docs/operator-manual/argocd-cm.yaml @@ -10,6 +10,10 @@ data: # Argo CD's externally facing base URL (optional). Required when configuring SSO url: https://argo-cd-demo.argoproj.io + # Additional externally facing base URLs (optional) + additionalUrls: | + - https://argo-cd-demo2.argoproj.io + # Enables application status badge feature statusbadge.enabled: "true" @@ -221,6 +225,16 @@ data: # An optional comma-separated list of metadata.labels to observe in the UI. resource.customLabels: tier + # An optional comma-separated list of metadata.labels keys to add to Kubernetes events generated for Applications. + # The keys are compared against the Application and its AppProject. If matched, + # the corresponding labels are 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. Supports wildcards. + resource.includeEventLabelKeys: team,env* + # 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 @@ -237,9 +251,9 @@ data: # A set of settings that allow enabling or disabling the config management tool. # If unset, each defaults to "true". - kustomize.enabled: true - jsonnet.enabled: true - helm.enabled: true + kustomize.enabled: "true" + jsonnet.enabled: "true" + helm.enabled: "true" # Build options/parameters to use with `kustomize build` (optional) kustomize.buildOptions: --load_restrictor none @@ -355,7 +369,7 @@ data: - url: https://mycompany.splunk.com?search={{.spec.destination.namespace}} title: Splunk # conditionally show link e.g. for specific project - # github.com/antonmedv/expr is used for evaluation of conditions + # github.com/expr-lang/expr is used for evaluation of conditions - url: https://mycompany.splunk.com?search={{.spec.destination.namespace}} title: Splunk if: spec.project == "default" @@ -410,3 +424,8 @@ data: cluster: name: some-cluster server: https://some-cluster + # The maximum size of the payload that can be sent to the webhook server. + webhook.maxPayloadSizeMB: 1024 + + # application.sync.impersonation.enabled indicates whether the application sync can be decoupled from control plane service account using impersonation. + application.sync.impersonation.enabled: "false" diff --git a/docs/operator-manual/argocd-cmd-params-cm.yaml b/docs/operator-manual/argocd-cmd-params-cm.yaml index ae2072a18fb53..348677b1cb065 100644 --- a/docs/operator-manual/argocd-cmd-params-cm.yaml +++ b/docs/operator-manual/argocd-cmd-params-cm.yaml @@ -72,6 +72,8 @@ data: # Diff calculation will be done by running a server side apply dryrun (when # diff cache is unavailable). controller.diff.server.side: "false" + # Enables profile endpoint on the internal metrics port + controller.profile.enabled: "false" ## Server properties # Listen on given address for incoming connections (default "0.0.0.0") @@ -93,6 +95,8 @@ data: # Semicolon-separated list of content types allowed on non-GET requests. Set an empty string to allow all. Be aware # that allowing content types besides application/json may make your API more vulnerable to CSRF attacks. server.api.content.types: "application/json" + # Number of webhook requests processed concurrently (default 50) + server.webhook.parallelism.limit: "50" # Set the logging format. One of: text|json (default "text") server.log.format: "text" @@ -134,6 +138,8 @@ data: server.default.cache.expiration: "24h0m0s" # Enable the experimental proxy extension feature server.enable.proxy.extension: "false" + # Enables profile endpoint on the internal metrics port + server.profile.enabled: "false" ## Repo-server properties # Listen on given address for incoming connections (default "0.0.0.0") @@ -165,6 +171,8 @@ data: reposerver.max.combined.directory.manifests.size: '10M' # Paths to be excluded from the tarball streamed to plugins. Separate with ; reposerver.plugin.tar.exclusions: "" + # Enable the repo server to use the 'argocd.argoproj.io/manifest-generate-paths' annotation to guide manifest generation. + reposerver.plugin.use.manifest.generate.paths: "false" # Allow repositories to contain symlinks that leave the boundaries of the repository. # Changing this to "true" will not allow _all_ out-of-bounds symlinks. Those will still be blocked for things like values # files in Helm charts. But symlinks which are not explicitly blocked by other checks will be allowed. @@ -182,14 +190,32 @@ data: # Include hidden directories from Git reposerver.include.hidden.directories: "false" + + # 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 dexserver.disable.tls: "false" ## ApplicationSet Controller Properties # Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager. applicationsetcontroller.enable.leader.election: "false" - # "Modify how application is synced between the generator and the cluster. Default is 'sync' (create & update & delete), options: 'create-only', 'create-update' (no deletion), 'create-delete' (no update)" - applicationsetcontroller.policy: "sync" + # "Modify how application is synced between the generator and the cluster. Default is '' (empty), which means AppSets + # will default to the 'sync' policy (create & update & delete). Explicitly setting the value prevents AppSet-level + # policy overrides unless overrides are explicitly enabled (see option below). Explicit options are: + # 'create-only', 'create-update' (no deletion), 'create-delete' (no update)" + applicationsetcontroller.policy: "" + # If applicationsetcontroller.policy is empty, this flag has no effect. If applicationsetcontroller.policy is set, + # this flag controls whether the policy set in the controller can be overridden by the ApplicationSet resource + # (i.e. the spec.syncPlicy.applicationSync field). Set it to "true" to allow overrides. "" or "false" will disable + # overrides. (default "") + applicationsetcontroller.enable.policy.override: "" + # Max concurrent reconciliation limit for the controller (default 10) + applicationsetcontroller.concurrent.reconciliations.max: "10" + # Enable new globbing in Git files generator (default "false") + # See https://argo-cd.readthedocs.io/en/stable/operator-manual/applicationset/Generators-Git-File-Globbing/ + applicationsetcontroller.enable.new.git.file.globbing: "false" # Print debug logs. Takes precedence over loglevel applicationsetcontroller.debug: "false" # Set the logging format. One of: text|json (default "text") @@ -213,6 +239,8 @@ data: applicationsetcontroller.allowed.scm.providers: "https://git.example.com/,https://gitlab.example.com/" # To disable SCM providers entirely (i.e. disable the SCM and PR generators), set this to "false". Default is "true". applicationsetcontroller.enable.scm.providers: "false" + # Number of webhook requests processed concurrently (default 50) + applicationsetcontroller.webhook.parallelism.limit: "50" ## Argo CD Notifications Controller Properties # Set the logging level. One of: debug|info|warn|error (default "info") @@ -221,3 +249,5 @@ data: 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 + notificationscontroller.repo.server.plaintext: "false" diff --git a/docs/operator-manual/argocd-repositories.yaml b/docs/operator-manual/argocd-repositories.yaml index b6aa0715c389d..8f48429ebd60b 100644 --- a/docs/operator-manual/argocd-repositories.yaml +++ b/docs/operator-manual/argocd-repositories.yaml @@ -12,6 +12,7 @@ stringData: url: https://github.com/argoproj/argocd-example-apps password: my-password username: my-username + project: my-project insecure: "true" # Ignore validity of server's TLS certificate. Defaults to "false" forceHttpBasicAuth: "true" # Skip auth method negotiation and force usage of HTTP basic auth. Defaults to "false" enableLfs: "true" # Enable git-lfs for this repository. Defaults to "false" @@ -42,6 +43,7 @@ metadata: stringData: url: https://storage.googleapis.com/istio-prerelease/daily-build/master-latest-daily/charts name: istio.io + project: my-project type: helm --- apiVersion: v1 diff --git a/docs/operator-manual/cluster-bootstrapping.md b/docs/operator-manual/cluster-bootstrapping.md index 7a43800da2478..9a06098db8670 100644 --- a/docs/operator-manual/cluster-bootstrapping.md +++ b/docs/operator-manual/cluster-bootstrapping.md @@ -119,4 +119,29 @@ metadata: - resources-finalizer.argocd.argoproj.io spec: ... -``` +``` + +### Ignoring differences in child applications + +To allow changes in child apps without triggering an out-of-sync status, or modification for debugging etc, the app of apps pattern works with [diff customization](../user-guide/diffing/). The example below shows how to ignore changes to syncPolicy and other common values. + +```yaml +spec: + ... + syncPolicy: + ... + syncOptions: + - RespectIgnoreDifferences=true + ... + ignoreDifferences: + - group: "*" + kind: "Application" + namespace: "*" + jsonPointers: + # Allow manually disabling auto sync for apps, useful for debugging. + - /spec/syncPolicy/automated + # These are automatically updated on a regular basis. Not ignoring last applied configuration since it's used for computing diffs after normalization. + - /metadata/annotations/argocd.argoproj.io~1refresh + - /operation + ... +``` diff --git a/docs/operator-manual/config-management-plugins.md b/docs/operator-manual/config-management-plugins.md index d37c514493d37..1d115261db643 100644 --- a/docs/operator-manual/config-management-plugins.md +++ b/docs/operator-manual/config-management-plugins.md @@ -359,6 +359,16 @@ You can set it one of three ways: For option 1, the flag can be repeated multiple times. For option 2 and 3, you can specify multiple globs by separating them with semicolons. +## Application manifests generation using argocd.argoproj.io/manifest-generate-paths + +To enhance the application manifests generation process, you can enable the use of the `argocd.argoproj.io/manifest-generate-paths` annotation. When this flag is enabled, the resources specified by this annotation will be passed to the CMP server for generating application manifests, rather than sending the entire repository. This can be particularly useful for monorepos. + +You can set it one of three ways: + +1. The `--plugin-use-manifest-generate-paths` argument on the repo server. +2. The `reposerver.plugin.use.manifest.generate.paths` key if you are using `argocd-cmd-params-cm` +3. Directly setting `ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS` environment variable on the repo server to `true`. + ## Migrating from argocd-cm plugins Installing plugins by modifying the argocd-cm ConfigMap is deprecated as of v2.4 and has been completely removed starting in v2.8. diff --git a/docs/operator-manual/core.md b/docs/operator-manual/core.md index 3d6e0a322c423..79b2530cfe340 100644 --- a/docs/operator-manual/core.md +++ b/docs/operator-manual/core.md @@ -12,6 +12,7 @@ installation: - Argo CD RBAC model - Argo CD API +- Argo CD Notification Controller - OIDC based authentication The following features will be partially available (see the diff --git a/docs/operator-manual/declarative-setup.md b/docs/operator-manual/declarative-setup.md index 2851ac953082f..be939570adf71 100644 --- a/docs/operator-manual/declarative-setup.md +++ b/docs/operator-manual/declarative-setup.md @@ -30,7 +30,7 @@ For each specific kind of ConfigMap and Secret resource, there is only a single |------------------------------------------------------------------|-------------|--------------------------| | [`application.yaml`](../user-guide/application-specification.md) | Application | Example application spec | | [`project.yaml`](./project-specification.md) | AppProject | Example project spec | -| - | Secret | Repository credentials | +| [`argocd-repositories.yaml`](./argocd-repositories-yaml.md) | Secret | Repository credentials | For `Application` and `AppProject` resources, the name of the resource equals the name of the application or project within Argo CD. This also means that application and project names are unique within a given Argo CD installation - you cannot have the same application name for two different applications. @@ -176,6 +176,7 @@ spec: Repository details are stored in secrets. To configure a repo, create a secret which contains repository details. Consider using [bitnami-labs/sealed-secrets](https://github.com/bitnami-labs/sealed-secrets) to store an encrypted secret definition as a Kubernetes manifest. Each repository must have a `url` field and, depending on whether you connect using HTTPS, SSH, or GitHub App, `username` and `password` (for HTTPS), `sshPrivateKey` (for SSH), or `githubAppPrivateKey` (for GitHub App). +Credentials can be scoped to a project using the optional `project` field. When omitted, the credential will be used as the default for all projects without a scoped credential. !!!warning When using [bitnami-labs/sealed-secrets](https://github.com/bitnami-labs/sealed-secrets) the labels will be removed and have to be readded as described here: https://github.com/bitnami-labs/sealed-secrets#sealedsecrets-as-templates-for-secrets @@ -195,6 +196,7 @@ stringData: url: https://github.com/argoproj/private-repo password: my-password username: my-username + project: my-project ``` Example for SSH: @@ -468,9 +470,9 @@ data: ### Configure repositories with proxy -Proxy for your repository can be specified in the `proxy` field of the repository secret, along with other repository configurations. Argo CD uses this proxy to access the repository. Argo CD looks for the standard proxy environment variables in the repository server if the custom proxy is absent. +Proxy for your repository can be specified in the `proxy` field of the repository secret, along with a corresponding `noProxy` config. Argo CD uses this proxy/noProxy config to access the repository and do related helm/kustomize operations. Argo CD looks for the standard proxy environment variables in the repository server if the custom proxy config is absent. -An example repository with proxy: +An example repository with proxy and noProxy: ```yaml apiVersion: v1 @@ -484,10 +486,13 @@ stringData: type: git url: https://github.com/argoproj/private-repo proxy: https://proxy-server-url:8888 + noProxy: ".internal.example.com,company.org,10.123.0.0/16" password: my-password username: my-username ``` +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 @@ -782,7 +787,7 @@ the role can be appended to the `args` section like so: ```yaml ... - "args": ["aws", "--cluster-name", "my-eks-cluster", "--roleARN", "arn:aws:iam:::role/"], + "args": ["aws", "--cluster-name", "my-eks-cluster", "--role-arn", "arn:aws:iam:::role/"], ... ``` This construct can be used in conjunction with something like the External Secrets Operator to avoid storing the keys in @@ -815,9 +820,9 @@ stringData: } } ``` -This will instruct ArgoCD to read the file at the provided path and use the credentials defined within to authenticate to -AWS. The profile must be mounted in order for this to work. For example, the following values can be defined in a Helm -based ArgoCD deployment: +This will instruct Argo CD to read the file at the provided path and use the credentials defined within to authenticate to AWS. +The profile must be mounted in both the `argocd-server` and `argocd-application-controller` components in order for this to work. +For example, the following values can be defined in a Helm-based Argo CD deployment: ```yaml controller: @@ -1041,7 +1046,7 @@ stringData: ## Resource Exclusion/Inclusion -Resources can be excluded from discovery and sync so that Argo CD is unaware of them. For example, the apiGroup/kind `events.k8s.io/*`, `metrics.k8s.io/*`, `coordination.k8s.io/Lease`, and `""/Endpoints` are always excluded. Use cases: +Resources can be excluded from discovery and sync so that Argo CD is unaware of them. For example, the apiGroup/kind `events.k8s.io/*`, `metrics.k8s.io/*` and `coordination.k8s.io/Lease` are always excluded. Use cases: * You have temporal issues and you want to exclude problematic resources. * There are many of a kind of resources that impacts Argo CD's performance. @@ -1132,6 +1137,22 @@ data: Custom Labels configured with `resource.customLabels` (comma separated string) will be displayed in the UI (for any resource that defines them). +## Labels on Application Events + +An optional comma-separated list of `metadata.labels` keys can be configured with `resource.includeEventLabelKeys` to add to Kubernetes events generated for Argo CD Applications. When events are generated for Applications containing the specified labels, the controller adds the matching labels to the event. This establishes an easy link between the event and the application, allowing for filtering using labels. In case of conflict between labels on the Application and AppProject, the Application label values are prioritized and added to the event. + +```yaml + resource.includeEventLabelKeys: team,env* +``` + +To exclude certain labels from events, use the `resource.excludeEventLabelKeys` key, which takes a comma-separated list of `metadata.labels` keys. + +```yaml + resource.excludeEventLabelKeys: environment,bu +``` + +Both `resource.includeEventLabelKeys` and `resource.excludeEventLabelKeys` support wildcards. + ## SSO & RBAC * SSO configuration details: [SSO](./user-management/index.md) diff --git a/docs/operator-manual/deep_links.md b/docs/operator-manual/deep_links.md index 6a5ab8ba56772..74c3196f8612a 100644 --- a/docs/operator-manual/deep_links.md +++ b/docs/operator-manual/deep_links.md @@ -26,7 +26,7 @@ Each link in the list has five subfields: 4. `icon.class` (optional): a font-awesome icon class to be used when displaying the links in dropdown menus 5. `if` (optional): a conditional statement that results in either `true` or `false`, it also has access to the same data as the `url` field. If the condition resolves to `true` the deep link will be displayed - else it will be hidden. If - the field is omitted, by default the deep links will be displayed. This uses [antonmedv/expr](https://github.com/antonmedv/expr/tree/master/docs) for evaluating conditions + the field is omitted, by default the deep links will be displayed. This uses [expr-lang/expr](https://github.com/expr-lang/expr/tree/master/docs) for evaluating conditions !!!note For resources of kind Secret the data fields are redacted but other fields are accessible for templating the deep links. @@ -63,7 +63,7 @@ An example `argocd-cm.yaml` file with deep links and their variations : - url: https://mycompany.splunk.com?search={{.app.spec.destination.namespace}}&env={{.project.metadata.labels.env}} title: Splunk # conditionally show link e.g. for specific project - # github.com/antonmedv/expr is used for evaluation of conditions + # github.com/expr-lang/expr is used for evaluation of conditions - url: https://mycompany.splunk.com?search={{.app.spec.destination.namespace}} title: Splunk if: application.spec.project == "default" diff --git a/docs/operator-manual/health.md b/docs/operator-manual/health.md index e958d1a7634ac..107f2f3f92cdb 100644 --- a/docs/operator-manual/health.md +++ b/docs/operator-manual/health.md @@ -38,21 +38,19 @@ metadata: app.kubernetes.io/name: argocd-cm app.kubernetes.io/part-of: argocd data: - resource.customizations: | - argoproj.io/Application: - health.lua: | - hs = {} - hs.status = "Progressing" - hs.message = "" - if obj.status ~= nil then - if obj.status.health ~= nil then - hs.status = obj.status.health.status - if obj.status.health.message ~= nil then - hs.message = obj.status.health.message - end - end + resource.customizations.health.argoproj.io_Application: | + hs = {} + hs.status = "Progressing" + hs.message = "" + if obj.status ~= nil then + if obj.status.health ~= nil then + hs.status = obj.status.health.status + if obj.status.health.message ~= nil then + hs.message = obj.status.health.message end - return hs + end + end + return hs ``` ## Custom Health Checks @@ -68,9 +66,7 @@ There are two ways to configure a custom health check. The next two sections des Custom health checks can be defined in ```yaml - resource.customizations: | - : - health.lua: | + resource.customizations.health._: | ``` field of `argocd-cm`. If you are using argocd-operator, this is overridden by [the argocd-operator resourceCustomizations](https://argocd-operator.readthedocs.io/en/latest/reference/argocd/#resource-customizations). @@ -78,49 +74,44 @@ The following example demonstrates a health check for `cert-manager.io/Certifica ```yaml data: - resource.customizations: | - cert-manager.io/Certificate: - health.lua: | - hs = {} - if obj.status ~= nil then - if obj.status.conditions ~= nil then - for i, condition in ipairs(obj.status.conditions) do - if condition.type == "Ready" and condition.status == "False" then - hs.status = "Degraded" - hs.message = condition.message - return hs - end - if condition.type == "Ready" and condition.status == "True" then - hs.status = "Healthy" - hs.message = condition.message - return hs - end - end + resource.customizations.health.cert-manager.io_Certificate: | + hs = {} + if obj.status ~= nil then + if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" and condition.status == "False" then + hs.status = "Degraded" + hs.message = condition.message + return hs + end + if condition.type == "Ready" and condition.status == "True" then + hs.status = "Healthy" + hs.message = condition.message + return hs end end + end + end - hs.status = "Progressing" - hs.message = "Waiting for certificate" - return hs + hs.status = "Progressing" + hs.message = "Waiting for certificate" + return hs ``` + In order to prevent duplication of the custom health check for potentially multiple resources, it is also possible to specify a wildcard in the resource kind, and anywhere in the resource group, like this: ```yaml - resource.customizations: | - ec2.aws.crossplane.io/*: - health.lua: | - ... + resource.customizations.health.ec2.aws.crossplane.io_*: | + ... ``` ```yaml - resource.customizations: | - "*.aws.crossplane.io/*": - health.lua: | - ... + resource.customizations.health.*.aws.crossplane.io_*: | + ... ``` !!!important - Please note the required quotes in the resource customization health section, if the wildcard starts with `*`. + Please, note that there can be ambiguous resolution of wildcards, see [#16905](https://github.com/argoproj/argo-cd/issues/16905) 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: @@ -133,15 +124,13 @@ The custom health check might return one of the following health statuses: By default health typically returns `Progressing` status. NOTE: As a security measure, access to the standard Lua libraries will be disabled by default. Admins can control access by -setting `resource.customizations.useOpenLibs.`. In the following example, standard libraries are enabled for health check of `cert-manager.io/Certificate`. +setting `resource.customizations.useOpenLibs._`. In the following example, standard libraries are enabled for health check of `cert-manager.io/Certificate`. ```yaml data: - resource.customizations: | - cert-manager.io/Certificate: - health.lua.useOpenLibs: true - health.lua: | - # Lua standard libraries are enabled for this script + resource.customizations.useOpenLibs.cert-manager.io_Certificate: true + resource.customizations.health.cert-manager.io_Certificate: | + # Lua standard libraries are enabled for this script ``` ### Way 2. Contribute a Custom Health Check diff --git a/docs/operator-manual/high_availability.md b/docs/operator-manual/high_availability.md index 632ac2fb1286b..ddcce80fab25a 100644 --- a/docs/operator-manual/high_availability.md +++ b/docs/operator-manual/high_availability.md @@ -130,6 +130,10 @@ stringData: count (grouped by k8s api version, the granule of parallelism for list operations). In this case, all resources will be buffered in memory -- no api server request will be blocked by processing. +* `ARGOCD_APPLICATION_TREE_SHARD_SIZE` - environment variable controlling the max number of resources stored in one Redis + key. Splitting application tree into multiple keys helps to reduce the amount of traffic between the controller and Redis. + The default value is 0, which means that the application tree is stored in a single Redis key. The reasonable value is 100. + **metrics** * `argocd_app_reconcile` - reports application reconciliation duration in seconds. Can be used to build reconciliation duration heat map to get a high-level reconciliation performance picture. @@ -273,6 +277,9 @@ spec: # ... ``` +!!! note + If application manifest generation using the `argocd.argoproj.io/manifest-generate-paths` annotation feature is enabled, only the resources specified by this annotation will be sent to the CMP server for manifest generation, rather than the entire repository. To determine the appropriate resources, a common root path is calculated based on the paths provided in the annotation. The application path serves as the deepest path that can be selected as the root. + ### Application Sync Timeout & Jitter Argo CD has a timeout for application syncs. It will trigger a refresh for each application periodically when the timeout expires. @@ -371,3 +378,17 @@ Not all HTTP responses are eligible for retries. The following conditions will n * Responses with a status code indicating client errors (4xx) except for 429 Too Many Requests. * Responses with the status code 501 Not Implemented. + + +## CPU/Memory Profiling + +Argo CD optionally exposes a profiling endpoint that can be used to profile the CPU and memory usage of the Argo CD component. +The profiling endpoint is available on metrics port of each component. See [metrics](./metrics.md) for more information about the port. +For security reasons the profiling endpoint is disabled by default. The endpoint can be enabled by setting the `server.profile.enabled` +or `controller.profile.enabled` key of [argocd-cmd-params-cm](argocd-cmd-params-cm.yaml) ConfigMap to `true`. +Once the endpoint is enabled you can use go profile tool to collect the CPU and memory profiles. Example: + +```bash +$ kubectl port-forward svc/argocd-metrics 8082:8082 +$ go tool pprof http://localhost:8082/debug/pprof/heap +``` diff --git a/docs/operator-manual/ingress.md b/docs/operator-manual/ingress.md index a46853546a28a..652458c32f093 100644 --- a/docs/operator-manual/ingress.md +++ b/docs/operator-manual/ingress.md @@ -471,7 +471,7 @@ Once we create this service, we can configure the Ingress to conditionally route ``` ## [Istio](https://www.istio.io) -You can put Argo CD behind Istio using following configurations. Here we will achive both serving Argo CD behind istio and using subpath on Istio +You can put Argo CD behind Istio using following configurations. Here we will achieve both serving Argo CD behind istio and using subpath on Istio First we need to make sure that we can run Argo CD with subpath (ie /argocd). For this we have used install.yaml from argocd project as is @@ -617,7 +617,7 @@ Edit the `--insecure` flag in the `argocd-server` command of the argocd-server d ### Creating a service -Now you need an externally accessible service. This is practically the same as the internal service Argo CD has, but with Google Cloud annotations. Note that this service is annotated to use a [Network Endpoint Group](https://cloud.google.com/load-balancing/docs/negs) (NEG) to allow your load balancer to send traffic directly to your pods without using kube-proxy, so remove the `neg` annotation it that's not what you want. +Now you need an externally accessible service. This is practically the same as the internal service Argo CD has, but with Google Cloud annotations. Note that this service is annotated to use a [Network Endpoint Group](https://cloud.google.com/load-balancing/docs/negs) (NEG) to allow your load balancer to send traffic directly to your pods without using kube-proxy, so remove the `neg` annotation if that's not what you want. The service: diff --git a/docs/operator-manual/installation.md b/docs/operator-manual/installation.md index 5782e5660868f..70494298c1391 100644 --- a/docs/operator-manual/installation.md +++ b/docs/operator-manual/installation.md @@ -21,6 +21,9 @@ Not recommended for production use. This type of installation is typically used in (i.e. kubernetes.svc.default). It will still be able to deploy to external clusters with inputted credentials. + > Note: The ClusterRoleBinding in the installation manifest is bound to a ServiceAccount in the argocd namespace. + > Be cautious when modifying the namespace, as changing it may cause permission-related errors unless the ClusterRoleBinding is correctly adjusted to reflect the new namespace. + * [namespace-install.yaml](https://github.com/argoproj/argo-cd/blob/master/manifests/namespace-install.yaml) - Installation of Argo CD which requires only namespace level privileges (does not need cluster roles). Use this manifest set if you do not need Argo CD to deploy applications in the same cluster that Argo CD runs in, and will rely solely @@ -78,6 +81,29 @@ resources: For an example of this, see the [kustomization.yaml](https://github.com/argoproj/argoproj-deployments/blob/master/argocd/kustomization.yaml) used to deploy the [Argoproj CI/CD infrastructure](https://github.com/argoproj/argoproj-deployments#argoproj-deployments). +#### Installing Argo CD in a Custom Namespace +If you want to install Argo CD in a namespace other than the default argocd, you can use Kustomize to apply a patch that updates the ClusterRoleBinding to reference the correct namespace for the ServiceAccount. This ensures that the necessary permissions are correctly set in your custom namespace. + +Below is an example of how to configure your kustomization.yaml to install Argo CD in a custom namespace: +```yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: +resources: + - https://raw.githubusercontent.com/argoproj/argo-cd/v2.7.2/manifests/install.yaml + +patches: + - patch: |- + - op: replace + path: /subjects/0/namespace + value: + target: + kind: ClusterRoleBinding +``` + +This patch ensures that the ClusterRoleBinding correctly maps to the ServiceAccount in your custom namespace, preventing any permission-related issues during the deployment. + ## Helm The Argo CD can be installed using [Helm](https://helm.sh/). The Helm chart is currently community maintained and available at diff --git a/docs/operator-manual/metrics.md b/docs/operator-manual/metrics.md index 5aebb9245c0ae..02a490998307a 100644 --- a/docs/operator-manual/metrics.md +++ b/docs/operator-manual/metrics.md @@ -8,6 +8,7 @@ Metrics about applications. Scraped at the `argocd-metrics:8082/metrics` endpoin | 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_reconcile` | histogram | Application reconciliation performance in seconds. | @@ -30,6 +31,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. @@ -60,6 +63,45 @@ argocd_app_labels{label_business_unit="bu-id-1",label_team_name="my-team",name=" argocd_app_labels{label_business_unit="bu-id-2",label_team_name="another-team",name="my-app-3",namespace="argocd",project="important-project"} 1 ``` +### Exposing Application conditions as Prometheus metrics + +There are use-cases where Argo CD Applications contain conditions that are desired to be exposed as Prometheus metrics. +Some examples are: + +* Hunting orphaned resources across all deployed applications +* Knowing which resources are excluded from ArgoCD + +As the Application conditions are specific to each company, this feature is disabled by default. To enable it, add the +`--metrics-application-conditions` flag to the Argo CD application controller. + +The example below will expose the Argo CD Application condition `OrphanedResourceWarning` and `ExcludedResourceWarning` to Prometheus: + +```yaml + containers: + - command: + - argocd-application-controller + - --metrics-application-conditions + - OrphanedResourceWarning + - --metrics-application-conditions + - ExcludedResourceWarning +``` + +## Application Set Controller metrics + +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. | + +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). + ## 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. diff --git a/docs/operator-manual/notifications/functions.md b/docs/operator-manual/notifications/functions.md index c50d122024b76..ebde62a62afb0 100644 --- a/docs/operator-manual/notifications/functions.md +++ b/docs/operator-manual/notifications/functions.md @@ -12,6 +12,44 @@ Golang [Time](https://golang.org/pkg/time/#Time). Parses specified string using RFC3339 layout. Returns an instance of Golang [Time](https://golang.org/pkg/time/#Time). +
+Time related constants. + +**Durations** + +``` + time.Nanosecond = 1 + time.Microsecond = 1000 * Nanosecond + time.Millisecond = 1000 * Microsecond + time.Second = 1000 * Millisecond + time.Minute = 60 * Second + time.Hour = 60 * Minute +``` + +**Timestamps** + +Used when formatting time instances as strings (e.g. `time.Now().Format(time.RFC3339)`). + +``` + time.Layout = "01/02 03:04:05PM '06 -0700" // The reference time, in numerical order. + time.ANSIC = "Mon Jan _2 15:04:05 2006" + time.UnixDate = "Mon Jan _2 15:04:05 MST 2006" + time.RubyDate = "Mon Jan 02 15:04:05 -0700 2006" + time.RFC822 = "02 Jan 06 15:04 MST" + time.RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone + time.RFC850 = "Monday, 02-Jan-06 15:04:05 MST" + time.RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST" + time.RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone + time.RFC3339 = "2006-01-02T15:04:05Z07:00" + time.RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00" + time.Kitchen = "3:04PM" + // Handy time stamps. + time.Stamp = "Jan _2 15:04:05" + time.StampMilli = "Jan _2 15:04:05.000" + time.StampMicro = "Jan _2 15:04:05.000000" + time.StampNano = "Jan _2 15:04:05.000000000" +``` + ### **strings** String related functions. diff --git a/docs/operator-manual/notifications/index.md b/docs/operator-manual/notifications/index.md index eccca906ae91b..002f67249c616 100644 --- a/docs/operator-manual/notifications/index.md +++ b/docs/operator-manual/notifications/index.md @@ -93,7 +93,7 @@ data: apiVersion: v1 kind: Secret metadata: - name: argo-cd-notification-secret + name: argocd-notifications-secret type: Opaque data: pagerduty-key-my-service: diff --git a/docs/operator-manual/notifications/troubleshooting-errors.md b/docs/operator-manual/notifications/troubleshooting-errors.md index 5ae95e8e384d6..ecfcf7151c0ce 100644 --- a/docs/operator-manual/notifications/troubleshooting-errors.md +++ b/docs/operator-manual/notifications/troubleshooting-errors.md @@ -40,6 +40,27 @@ You need to check your argocd-notifications controller version. For instance, th You have not defined `xxxx` in `argocd-notifications-cm` or to fail to parse settings. +### GitHub.repoURL (\u003cno value\u003e) does not have a / using the configuration + +You probably have an Application with [multiple sources](https://argo-cd.readthedocs.io/en/stable/user-guide/multiple_sources/): + +```yaml +spec: + sources: # <- multiple sources + - repoURL: https://github.com/exampleOrg/first.git + path: sources/example + - repoURL: https://github.com/exampleOrg/second.git + targetRevision: "{{branch}}" +``` + +So standard notification template won't work (`{{.app.spec.source.repoURL}}`). You should choose a single source instead: + +```yaml +template.example: | + github: + repoURLPath: "{{ (index .app.spec.sources 0).repoURL }}" +``` + ## config referenced xxx, but key does not exist in secret - If you are using a custom secret, check that the secret is in the same namespace diff --git a/docs/operator-manual/rbac.md b/docs/operator-manual/rbac.md index 8b318e77b7060..e85be535bd826 100644 --- a/docs/operator-manual/rbac.md +++ b/docs/operator-manual/rbac.md @@ -154,6 +154,8 @@ The `action` action corresponds to either built-in resource customizations defin [in the Argo CD repository](https://github.com/argoproj/argo-cd/tree/master/resource_customizations), or to [custom resource actions](resource_actions.md#custom-resource-actions) defined by you. +See the [resource actions documentation](resource_actions.md#built-in-actions) for a list of built-in actions. + The `` has the `action///` format. For example, a resource customization path `resource_customizations/extensions/DaemonSet/actions/restart/action.lua` diff --git a/docs/operator-manual/reconcile.md b/docs/operator-manual/reconcile.md index a956cd9cf7b28..ebf8983a39a97 100644 --- a/docs/operator-manual/reconcile.md +++ b/docs/operator-manual/reconcile.md @@ -4,7 +4,8 @@ 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. @@ -109,5 +110,57 @@ data: jqPathExpressions: # Ignore lastTransitionTime for conditions; helpful when SharedResourceWarnings are being regularly updated but not # actually changing in content. - - .status.conditions[].lastTransitionTime + - .status?.conditions[]?.lastTransitionTime +``` + +## Ignoring updates for untracked resources + +ArgoCD will only apply `ignoreResourceUpdates` configuration to tracked resources of an application. This means dependant resources, such as a `ReplicaSet` and `Pod` created by a `Deployment`, will not ignore any updates and trigger a reconcile of the application for any changes. + +If you want to apply the `ignoreResourceUpdates` configuration to an untracked resource, you can add the +`argocd.argoproj.io/ignore-resource-updates=true` annotation in the dependent resources manifest. + +## Example + +### CronJob + +```yaml +apiVersion: batch/v1 +kind: CronJob +metadata: + name: hello + namespace: test-cronjob +spec: + schedule: "* * * * *" + jobTemplate: + metadata: + annotations: + argocd.argoproj.io/ignore-resource-updates: "true" + spec: + template: + metadata: + annotations: + 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 + 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 +resource.customizations.ignoreResourceUpdates.Pod: | + jsonPointers: + - /status ``` diff --git a/docs/operator-manual/resource_actions.md b/docs/operator-manual/resource_actions.md index b720f589ae8d0..0a4ea2cb3936a 100644 --- a/docs/operator-manual/resource_actions.md +++ b/docs/operator-manual/resource_actions.md @@ -5,6 +5,14 @@ Argo CD allows operators to define custom actions which users can perform on spe Operators can add actions to custom resources in form of a Lua script and expand those capabilities. +## Built-in Actions + +The following are actions that are built-in to Argo CD. Each action name links to its Lua script definition: + +{!docs/operator-manual/resource_actions_builtin.md!} + +See the [RBAC documentation](rbac.md#the-action-action) for information on how to control access to these actions. + ## Custom Resource Actions Argo CD supports custom resource actions written in [Lua](https://www.lua.org/). This is useful if you: @@ -72,6 +80,20 @@ The `discovery.lua` script must return a table where the key name represents the Each action name must be represented in the list of `definitions` with an accompanying `action.lua` script to control the resource modifications. The `obj` is a global variable which contains the resource. Each action script returns an optionally modified version of the resource. In this example, we are simply setting `.spec.suspend` to either `true` or `false`. +By default, defining a resource action customization will override any built-in action for this resource kind. If you want to retain the built-in actions, you can set the `mergeBuiltinActions` key to `true`. Your custom actions will have precedence over the built-in actions. +```yaml +resource.customizations.actions.argoproj.io_Rollout: | + mergeBuiltinActions: true + discovery.lua: | + actions = {} + actions["do-things"] = {} + return actions + definitions: + - name: do-things + action.lua: | + return obj +``` + #### Creating new resources with a custom action !!! important diff --git a/docs/operator-manual/resource_actions_builtin.md b/docs/operator-manual/resource_actions_builtin.md new file mode 100644 index 0000000000000..46230a879a875 --- /dev/null +++ b/docs/operator-manual/resource_actions_builtin.md @@ -0,0 +1,50 @@ +- [apps/DaemonSet/restart](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/apps/DaemonSet/actions/restart/action.lua) +- [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/StatefulSet/restart](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/apps/StatefulSet/actions/restart/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/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/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) +- [external-secrets.io/PushSecret/push](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/external-secrets.io/PushSecret/actions/push/action.lua) +- [helm.toolkit.fluxcd.io/HelmRelease/reconcile](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/reconcile/action.lua) +- [helm.toolkit.fluxcd.io/HelmRelease/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/resume/action.lua) +- [helm.toolkit.fluxcd.io/HelmRelease/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/suspend/action.lua) +- [image.toolkit.fluxcd.io/ImageRepository/reconcile](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/reconcile/action.lua) +- [image.toolkit.fluxcd.io/ImageRepository/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/resume/action.lua) +- [image.toolkit.fluxcd.io/ImageRepository/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/suspend/action.lua) +- [image.toolkit.fluxcd.io/ImageUpdateAutomation/reconcile](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/reconcile/action.lua) +- [image.toolkit.fluxcd.io/ImageUpdateAutomation/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/resume/action.lua) +- [image.toolkit.fluxcd.io/ImageUpdateAutomation/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/suspend/action.lua) +- [kustomize.toolkit.fluxcd.io/Kustomization/reconcile](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/reconcile/action.lua) +- [kustomize.toolkit.fluxcd.io/Kustomization/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/resume/action.lua) +- [kustomize.toolkit.fluxcd.io/Kustomization/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/suspend/action.lua) +- [notification.toolkit.fluxcd.io/Alert/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/resume/action.lua) +- [notification.toolkit.fluxcd.io/Alert/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/suspend/action.lua) +- [notification.toolkit.fluxcd.io/Provider/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/resume/action.lua) +- [notification.toolkit.fluxcd.io/Provider/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/suspend/action.lua) +- [notification.toolkit.fluxcd.io/Receiver/reconcile](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/reconcile/action.lua) +- [notification.toolkit.fluxcd.io/Receiver/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/resume/action.lua) +- [notification.toolkit.fluxcd.io/Receiver/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/suspend/action.lua) +- [source.toolkit.fluxcd.io/Bucket/reconcile](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/reconcile/action.lua) +- [source.toolkit.fluxcd.io/Bucket/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/resume/action.lua) +- [source.toolkit.fluxcd.io/Bucket/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/suspend/action.lua) +- [source.toolkit.fluxcd.io/GitRepository/reconcile](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/reconcile/action.lua) +- [source.toolkit.fluxcd.io/GitRepository/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/resume/action.lua) +- [source.toolkit.fluxcd.io/GitRepository/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/suspend/action.lua) +- [source.toolkit.fluxcd.io/HelmChart/reconcile](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/reconcile/action.lua) +- [source.toolkit.fluxcd.io/HelmChart/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/resume/action.lua) +- [source.toolkit.fluxcd.io/HelmChart/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/suspend/action.lua) +- [source.toolkit.fluxcd.io/HelmRepository/reconcile](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/reconcile/action.lua) +- [source.toolkit.fluxcd.io/HelmRepository/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/resume/action.lua) +- [source.toolkit.fluxcd.io/HelmRepository/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/suspend/action.lua) +- [source.toolkit.fluxcd.io/OCIRepository/reconcile](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/reconcile/action.lua) +- [source.toolkit.fluxcd.io/OCIRepository/resume](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/resume/action.lua) +- [source.toolkit.fluxcd.io/OCIRepository/suspend](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/suspend/action.lua) diff --git a/docs/operator-manual/server-commands/argocd-application-controller.md b/docs/operator-manual/server-commands/argocd-application-controller.md index 930dfa414751c..f0d1a01dbd02d 100644 --- a/docs/operator-manual/server-commands/argocd-application-controller.md +++ b/docs/operator-manual/server-commands/argocd-application-controller.md @@ -31,6 +31,7 @@ argocd-application-controller [flags] --default-cache-expiration duration Cache expiration default (default 24h0m0s) --disable-compression If true, opt-out of response compression for all requests to the server --dynamic-cluster-distribution-enabled Enables dynamic cluster distribution. + --enable-k8s-event none Enable ArgoCD to use k8s event. For disabling all events, set the value as none. (e.g --enable-k8s-event=none), For enabling specific events, set the value as `event reason`. (e.g --enable-k8s-event=StatusRefreshed,ResourceCreated) (default [all]) --gloglevel int Set the glog logging level -h, --help help for argocd-application-controller --ignore-normalizer-jq-execution-timeout-seconds duration Set ignore normalizer JQ execution timeout @@ -39,6 +40,7 @@ argocd-application-controller [flags] --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: 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-port int Start metrics server on given port (default 8082) diff --git a/docs/operator-manual/server-commands/argocd-repo-server.md b/docs/operator-manual/server-commands/argocd-repo-server.md index 3532fc6c30b4a..12e4d34d14028 100644 --- a/docs/operator-manual/server-commands/argocd-repo-server.md +++ b/docs/operator-manual/server-commands/argocd-repo-server.md @@ -35,6 +35,7 @@ argocd-repo-server [flags] --otlp-insecure OpenTelemetry collector insecure mode (default true) --parallelismlimit int Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit. --plugin-tar-exclude stringArray Globs to filter when sending tarballs to plugins. + --plugin-use-manifest-generate-paths Pass the resources described in argocd.argoproj.io/manifest-generate-paths value to the cmpserver to generate the application manifests. --port int Listen on given port for incoming connections (default 8081) --redis string Redis server hostname and port (e.g. argocd-redis:6379). --redis-ca-certificate string Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation. diff --git a/docs/operator-manual/server-commands/argocd-server.md b/docs/operator-manual/server-commands/argocd-server.md index 5b3fd72ebff00..0fe1e2d3ca45e 100644 --- a/docs/operator-manual/server-commands/argocd-server.md +++ b/docs/operator-manual/server-commands/argocd-server.md @@ -29,6 +29,10 @@ argocd-server [flags] --api-content-types string Semicolon separated list of allowed content types for non GET api requests. Any content type is allowed if empty. (default "application/json") --app-state-cache-expiration duration Cache expiration for app state (default 1h0m0s) --application-namespaces strings List of additional namespaces where application resources can be managed in + --appset-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) + --appset-enable-new-git-file-globbing Enable new globbing in Git files generator. + --appset-enable-scm-providers Enable retrieving information from SCM providers, used by the SCM and PR generators (Default: true) (default true) + --appset-scm-root-ca-path string Provide Root CA Path for self-signed TLS Certificates --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 @@ -47,6 +51,7 @@ argocd-server [flags] --disable-auth Disable client authentication --disable-compression If true, opt-out of response compression for all requests to the server --enable-gzip Enable GZIP compression (default true) + --enable-k8s-event none Enable ArgoCD to use k8s event. For disabling all events, set the value as none. (e.g --enable-k8s-event=none), For enabling specific events, set the value as `event reason`. (e.g --enable-k8s-event=StatusRefreshed,ResourceCreated) (default [all]) --enable-proxy-extension Enable Proxy Extension feature --gloglevel int Set the glog logging level -h, --help help for argocd-server @@ -106,6 +111,7 @@ argocd-server [flags] --token string Bearer token for authentication to the API server --user string The name of the kubeconfig user to use --username string Username for basic authentication to the API server + --webhook-parallelism-limit int Number of webhook requests processed concurrently (default 50) --x-frame-options value Set X-Frame-Options header in HTTP responses to value. To disable, set to "". (default "sameorigin") ``` diff --git a/docs/operator-manual/signed-release-assets.md b/docs/operator-manual/signed-release-assets.md index b574876345b5b..3c42b27fd4e10 100644 --- a/docs/operator-manual/signed-release-assets.md +++ b/docs/operator-manual/signed-release-assets.md @@ -32,7 +32,8 @@ Argo CD container images are signed by [cosign](https://github.com/sigstore/cosi cosign verify \ --certificate-identity-regexp https://github.com/argoproj/argo-cd/.github/workflows/image-reuse.yaml@refs/tags/v \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ -quay.io/argoproj/argocd:v2.7.0 | jq +--certificate-github-workflow-repository "argoproj/argo-cd" \ +quay.io/argoproj/argocd:v2.11.3 | jq ``` The command should output the following if the container image was correctly verified: ```bash diff --git a/docs/operator-manual/tested-kubernetes-versions.md b/docs/operator-manual/tested-kubernetes-versions.md index 897620296a515..73475e8523f5b 100644 --- a/docs/operator-manual/tested-kubernetes-versions.md +++ b/docs/operator-manual/tested-kubernetes-versions.md @@ -1,6 +1,2 @@ -| Argo CD version | Kubernetes versions | -|-----------------|---------------------| -| 2.7 | v1.26, v1.25, v1.24, v1.23 | -| 2.6 | v1.24, v1.23, v1.22 | -| 2.5 | v1.24, v1.23, v1.22 | - +This page is populated for released Argo CD versions. Use the version selector to view this table for a specific +version. diff --git a/docs/operator-manual/upgrading/2.11-2.12.md b/docs/operator-manual/upgrading/2.11-2.12.md index 4ce87578d1c1b..deb538feb1915 100644 --- a/docs/operator-manual/upgrading/2.11-2.12.md +++ b/docs/operator-manual/upgrading/2.11-2.12.md @@ -1,5 +1,18 @@ # v2.11 to 2.12 +## Cluster secret scoping changes + +From Argo CD 2.12, there have been some changes to the use of cluster secrets where a `project` is a non-empty value. +Previously, an `Application` or `ApplicationSet` would use any cluster secret matching the URL of the `repoUrl` field. +From 2.12, we now check to see whether the project field of an application _also_ matches the project field of the cluster +secret. What this means is that if you have a cluster secret scoped to `project-a`, an application scoped to `project-b` +can no longer make use of the secret. If you have a cluster secret that's intended to be used by applications in multiple +projects, you need to **unset** the `project` field. + +This also applies when using the Git generator in applicationsets; since an applicationset is not scoped to a particular +project any cluster secrets it makes use of also needs to be globally scoped (i.e. any secret needs to have an unset +`project`). + ## Upgraded Helm Version Note that bundled Helm version has been upgraded from 3.14.4 to 3.15.2. diff --git a/docs/operator-manual/upgrading/2.12-2.13.md b/docs/operator-manual/upgrading/2.12-2.13.md new file mode 100644 index 0000000000000..14b26f22a2d70 --- /dev/null +++ b/docs/operator-manual/upgrading/2.12-2.13.md @@ -0,0 +1,69 @@ +# v2.12 to 2.13 + +## Custom Resource Actions for Flux Resources + +[`Custom Resource Actions`](../resource_actions.md#Custom-Resource-Actions) have been added for Flux Resources. +The following actions are now available: + +| Custom Resource | Supported Actions | +|-----------------------|----------------------------------| +| HelmRelease | `Suspend`, `Resume`, `Reconcile` | +| ImageRepository | `Suspend`, `Resume`, `Reconcile` | +| ImageUpdateAutomation | `Suspend`, `Resume`, `Reconcile` | +| Kustomization | `Suspend`, `Resume`, `Reconcile` | +| Alert | `Suspend`, `Resume` | +| Provider | `Suspend`, `Resume` | +| Receiver | `Suspend`, `Resume`, `Reconcile` | +| Bucket | `Suspend`, `Resume`, `Reconcile` | +| GitRepository | `Suspend`, `Resume`, `Reconcile` | +| HelmChart | `Suspend`, `Resume`, `Reconcile` | +| HelmRepository | `Suspend`, `Resume`, `Reconcile` | +| OCIRepository | `Suspend`, `Resume`, `Reconcile` | + +If you want to use these actions do not forget to update the permissions (RBAC) for your Argo CD instance. + +## Custom Resource Health for Flux Resources + +[`Custom Resource Health`](../health.md#custom-health-checks) has been added for Flux Resources. +The following Flux resources now support health checks: +- HelmRelease +- ImagePolicy +- ImageRepository +- ImageUpdateAutomation +- Kustomization +- Receiver +- Bucket +- GitRepository +- HelmChart +- HelmRepository +- OCIRepository + +## Upgraded Dex Version + +Dex [v2.39.0](https://github.com/dexidp/dex/releases/tag/v2.39.0) included a breaking change for the LDAP connector: + +> The validation of username and password in the LDAP connector is much more strict now. +> As of today, Dex uses the EscapeFilter function to check for special characters in credentials and prevent injections by denying such requests. + +## Updated Job name for manually started CronJob jobs + +The naming of Jobs that are manually started from CronJobs (using Argo CD) was changed. Instead of the previous postfix `-YYYYMMDDHHmm` (4-digit year), manually started Jobs now receive postfix `-YYMMDDHHmm` (2-digit year). + +The format of Jobs that are started from a CronJob on schedule (by Kubernetes) is not handled by Argo CD and remains unchanged. + +## Change in Log File Extension for Downloaded Logs + +The default extension for log files generated by Argo CD when using the "Download Logs" feature has been changed from `.txt` to `.log`. This change aligns with industry standards and improves compatibility with various log management tools and IDEs that offer enhanced features for `.log` files. + +**Impact:** +- Users and systems that rely on the `.txt` extension will need to adjust their workflows. +- Automated scripts and processes that specifically target `.txt` log files should be updated to handle `.log` files. + +**Benefits:** +- Improved readability and parsing in IDEs and log management tools. +- Consistency with standard log file conventions. + +If you have any custom scripts or tools that depend on the `.txt` extension, please update them accordingly. +## Added proxy to kustomize + +Proxy config set on repository credentials / repository templates is now passed down to the `kustomize build` command. diff --git a/docs/operator-manual/upgrading/overview.md b/docs/operator-manual/upgrading/overview.md index b4f1c397b62fb..290ef05638d88 100644 --- a/docs/operator-manual/upgrading/overview.md +++ b/docs/operator-manual/upgrading/overview.md @@ -37,6 +37,7 @@ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/ +* [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) * [v2.9 to v2.10](./2.9-2.10.md) diff --git a/docs/operator-manual/user-management/identity-center.md b/docs/operator-manual/user-management/identity-center.md index 0fd78b1aaf62f..c4019964d7a4d 100644 --- a/docs/operator-manual/user-management/identity-center.md +++ b/docs/operator-manual/user-management/identity-center.md @@ -1,7 +1,7 @@ # Identity Center (AWS SSO) !!! note "Are you using this? Please contribute!" - If you're using this IdP please consider [contributing](../../developer-guide/site.md) to this document. + If you're using this IdP please consider [contributing](../../developer-guide/docs-site.md) to this document. A working Single Sign-On configuration using Identity Center (AWS SSO) has been achieved using the following method: diff --git a/docs/operator-manual/user-management/index.md b/docs/operator-manual/user-management/index.md index c002b77ada5ed..8616764172988 100644 --- a/docs/operator-manual/user-management/index.md +++ b/docs/operator-manual/user-management/index.md @@ -172,6 +172,8 @@ kubectl edit configmap argocd-cm -n argocd ``` * In the `url` key, input the base URL of Argo CD. In this example, it is `https://argocd.example.com` +* (Optional): If Argo CD should be accessible via multiple base URLs you may + specify any additional base URLs via the `additionalUrls` key. * In the `dex.config` key, add the `github` connector to the `connectors` sub field. See Dex's [GitHub connector](https://github.com/dexidp/website/blob/main/content/docs/connectors/github.md) documentation for explanation of the fields. A minimal config should populate the clientID, diff --git a/docs/operator-manual/user-management/keycloak.md b/docs/operator-manual/user-management/keycloak.md index 6f0c99de0dec2..10551321d976a 100644 --- a/docs/operator-manual/user-management/keycloak.md +++ b/docs/operator-manual/user-management/keycloak.md @@ -125,3 +125,9 @@ In this example we give the role _role:admin_ to all users in the group _ArgoCDA You can now login using our new Keycloak OIDC authentication: ![Keycloak ArgoCD login](../../assets/keycloak-login.png "Keycloak ArgoCD login") + +## Troubleshoot +If ArgoCD auth returns 401 or when the login attempt leads to the loop, then restart the argocd-server pod. +``` +kubectl rollout restart deployment argocd-server -n argocd +``` diff --git a/docs/operator-manual/user-management/microsoft.md b/docs/operator-manual/user-management/microsoft.md index 19e28cf6fd289..72a3a3ce77980 100644 --- a/docs/operator-manual/user-management/microsoft.md +++ b/docs/operator-manual/user-management/microsoft.md @@ -133,6 +133,7 @@ requestedIDTokenClaims: groups: essential: true + value: "SecurityGroup" requestedScopes: - openid - profile diff --git a/docs/operator-manual/user-management/okta.md b/docs/operator-manual/user-management/okta.md index 308254759de6e..4fd7ea0dc734c 100644 --- a/docs/operator-manual/user-management/okta.md +++ b/docs/operator-manual/user-management/okta.md @@ -1,7 +1,7 @@ # Okta !!! note "Are you using this? Please contribute!" - If you're using this IdP please consider [contributing](../../developer-guide/site.md) to this document. + If you're using this IdP please consider [contributing](../../developer-guide/docs-site.md) to this document. A working Single Sign-On configuration using Okta via at least two methods was achieved using: @@ -135,7 +135,7 @@ First, create the OIDC integration: ![Okta OIDC app dialogue](../../assets/okta-create-oidc-app.png) 1. Update the following: 1. `App Integration name` and `Logo` - set these to suit your needs; they'll be displayed in the Okta catalogue. - 1. `Sign-in redirect URLs`: Add `https://argocd.example.com/auth/callback`; replacing `argocd.example.com` with your ArgoCD web interface URL. Also add `http://localhost:8085/auth/callback` if you would like to be able to login with the CLI. + 1. `Sign-in redirect URLs`: Add `https://argocd.example.com/auth/callback`; replacing `argocd.example.com` with your ArgoCD web interface URL. 1. `Sign-out redirect URIs`: Add `https://argocd.example.com`; substituting the correct domain name as above. 1. Either assign groups, or choose to skip this step for now. 1. Leave the rest of the options as-is, and save the integration. @@ -170,6 +170,25 @@ Next, create a custom Authorization server: ![Default rule](../../assets/okta-auth-rule.png) 1. Finally, click `Back to Authorization Servers`, and copy the `Issuer URI`. You will need this later. +### CLI login + +In order to login with the CLI `argocd login https://argocd.example.com --sso`, Okta requires a separate dedicated App Integration: + +1. Create a new `Create App Integration`, and choose `OIDC`, and then `Single-Page Application`. +1. Update the following: + 1. `App Integration name` and `Logo` - set these to suit your needs; they'll be displayed in the Okta catalogue. + 1. `Sign-in redirect URLs`: Add `http://localhost:8085/auth/callback`. + 1. `Sign-out redirect URIs`: Add `http://localhost:8085`. + 1. Either assign groups, or choose to skip this step for now. + 1. Leave the rest of the options as-is, and save the integration. + 1. Copy the `Client ID` from the newly created app; `cliClientID: ` will be used in your `argocd-cm` ConfigMap. +1. Edit your Authorization Server `Access Policies`: + 1. Navigate to the Okta API Management at `Security > API`. + 1. Choose your existing `Authorization Server` that was created previously. + 1. Click `Access Policies` > `Edit Policy`. + 1. Assign your newly created `App Integration` by filling in the text box and clicking `Update Policy`. + ![Edit Policy](../../assets/okta-auth-policy-edit.png) + If you haven't yet created Okta groups, and assigned them to the application integration, you should do that now: 1. Go to `Directory > Groups` @@ -190,6 +209,7 @@ oidc.config: | # this is the authorization server URI issuer: https://example.okta.com/oauth2/aus9abcdefgABCDEFGd7 clientID: 0oa9abcdefgh123AB5d7 + cliClientID: gfedcba0987654321GEFDCBA # Optional if using the CLI for SSO clientSecret: ABCDEFG1234567890abcdefg requestedScopes: ["openid", "profile", "email", "groups"] requestedIDTokenClaims: {"groups": {"essential": true}} diff --git a/docs/operator-manual/user-management/onelogin.md b/docs/operator-manual/user-management/onelogin.md index 21432d7312732..fa417d42de308 100644 --- a/docs/operator-manual/user-management/onelogin.md +++ b/docs/operator-manual/user-management/onelogin.md @@ -1,7 +1,7 @@ # OneLogin !!! note "Are you using this? Please contribute!" - If you're using this IdP please consider [contributing](../../developer-guide/site.md) to this document. + If you're using this IdP please consider [contributing](../../developer-guide/docs-site.md) to this document.
diff --git a/docs/operator-manual/web_based_terminal.md b/docs/operator-manual/web_based_terminal.md index 5c791e9faa00f..3fc5807586be1 100644 --- a/docs/operator-manual/web_based_terminal.md +++ b/docs/operator-manual/web_based_terminal.md @@ -13,10 +13,20 @@ Kubernetes), then the user effectively has the same privileges as that ServiceAc ## Enabling the terminal -1. Set the `exec.enabled` key to `"true"` on the `argocd-cm` ConfigMap. +1. In the `argocd-cm` ConfigMap, set the `exec.enabled` key to `"true"`. This enables the exec feature in Argo CD. + + ``` + apiVersion: v1 + kind: ConfigMap + metadata: + name: argocd-cm + namespace: # Replace with your actual namespace + data: + exec.enabled: "true" + ``` 2. Patch the `argocd-server` Role (if using namespaced Argo) or ClusterRole (if using clustered Argo) to allow `argocd-server` -to exec into pods +to `exec` into pods - apiGroups: - "" @@ -24,14 +34,24 @@ to exec into pods - pods/exec verbs: - create + If you'd like to perform the patch imperatively, you can use the following command: + + - For namespaced Argo + ``` + kubectl patch role -n argocd - type='json' -p='[{"op": "add", "path": "/rules/-", "value": {"apiGroups": ["*"], "resources": ["pods/exec"], "verbs": ["create"]}}]' + ``` + - For clustered Argo + ```` + kubectl patch clusterrole - type='json' -p='[{"op": "add", "path": "/rules/-", "value": {"apiGroups": ["*"], "resources": ["pods/exec"], "verbs": ["create"]}}]' + ``` +3. Add RBAC rules to allow your users to `create` the `exec` resource i.e. -3. Add RBAC rules to allow your users to `create` the `exec` resource, i.e. + p, role:myrole, exec, create, */*, allow - p, role:myrole, exec, create, */*, allow + This can be added either to the `argocd-cm` `Configmap` manifest or an `AppProject` manifest. - -See [RBAC Configuration](rbac.md#exec-resource) for more info. + See [RBAC Configuration](rbac.md#exec-resource) for more info. ## Changing allowed shells diff --git a/docs/operator-manual/webhook.md b/docs/operator-manual/webhook.md index a0e6c8deba1b2..92789e983d3b3 100644 --- a/docs/operator-manual/webhook.md +++ b/docs/operator-manual/webhook.md @@ -19,6 +19,8 @@ URL configured in the Git provider should use the `/api/webhook` endpoint of you (e.g. `https://argocd.example.com/api/webhook`). If you wish to use a shared secret, input an arbitrary value in the secret. This value will be used when configuring the webhook in the next step. +To prevent DDoS attacks with unauthenticated webhook events (the `/api/webhook` endpoint currently lacks rate limiting protection), it is recommended to limit the payload size. You can achieve this by configuring the `argocd-cm` ConfigMap with the `webhook.maxPayloadSizeMB` attribute. The default value is 1GB. + ## Github ![Add Webhook](../assets/webhook-config.png "Add Webhook") diff --git a/docs/proposals/config-management-plugin-v2.md b/docs/proposals/config-management-plugin-v2.md index 549ed3967ef49..d0d2b993c7d08 100644 --- a/docs/proposals/config-management-plugin-v2.md +++ b/docs/proposals/config-management-plugin-v2.md @@ -21,6 +21,7 @@ for using additional tools such as cdk8s, Tanka, jkcfg, QBEC, Dhall, pulumi, etc ## Summary Currently, Argo CD provides first-class support for Helm, Kustomize and Jsonnet/YAML. The support includes: + - Bundled binaries (maintainers periodically upgrade binaries) - An ability to override parameters using UI/CLI - The applications are discovered in Git repository and auto-suggested during application creation in UI @@ -41,6 +42,7 @@ The goals for config management plugin enhancement are, #### Improve Installation Experience The current Config Management plugin installation experience requires two changes: + - An entry in configManagementPlugins in the Argo CD configmap (i.e. argocd-cm) - Either an init container with a volume mount that adds a new binary into Argo CD repo server pod, or a rebuild of the argocd image, which contains the necessary tooling @@ -66,13 +68,14 @@ to additional config management tools. ### Non-Goals -* We aren't planning on changing the existing support for native plugins as of now. +- We aren't planning on changing the existing support for native plugins as of now. ## Proposal We have drafted the solution to the problem statement as **running configuration management plugin tools as sidecar in the argocd-repo-server**. All it means that Argo CD Config Management Plugin 2.0 will be, + - A user-supplied container image with all the necessary tooling installed in it. - It will run as a sidecar in the repo server deployment and will have shared access to the git repositories. - It will contain a CMP YAML specification file describing how to render manifests. @@ -80,6 +83,7 @@ All it means that Argo CD Config Management Plugin 2.0 will be, based on the CMP specification file. This mechanism will provide the following benefits over the existing solution, + - Plugin owners control their execution environment, packaging whatever dependent binaries required. - An Argo CD user who wants to use additional config management tools does not have to go through the hassle of building a customized argocd-repo-server in order to install required dependencies. @@ -87,9 +91,9 @@ a customized argocd-repo-server in order to install required dependencies. ### Use cases -* UC1: As an Argo CD user, I would like to use first-class support provided for additional tools to generate and manage deployable kubernetes manifests -* UC2: As an Argo CD operator, I want to have smooth experience while installing additional tools such as cdk8s, Tanka, jkcfg, QBEC, Dhall, pulumi, etc. -* UC3: As a plugin owner, I want to have some control over the execution environment as I want to package whatever dependent binaries required. +- UC1: As an Argo CD user, I would like to use first-class support provided for additional tools to generate and manage deployable kubernetes manifests +- UC2: As an Argo CD operator, I want to have smooth experience while installing additional tools such as cdk8s, Tanka, jkcfg, QBEC, Dhall, pulumi, etc. +- UC3: As a plugin owner, I want to have some control over the execution environment as I want to package whatever dependent binaries required. ### Implementation Details @@ -143,6 +147,7 @@ volumes: Plugins will be configured via a ConfigManagementPlugin manifest located inside the plugin container, placed at a well-known location (e.g. /home/argocd/plugins/plugin.yaml). Argo CD is agnostic to the mechanism of how the plugin.yaml would be placed, but various options can be used on how to place this file, including: + - Baking the file into the plugin image as part of docker build - Volume mapping the file through a configmap. @@ -262,26 +267,27 @@ volumes: After upgrading to CMP v2, an Argo CD operator will have to make following changes, -* In order to install a plugin, an Argo CD operator will simply have to patch argocd-repo-server +- In order to install a plugin, an Argo CD operator will simply have to patch argocd-repo-server to run config management plugin container as a sidecar, with argocd-cmp-server as it’s entrypoint: -```bash -# A plugin is a container image which runs as a sidecar, with the execution environment -# necessary to render manifests. To install a plugin, -containers: -- name: cdk8s - command: [/var/run/argocd/argocd-cmp-server] - image: docker.ui/cdk8s/cdk8s:latest - volumeMounts: - - mountPath: /var/run/argocd - name: var-files -``` - -* Plugins will be configured via a ConfigManagementPlugin manifest located inside the plugin container, placed at a + ```bash + # A plugin is a container image which runs as a sidecar, with the execution environment + # necessary to render manifests. To install a plugin, + containers: + - name: cdk8s + command: [/var/run/argocd/argocd-cmp-server] + image: docker.ui/cdk8s/cdk8s:latest + volumeMounts: + - mountPath: /var/run/argocd + name: var-files + ``` + +- Plugins will be configured via a ConfigManagementPlugin manifest located inside the plugin container, placed at a well-known location (e.g. /plugin.yaml). Argo CD is agnostic to the mechanism of how the plugin.yaml would be placed, but various options can be used on how to place this file, including: - Baking the file into the plugin image as part of docker build - Volume mapping the file through a configmap. + (For more details please refer to [implementation details](#configuration)) ## Drawbacks @@ -290,34 +296,34 @@ There aren't any major drawbacks to this proposal. Also, the advantages supersed However following are few minor drawbacks, -* With addition of plugin.yaml, there will be more yamls to manage -* Operators need to be aware of the modified Kubernetes manifests in the subsequent version. -* The format of the CMP manifest is a new "contract" that would need to adhere the usual Argo CD compatibility promises in future. - +- With addition of plugin.yaml, there will be more yamls to manage +- Operators need to be aware of the modified Kubernetes manifests in the subsequent version. +- The format of the CMP manifest is a new "contract" that would need to adhere the usual Argo CD compatibility promises in future. ## Alternatives 1. ConfigManagementPlugin as CRD. Have a CR which the human operator creates: -```bash -apiVersion: argoproj.io/v1alpha1 -kind: ConfigManagementPlugin -metadata: - name: cdk8s -spec: - name: cdk8s - image: docker.ui/cdk8s/cdk8s:latest - version: v1.0 - init: - command: [cdk8s, init] - generate: - command: [sh, -c, "cdk8s synth && cat dist/*.yaml"] - discovery: - find: - - command: [find . -name main.ts] - glob: "**/*/main.ts" - check: - - command: [-f ./main.ts] - glob: "main.ts" -``` + ```bash + apiVersion: argoproj.io/v1alpha1 + kind: ConfigManagementPlugin + metadata: + name: cdk8s + spec: + name: cdk8s + image: docker.ui/cdk8s/cdk8s:latest + version: v1.0 + init: + command: [cdk8s, init] + generate: + command: [sh, -c, "cdk8s synth && cat dist/*.yaml"] + discovery: + find: + - command: [find . -name main.ts] + glob: "**/*/main.ts" + check: + - command: [-f ./main.ts] + glob: "main.ts" + ``` + 2. Something magically patches the relevant manifest to add the sidecar. diff --git a/docs/proposals/decouple-application-sync-user-using-impersonation.md b/docs/proposals/decouple-application-sync-user-using-impersonation.md index e7e459a7059c0..050c8d6b0a635 100644 --- a/docs/proposals/decouple-application-sync-user-using-impersonation.md +++ b/docs/proposals/decouple-application-sync-user-using-impersonation.md @@ -29,7 +29,7 @@ Impersonation is a feature in Kubernetes and enabled in the `kubectl` CLI client Impersonation requests first authenticate as the requesting user, then switch to the impersonated user info. -``` +```shell kubectl --as ... kubectl --as --as-group ... ``` @@ -68,8 +68,9 @@ This proposal would allow ArgoCD administrators to manage the cluster permission ### Goals - Applications may only impersonate ServiceAccounts that live in the same namespace as the destination namespace configured in the application.If the service account is created in a different namespace, then the user can provide the service account name in the format `:` . ServiceAccount to be used for syncing each application is determined by the target destination configured in the `AppProject` associated with the `Application`. -- If impersonation feature is enabled, and no service account name is provided in the associated `AppProject`, then the default service account of the destination namespace of the `Application` should be used. +- If impersonation feature is enabled, and no service account name is provided in the associated `AppProject`, then the sync operation would fail with an appropriate error message. Users can configure a catch all service account matching all destinations to avoid such sync errors. - Access restrictions implemented through properties in AppProject (if done) must have the existing behavior. From a security standpoint, any restrictions that were available before switching to a service account based approach should continue to exist even when the impersonation feature is enabled. +- The feature can be enabled/disabled only at the system level. Once enabled/disabled, it is applicable to all ArgoCD `Applications`. ### Non-Goals @@ -81,9 +82,9 @@ As part of this proposal, it would be possible for an ArgoCD Admin to specify a When applications gets synced, based on its destination (target cluster and namespace combination), the `defaultServiceAccount` configured in the `AppProject` will be selected and used for impersonation when executing the kubectl commands for the sync operation. -We would be introducing a new element `destinationServiceAccounts` in `AppProject.spec`. This element is used for the sole purpose of specifying the impersonation configuration. The `defaultServiceAccount` configured for the `AppProject` would be used for the sync operation for a particular destination cluster and namespace. If impersonation feature is enabled and no specific service account is provided in the `AppProject` CR, then the `default` service account in the destination namespace would be used for impersonation. +We would be introducing a new element `destinationServiceAccounts` in `AppProject.spec`. This element is used for the sole purpose of specifying the impersonation configuration. The `defaultServiceAccount` configured for the `AppProject` would be used for the sync operation for a particular destination cluster and namespace. If impersonation feature is enabled and no specific service account is provided in the `AppProject` CR, then the sync operation will fail with an error. Users can configure a catch all service account matching all destinations to avoid such sync errors. -``` +```yaml apiVersion: argoproj.io/v1alpha1 kind: AppProject metadata: @@ -97,7 +98,7 @@ spec: sourceRepos: - '*' destinations: - - * + - '*' destinationServiceAccounts: - server: https://kubernetes.default.svc namespace: guestbook @@ -108,6 +109,9 @@ spec: - server: https://kubernetes.default.svc namespace: guestbook-stage defaultServiceAccount: guestbook-stage-deployer + - server: '* + namespace: '*' + defaultServiceAccount: default # catch all service account to be used when all other matches fail. ``` ### Structure of DestinationServiceAccount: @@ -157,10 +161,7 @@ So that, I can use a generic convention of naming service accounts and avoid ass #### Component: ArgoCD Application Controller -- Provide a configuration in `argocd-cm` which can be modified to enable the Impersonation feature. Set `applicationcontroller.enable.impersonation: true` in the Argo CD ConfigMap. Default value of `applicationcontroller.enable.impersonation` would be `false` and user has to explicitly override it to use this feature. -- Provide an option to override the Impersonation feature using environment variables. -Set `ARGOCD_APPLICATION_CONTROLLER_ENABLE_IMPERSONATION=true` in the Application controller environment variables. Default value of the environment variable must be `false` and user has to explicitly set it to `true` to use this feature. -- Provide an option to enable this feature using a command line flag `--enable-impersonation`. This new argument option needs to be added to the Application controller args. +- Provide a configuration in `argocd-cm` which can be modified to enable the Impersonation feature. Set `application.sync.impersonation.enabled: "true"` in the Argo CD ConfigMap. Default value of `application.sync.impersonation.enabled` would be `"false"` and user has to explicitly override it to use this feature. - Fix Application Controller `sync.go` to set the Impersonate configuration from the AppProject CR to the `SyncContext` Object (rawConfig and restConfig field, need to understand which config is used for the actual sync and if both configs need to be impersonated.) #### Component: ArgoCD UI @@ -189,13 +190,13 @@ Set `ARGOCD_APPLICATION_CONTROLLER_ENABLE_IMPERSONATION=true` in the Application In this specific scenario, service account name `generic-deployer` will get used for the application sync as the namespace `guestbook` matches the glob pattern `*`. - Install ArgoCD in the `argocd` namespace. -``` +```shell kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-cd/master/manifests/install.yaml -n argocd ``` - Enable the impersonation feature in ArgoCD. -``` -kubectl set env statefulset/argocd-application-controller ARGOCD_APPLICATION_CONTROLLER_ENABLE_IMPERSONATION=true +```shell +kubectl patch cm argocd-cm -n argocd --type json --patch '[{ "op": "add", "path": "/data/application.sync.impersonation.enabled", "value": "true" }]' ``` - Create a namespace called `guestbook` and a service account called `guestbook-deployer`. @@ -205,13 +206,13 @@ kubectl create serviceaccount guestbook-deployer ``` - Create Role and RoleBindings and configure RBAC access for creating `Service` and `Deployment` objects in namespace `guestbook` for service account `guestbook-deployer`. -``` +```shell kubectl create role guestbook-deployer-role --verb get,list,update,delete --resource pods,deployment,service kubectl create rolebinding guestbook-deployer-rb --serviceaccount guestbook-deployer --role guestbook-deployer-role ``` - Create the `Application` in the `argocd` namespace and the required `AppProject` as below -``` +```yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: @@ -240,10 +241,10 @@ spec: sourceRepos: - '*' destinations: - - namespace: * + - namespace: '*' server: https://kubernetes.default.svc destinationServiceAccounts: - - namespace: * + - namespace: '*' server: https://kubernetes.default.svc defaultServiceAccount: generic-deployer ``` @@ -253,28 +254,28 @@ spec: In this specific scenario, service account name `guestbook-deployer` will get used for the application sync as the namespace `guestbook` matches the target namespace `guestbook`. - Install ArgoCD in the `argocd` namespace. -``` +```shell kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-cd/master/manifests/install.yaml -n argocd ``` - Enable the impersonation feature in ArgoCD. -``` -kubectl set env statefulset/argocd-application-controller ARGOCD_APPLICATION_CONTROLLER_ENABLE_IMPERSONATION=true +```shell +kubectl patch cm argocd-cm -n argocd --type json --patch '[{ "op": "add", "path": "/data/application.sync.impersonation.enabled", "value": "true" }]' ``` - Create a namespace called `guestbook` and a service account called `guestbook-deployer`. -``` +```shell kubectl create namespace guestbook kubectl create serviceaccount guestbook-deployer ``` - Create Role and RoleBindings and configure RBAC access for creating `Service` and `Deployment` objects in namespace `guestbook` for service account `guestbook-deployer`. -``` +```shell kubectl create role guestbook-deployer-role --verb get,list,update,delete --resource pods,deployment,service kubectl create rolebinding guestbook-deployer-rb --serviceaccount guestbook-deployer --role guestbook-deployer-role ``` In this specific scenario, service account name `guestbook-deployer` will get used as it matches to the specific namespace `guestbook`. -``` +```yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: @@ -321,23 +322,23 @@ spec: **Note**: In this example, we are relying on the default service account `argocd-manager` with `cluster-admin` privileges which gets created when adding a remote cluster destination using the ArgoCD CLI. - Install ArgoCD in the `argocd` namespace. -``` +```shell kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-cd/master/manifests/install.yaml -n argocd ``` - Enable the impersonation feature in ArgoCD. -``` -kubectl set env statefulset/argocd-application-controller ARGOCD_APPLICATION_CONTROLLER_ENABLE_IMPERSONATION=true +```shell +kubectl patch cm argocd-cm -n argocd --type json --patch '[{ "op": "add", "path": "/data/application.sync.impersonation.enabled", "value": "true" }]' ``` - Add the remote cluster as a destination to argocd -``` +```shell argocd cluster add remote-cluster --name remote-cluster ``` **Note:** The above command would create a service account named `argocd-manager` in `kube-system` namespace and `ClusterRole` named `argocd-manager-role` with full cluster admin access and a `ClusterRoleBinding` named `argocd-manager-role-binding` mapping the `argocd-manager-role` to the service account `remote-cluster` - In the remote cluster, create a namespace called `guestbook` and a service account called `guestbook-deployer`. -``` +```shell kubectl ctx remote-cluster kubectl create namespace guestbook kubectl create serviceaccount guestbook-deployer @@ -345,14 +346,14 @@ kubectl create serviceaccount guestbook-deployer - In the remote cluster, create `Role` and `RoleBindings` and configure RBAC access for creating `Service` and `Deployment` objects in namespace `guestbook` for service account `guestbook-deployer`. -``` +```shell kubectl ctx remote-cluster kubectl create role guestbook-deployer-role --verb get,list,update,delete --resource pods,deployment,service kubectl create rolebinding guestbook-deployer-rb --serviceaccount guestbook-deployer --role guestbook-deployer-role ``` - Create the `Application` and `AppProject` for the `guestbook` application. -``` +```yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: @@ -383,7 +384,6 @@ spec: destinations: - namespace: guestbook server: https://kubernetes.default.svc - serviceAccountName: guestbook-deployer destinationServiceAccounts: - namespace: guestbook server: https://kubernetes.default.svc @@ -395,17 +395,17 @@ spec: **Note**: In this example, we are relying on a non default service account `guestbook` created in the target cluster and namespace for the sync operation. This use case is for handling scenarios where the remote cluster is managed by a different administrator and providing a service account with `cluster-admin` level access is not feasible. - Install ArgoCD in the `argocd` namespace. -``` +```shell kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-cd/master/manifests/install.yaml -n argocd ``` - Enable the impersonation feature in ArgoCD. -``` -kubectl set env statefulset/argocd-application-controller ARGOCD_APPLICATION_CONTROLLER_ENABLE_IMPERSONATION=true +```shell +kubectl patch cm argocd-cm -n argocd --type json --patch '[{ "op": "add", "path": "/data/application.sync.impersonation.enabled", "value": "true" }]' ``` - In the remote cluster, create a service account called `argocd-admin` -``` +```shell kubectl ctx remote-cluster kubectl create serviceaccount argocd-admin kubectl create clusterrole argocd-admin-role --verb=impersonate --resource="users,groups,serviceaccounts" @@ -415,20 +415,20 @@ kubectl create clusterrolebinding argocd-admin-access-review-role-binding --serv ``` - In the remote cluster, create a namespace called `guestbook` and a service account called `guestbook-deployer`. -``` +```shell kubectl ctx remote-cluster kubectl create namespace guestbook kubectl create serviceaccount guestbook-deployer ``` - In the remote cluster, create `Role` and `RoleBindings` and configure RBAC access for creating `Service` and `Deployment` objects in namespace `guestbook` for service account `guestbook-deployer`. -``` +```shell kubectl create role guestbook-deployer-role --verb get,list,update,delete --resource pods,deployment,service kubectl create rolebinding guestbook-deployer-rb --serviceaccount guestbook-deployer --role guestbook-deployer-role ``` In this specific scenario, service account name `guestbook-deployer` will get used as it matches to the specific namespace `guestbook`. -``` +```yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: @@ -476,11 +476,11 @@ spec: By default, the service account would be looked up in the Application's destination namespace configured through `Application.Spec.Destination.Namespace` field. If the service account is in a different namespace, then users can provide the namespace of the service account explicitly in the format : eg: -``` +```yaml ... destinationServiceAccounts: - server: https://kubernetes.default.svc - namespace: * + namespace: '*' defaultServiceAccount: mynamespace:guestbook-deployer ... ``` @@ -491,17 +491,17 @@ If there are multiple matches for a given destination, the first valid match in eg: Lets assume that the `AppProject` has the below `destinationServiceAccounts` configured. -``` +```yaml ... destinationServiceAccounts: - server: https://kubernetes.default.svc namespace: guestbook-prod defaultServiceAccount: guestbook-prod-deployer - server: https://kubernetes.default.svc - namespace: guestbook-* + namespace: 'guestbook-*' defaultServiceAccount: guestbook-generic-deployer - server: https://kubernetes.default.svc - namespace: * + namespace: '*' defaultServiceAccount: generic-deployer ... ``` @@ -514,6 +514,55 @@ If application resources have hardcoded namespaces in the git repository, would The service account to be used for impersonation is determined on a per Application level rather than on per resource level. The value specified in `Application.spec.destination.namespace` would be used to determine the service account to be used for the sync operation of all resources present in the `Application`. +#### Application does not have a `spec.destination.namespace` field +`spec.destination.namespace` is an optional field in an `Application`. If the user does not specify it, the application controller will use the service account in the Application's namespace for the sync operation. User's also have the option of specifying the service account along with its namespace, in which case the service account in the user specified namespace will be used for the sync operation. + +eg: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: guestbook + namespace: argocd +spec: + project: my-project + source: + repoURL: https://github.com/argoproj/argocd-example-apps.git + targetRevision: HEAD + path: guestbook + destination: + server: https://kubernetes.default.svc +--- +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: my-project + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + description: Example Project + # Allow manifests to deploy from any Git repos + sourceRepos: + - '*' + destinations: + - namespace: guestbook + server: https://kubernetes.default.svc + - namespace: guestbook-ui + server: https://kubernetes.default.svc + destinationServiceAccounts: + - namespace: guestbook + server: https://kubernetes.default.svc + defaultServiceAccount: guestbook-deployer + - namespace: guestbook-ui + server: https://kubernetes.default.svc + defaultServiceAccount: guestbook-ui-deployer +``` +In the above example, since `spec.destination.namespace` is not specified, Application's namespace `argocd` is used for scoping the service account. So the service account `system:serviceaccount:argocd:guestbook-deployer` will be used for the sync operation. + +In the above example, If the matching service account is specified with a namespace, eg: `guestbook:guestbook-deployer`, then the service account `system:serviceaccount:guestbook:guestbook-deployer` will be used for the sync operation. + ### Security Considerations * How does this proposal impact the security aspects of Argo CD workloads ? @@ -553,7 +602,7 @@ Consider the following in developing an upgrade/downgrade strategy for this enha ### Option 1 Allow all options available in the `ImpersonationConfig` available to the user through the `AppProject` CRs. -``` +```yaml apiVersion: argoproj.io/v1alpha1 kind: AppProject metadata: @@ -565,7 +614,7 @@ spec: sourceRepos: - '*' destinations: - - namespace: * + - namespace: '*' server: https://kubernetes.default.svc namespace: guestbook impersonate: diff --git a/docs/proposals/resource-deletion-with-approval.md b/docs/proposals/resource-deletion-with-approval.md new file mode 100644 index 0000000000000..4d843ce08fa38 --- /dev/null +++ b/docs/proposals/resource-deletion-with-approval.md @@ -0,0 +1,171 @@ +--- +title: Neat-enhancement-idea +authors: +- "@alexmt" + sponsors: +- TBD + reviewers: +- "@jessesuen" +- TBD + approvers: +- "@jessesuen" +- TBD + +creation-date: 2020-04-19 +last-updated: 2020-04-19 + +--- +# Neat Enhancement Idea + +Support manual approval for pruning and deleting Kubernetes resources during application syncing/deletion. + +## Summary + +Introduce Kubernetes resource-level annotations that require manual user approval using Argo CD UI/CLI/API before the +resource is pruned or deleted. The annotations should be respected while Argo CD attempts to synchronize or delete the +application. + +## Motivation + +We’ve seen cases where Argo CD deleted Kubernetes resources due to a bug or misconfiguration.​ Examples include [corrupted +data](https://github.com/argoproj/argo-cd/issues/4423) in Redis, user errors +([1](https://github.com/argoproj/argo-cd/issues/9093), [2](https://github.com/argoproj/argo-cd/issues/4844)) +and [bug](https://github.com/argoproj/argo-cd/issues/3473) in the automation on top of Argo CD. These examples don’t +mean Argo CD is not reliable; however, there are cases where misbehavior is catastrophic, and erroneous deletion is not +acceptable. Examples include the app-of-apps pattern where Argo CD is used to manage itself, or namespaces in production +clusters. + +### Goals + +The goals of a proposal ares: + +#### Allow developers to mark resources that require manual approval before application deletion. + +Developers should be able to add an annotation to resources that require manual approval before deletion. The annotation +should be respected by Argo CD when it attempts to delete the application. + +#### Allow developers to mark resources that require manual approval before pruning + +Developers should be able to add an annotation to resources that require manual approval before pruning. The annotation +should be respected by Argo CD when it attempts to prune extra resources while syncing the application. + +### Non-Goals + +#### Implement automatic self check while deleting resources + +We've made our best effort to implement corrected behavior, and as of now, we are not aware of any bugs that cause +erroneous deletion. The goal of this proposal is to provide a safety net for cases where deletion is not acceptable. + +## Proposal + +It is proposed to introduce two new sync options for Argo CD applications: `Prune=confirm` and `Delete=confirm`. Options would +protect resources from accidental deletion during cascading application deletion as well as during sync operations. + +### Introduce `confirm` option for Prune sync option. + +Argo CD already supports `argocd.argoproj.io/sync-options: Prune=false` sync option that prevents resource deletion while syncing +the application. This, however, is not ideal since it prevents implementing fully automated workflows that include resource deletion. + +In order to improve the situation, we propose to introduce `confirm` option for Prune sync option. When `confirm` option is set, Argo CD should pause the sync operation +**before deleting any app resources** and wait for the user to confirm the deletion. The confirmation can be done in a very friendly way using Argo CD UI, CLI or API. + +* **Sync Operation status**. I suggest not to introduce new sync operation states to avoid disturbing the existing automation around syncing (CI pipelines, scripts etc). + If Argo CD is waiting for the operation state should remain `Progressing`. Once the user confirms the deletion, the operation should resume. +* **Sync Waves**. The sync wave shuold be "paused" while Argo CD is waiting for the user to confirm the deletion. No difference from waiting for the resource to became healthy. + +### Introduce `confirm` option for Delete sync option. + +Similarly to `Prune` sync option we need to introduce `confirm` value for `Delete` sync option: `argocd.argoproj.io/sync-options: Delete=confirm`. The `confirm` option +should pause the sync operation **before deleting any app resources** and wait for the user to confirm the deletion. The confirmation can be done in a very friendly way +using Argo CD UI, CLI or API. + + +### Friendly prunning/deletion manual approval + +Since we know Argo CD is often used to implement fully automated developer workflows that include resource deletion, the +deletion approval process should be as painless as possible. This way, platform administrators can instruct end users to +apply the new prune/delete option to resources that require special care without significantly disturbing the developer +experience. + +In both cases where Argo CD requires manual approval, the user should be able to approve the deletion using Argo CD UI, +CLI, or API. The approval process should be as simple as possible and should not require the user to understand the +internals of Argo CD. + +#### New `requiresDeletionApproval` resource field in application status + +A new field `requiresDeletionApproval` should be added to the `status.resources` list items. The field should be set to `true` when the resource deletion approval is required. + +```yaml + - health: + status: Healthy + kind: Service + name: guestbook-ui + namespace: default + status: OutOfSync + version: v1 + requiresPruning: true + requiresDeletionApproval: true # new field that indicates that deletion approval is required +``` + +The Argo CD UI, CLI should visualize the `requiresDeletionApproval` field so that the user can easily discover which resources require manual approval. + +#### Approve deletion resource action + +The Argo CD UI, CLI should bundle the `Approve Deletion` [resource action](https://argo-cd.readthedocs.io/en/stable/operator-manual/resource_actions/) +that would allow the user to approve the deletion. The action should patch the resource with the `argocd.argoproj.io/deletion-approved: true` annotation. +Once annotation is applied the Argo CD should proceed with the deletion. + +The main reason to use the action is that we can reuse existing [RBAC](https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/) to control who can approve the deletion. + +#### UI/CLI Convinience to approve all resources + +The Argo CD UI should provide a convinient way to approve resources that require manual approval. The existing user interface will provide a button that allows end user +execute the `Approve Deletion` action and approve resources one by one. In addition to the single resource approval, the UI should provide a way to approve all resources +that require manual approval. The new button should execute the `Approve Deletion` action for all resources that require manual approval. + +Argo CD CLI would no need changes since existing `argocd app actions run` command allows to execute an action against multiple resources. + +#### Require deletion approval notification + +The default Argo CD notification catalog should include a trigger and notification template that notifies the user when +deletion approval is required. The notification template should include a list of resources that require approval. + + +#### Declarative approval + +The user should be able to approve resource deletion without using the UI or CLI by manually adding the `argocd.argoproj.io/deletion-approved: true` annotation to the resource. + +### Use cases + +Add a list of detailed use cases this enhancement intends to take care of. + +## Use case 1: + +As a developer, I would like to mark resources that require manual pruning approval so I can prevent the accidental deletion of critical resources. + +## Use case 2: + +As a developer, I would like to mark resources that require manual deletion approval so I can prevent the accidental deletion of critical resources. + + +### Security Considerations + +The resource approval would require a mechanism to control who can approve the deletion. The proposal to use +resource-level actions solves this problem and allows us to reuse the existing RBAC model. + +### Risks and Mitigations + +None. + +### Upgrade / Downgrade Strategy + +In case of rollback to the previous version the sync option would be ignored and the resources would be deleted as before. + +## Open Issues + +The proposal would require end users to learn about the new behavior and adjust their workflows. It includes a set of +enhancements aimed at minimizing the impact on end users. + +## Alternatives + +None. \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt index 7245c6823c935..26b5dc2049e05 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -3,7 +3,7 @@ mkdocs==1.3.0 # Thus pointing to the older version of mkdocs-material. mkdocs-material==7.1.8 markdown_include==0.6.0 -pygments==2.15.0 +pygments==2.15.1 jinja2==3.1.4 markdown==3.3.7 pymdown-extensions==10.2.1 \ No newline at end of file diff --git a/docs/snyk/index.md b/docs/snyk/index.md index 0b14ff28d76d5..b9e7582682786 100644 --- a/docs/snyk/index.md +++ b/docs/snyk/index.md @@ -13,51 +13,66 @@ recent minor releases. | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](master/argocd-test.html) | 0 | 0 | 7 | 0 | +| [go.mod](master/argocd-test.html) | 0 | 0 | 1 | 0 | | [ui/yarn.lock](master/argocd-test.html) | 0 | 0 | 1 | 0 | -| [dex:v2.38.0](master/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 3 | -| [haproxy:2.6.17-alpine](master/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 1 | -| [redis:7.0.15-alpine](master/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 2 | 1 | -| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 3 | 11 | -| [redis:7.0.15-alpine](master/redis_7.0.15-alpine.html) | 0 | 0 | 2 | 1 | +| [dex:v2.41.1](master/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 0 | 0 | 1 | +| [haproxy:2.6.17-alpine](master/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 3 | +| [redis:7.0.15-alpine](master/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | +| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 3 | 8 | +| [redis:7.0.15-alpine](master/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | | [install.yaml](master/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](master/argocd-iac-namespace-install.html) | - | - | - | - | -### v2.11.3 +### v2.13.0-rc2 | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.11.3/argocd-test.html) | 0 | 1 | 7 | 0 | -| [ui/yarn.lock](v2.11.3/argocd-test.html) | 0 | 0 | 1 | 0 | -| [dex:v2.38.0](v2.11.3/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 3 | -| [haproxy:2.6.14-alpine](v2.11.3/haproxy_2.6.14-alpine.html) | 0 | 1 | 7 | 3 | -| [argocd:v2.11.3](v2.11.3/quay.io_argoproj_argocd_v2.11.3.html) | 0 | 0 | 4 | 19 | -| [redis:7.0.14-alpine](v2.11.3/redis_7.0.14-alpine.html) | 0 | 0 | 6 | 3 | -| [install.yaml](v2.11.3/argocd-iac-install.html) | - | - | - | - | -| [namespace-install.yaml](v2.11.3/argocd-iac-namespace-install.html) | - | - | - | - | +| [go.mod](v2.13.0-rc2/argocd-test.html) | 0 | 0 | 1 | 0 | +| [ui/yarn.lock](v2.13.0-rc2/argocd-test.html) | 0 | 0 | 1 | 0 | +| [dex:v2.41.1](v2.13.0-rc2/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 0 | 0 | 1 | +| [haproxy:2.6.17-alpine](v2.13.0-rc2/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 3 | +| [redis:7.0.15-alpine](v2.13.0-rc2/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | +| [argocd:v2.13.0-rc2](v2.13.0-rc2/quay.io_argoproj_argocd_v2.13.0-rc2.html) | 0 | 0 | 3 | 8 | +| [redis:7.0.15-alpine](v2.13.0-rc2/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | +| [install.yaml](v2.13.0-rc2/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.13.0-rc2/argocd-iac-namespace-install.html) | - | - | - | - | -### v2.10.12 +### v2.12.3 | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.10.12/argocd-test.html) | 0 | 1 | 8 | 0 | -| [ui/yarn.lock](v2.10.12/argocd-test.html) | 0 | 0 | 1 | 0 | -| [dex:v2.37.0](v2.10.12/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 1 | 10 | 3 | -| [haproxy:2.6.14-alpine](v2.10.12/haproxy_2.6.14-alpine.html) | 0 | 1 | 7 | 3 | -| [argocd:v2.10.12](v2.10.12/quay.io_argoproj_argocd_v2.10.12.html) | 0 | 0 | 4 | 19 | -| [redis:7.0.15-alpine](v2.10.12/redis_7.0.15-alpine.html) | 0 | 0 | 2 | 1 | -| [install.yaml](v2.10.12/argocd-iac-install.html) | - | - | - | - | -| [namespace-install.yaml](v2.10.12/argocd-iac-namespace-install.html) | - | - | - | - | +| [go.mod](v2.12.3/argocd-test.html) | 0 | 0 | 2 | 0 | +| [ui/yarn.lock](v2.12.3/argocd-test.html) | 0 | 1 | 2 | 0 | +| [dex:v2.38.0](v2.12.3/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 6 | +| [haproxy:2.6.17-alpine](v2.12.3/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html) | 0 | 0 | 2 | 3 | +| [redis:7.0.15-alpine](v2.12.3/public.ecr.aws_docker_library_redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | +| [argocd:v2.12.3](v2.12.3/quay.io_argoproj_argocd_v2.12.3.html) | 0 | 0 | 8 | 8 | +| [redis:7.0.15-alpine](v2.12.3/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | +| [install.yaml](v2.12.3/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.12.3/argocd-iac-namespace-install.html) | - | - | - | - | -### v2.9.17 +### v2.11.8 | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.9.17/argocd-test.html) | 0 | 2 | 8 | 0 | -| [ui/yarn.lock](v2.9.17/argocd-test.html) | 0 | 0 | 1 | 0 | -| [dex:v2.37.0](v2.9.17/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 1 | 10 | 3 | -| [haproxy:2.6.14-alpine](v2.9.17/haproxy_2.6.14-alpine.html) | 0 | 1 | 7 | 3 | -| [argocd:v2.9.17](v2.9.17/quay.io_argoproj_argocd_v2.9.17.html) | 0 | 0 | 4 | 19 | -| [redis:7.0.15-alpine](v2.9.17/redis_7.0.15-alpine.html) | 0 | 0 | 2 | 1 | -| [install.yaml](v2.9.17/argocd-iac-install.html) | - | - | - | - | -| [namespace-install.yaml](v2.9.17/argocd-iac-namespace-install.html) | - | - | - | - | +| [go.mod](v2.11.8/argocd-test.html) | 0 | 1 | 3 | 0 | +| [ui/yarn.lock](v2.11.8/argocd-test.html) | 0 | 1 | 2 | 0 | +| [dex:v2.38.0](v2.11.8/ghcr.io_dexidp_dex_v2.38.0.html) | 0 | 0 | 6 | 6 | +| [haproxy:2.6.14-alpine](v2.11.8/haproxy_2.6.14-alpine.html) | 0 | 1 | 7 | 6 | +| [argocd:v2.11.8](v2.11.8/quay.io_argoproj_argocd_v2.11.8.html) | 0 | 0 | 8 | 16 | +| [redis:7.0.15-alpine](v2.11.8/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | +| [install.yaml](v2.11.8/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.11.8/argocd-iac-namespace-install.html) | - | - | - | - | + +### v2.10.16 + +| | Critical | High | Medium | Low | +|---:|:--------:|:----:|:------:|:---:| +| [go.mod](v2.10.16/argocd-test.html) | 0 | 1 | 4 | 0 | +| [ui/yarn.lock](v2.10.16/argocd-test.html) | 0 | 1 | 2 | 0 | +| [dex:v2.37.0](v2.10.16/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 1 | 10 | 6 | +| [haproxy:2.6.14-alpine](v2.10.16/haproxy_2.6.14-alpine.html) | 0 | 1 | 7 | 6 | +| [argocd:v2.10.16](v2.10.16/quay.io_argoproj_argocd_v2.10.16.html) | 0 | 0 | 12 | 20 | +| [redis:7.0.15-alpine](v2.10.16/redis_7.0.15-alpine.html) | 0 | 0 | 0 | 0 | +| [install.yaml](v2.10.16/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.10.16/argocd-iac-namespace-install.html) | - | - | - | - | diff --git a/docs/snyk/master/argocd-iac-install.html b/docs/snyk/master/argocd-iac-install.html index 7c5eefc353e7c..4ffca011eadd2 100644 --- a/docs/snyk/master/argocd-iac-install.html +++ b/docs/snyk/master/argocd-iac-install.html @@ -456,7 +456,7 @@

Snyk test report

-

June 16th 2024, 12:18:10 am (UTC+00:00)

+

September 22nd 2024, 12:21:06 am (UTC+00:00)

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

Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Role or ClusterRole with dangerous permissions

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

    Container could be running with outdated image

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

    Container could be running with outdated image

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container is running with multiple open ports

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

    Container is running without liveness probe

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

    Container is running without liveness probe

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

    Container is running without liveness probe

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

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

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

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

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

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

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

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

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

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

    Container's or Pod's UID could clash with hos
  • - Line number: 22971 + Line number: 24320
  • diff --git a/docs/snyk/master/argocd-iac-namespace-install.html b/docs/snyk/master/argocd-iac-namespace-install.html index 2a7537570f30a..a78881186e589 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

    -

    June 16th 2024, 12:18:18 am (UTC+00:00)

    +

    September 22nd 2024, 12:21:16 am (UTC+00:00)

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

    Role or ClusterRole with dangerous permissions

  • - Line number: 162 + Line number: 164
  • @@ -599,7 +599,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 190 + Line number: 192
  • @@ -645,7 +645,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 220 + Line number: 222
  • @@ -691,7 +691,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 238 + Line number: 240
  • @@ -737,7 +737,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 256 + Line number: 258
  • @@ -783,7 +783,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 278 + Line number: 280
  • @@ -835,7 +835,7 @@

    Container could be running with outdated image

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

    Container could be running with outdated image

  • - Line number: 1411 + Line number: 1437
  • @@ -945,7 +945,7 @@

    Container has no CPU limit

  • - Line number: 673 + Line number: 675
  • @@ -1003,7 +1003,7 @@

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container has no CPU limit

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

    Container is running with multiple open ports

  • - Line number: 904 + Line number: 924
  • @@ -1571,7 +1571,7 @@

    Container is running without liveness probe

  • - Line number: 673 + Line number: 675
  • @@ -1623,7 +1623,7 @@

    Container is running without liveness probe

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

    Container is running without liveness probe

  • - Line number: 1083 + Line number: 1109
  • @@ -1733,7 +1733,7 @@

    Container is running without memory limit

  • - Line number: 673 + Line number: 675
  • @@ -1791,7 +1791,7 @@

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

    Container is running without memory limit

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

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

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

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

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

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

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

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

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

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

    Container's or Pod's UID could clash with hos
  • - Line number: 2048 + Line number: 2113
  • diff --git a/docs/snyk/master/argocd-test.html b/docs/snyk/master/argocd-test.html index 052e1be87ae85..0c91d6f1cb159 100644 --- a/docs/snyk/master/argocd-test.html +++ b/docs/snyk/master/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    June 16th 2024, 12:16:13 am (UTC+00:00)

    +

    September 22nd 2024, 12:18:54 am (UTC+00:00)

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

    Snyk test report

    -
    8 known vulnerabilities
    -
    26 vulnerable dependency paths
    -
    2059 dependencies
    +
    2 known vulnerabilities
    +
    4 vulnerable dependency paths
    +
    2132 dependencies

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

    Snyk test report

    -

    LGPL-3.0 license

    +

    Regular Expression Denial of Service (ReDoS)

    @@ -489,420 +489,21 @@

    LGPL-3.0 license

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

    Detailed paths

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

    LGPL-3.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-retryablehttp -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.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@#0802cd427621 - - 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@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - - 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@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - - 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@#0802cd427621 - - 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@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - - 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@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - - 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@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    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@#0802cd427621 - - 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@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.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@#0802cd427621 - - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + argo-cd-ui@1.0.0 - github.com/hashicorp/go-retryablehttp@0.7.4 + react-router@4.3.1 - github.com/hashicorp/go-cleanhttp@0.5.2 + path-to-regexp@1.8.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 + argo-cd-ui@1.0.0 - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + react-router-dom@4.3.1 - github.com/hashicorp/go-retryablehttp@0.7.4 + react-router@4.3.1 - github.com/hashicorp/go-cleanhttp@0.5.2 + path-to-regexp@1.8.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 + argo-cd-ui@1.0.0 - github.com/argoproj/notifications-engine/pkg/services@#0802cd427621 + argo-ui@1.0.0 - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + react-router-dom@4.3.1 - github.com/hashicorp/go-retryablehttp@0.7.4 + react-router@4.3.1 - github.com/hashicorp/go-cleanhttp@0.5.2 + path-to-regexp@1.8.0 @@ -1040,72 +558,91 @@

      Detailed paths


      -

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

    Overview

    +

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

    +

    Note: + While the 8.0.0 release has completely eliminated the vulnerable functionality, prior versions that have received the patch to mitigate backtracking may still be vulnerable if custom regular expressions are used. So it is strongly recommended for regular expression input to be controlled to avoid malicious performance degradation in those versions. This behavior is enforced as of version 7.1.0 via the strict option, which returns an error if a dangerous regular expression is detected.

    +

    Workaround

    +

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

    +

    PoC

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

    Details

    +

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

    +

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

    +

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

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

    This regular expression accomplishes the following:

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

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

    +

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

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

    MPL-2.0 license

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

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

    +

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

    +

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

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

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

    +

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

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

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

    +

    Remediation

    +

    Upgrade path-to-regexp to version 0.1.10, 1.9.0, 3.3.0, 6.3.0, 8.0.0 or higher.

    +

    References

    +
    @@ -1200,81 +737,6 @@

    References

    -
    -

    Template Injection

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

    Detailed paths

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

    Overview

    -

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

    -

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

    -

    PoC

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

    Remediation

    -

    Upgrade dompurify to version 2.4.9, 3.0.11 or higher.

    -

    References

    - - -
    - - - -
    diff --git a/docs/snyk/v2.10.12/redis_7.0.15-alpine.html b/docs/snyk/master/ghcr.io_dexidp_dex_v2.41.1.html similarity index 61% rename from docs/snyk/v2.10.12/redis_7.0.15-alpine.html rename to docs/snyk/master/ghcr.io_dexidp_dex_v2.41.1.html index b2c73a984eee9..55eb2fcbe954b 100644 --- a/docs/snyk/v2.10.12/redis_7.0.15-alpine.html +++ b/docs/snyk/master/ghcr.io_dexidp_dex_v2.41.1.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,20 +456,22 @@

    Snyk test report

    -

    June 16th 2024, 12:21:13 am (UTC+00:00)

    +

    September 22nd 2024, 12:19:01 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)
    • +
    • 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)
    -
    3 known vulnerabilities
    -
    19 vulnerable dependency paths
    -
    18 dependencies
    +
    2 known vulnerabilities
    +
    8 vulnerable dependency paths
    +
    969 dependencies
    @@ -478,7 +480,7 @@

    Snyk test report

    -

    Use After Free

    +

    Insertion of Sensitive Information into Log File

    @@ -489,125 +491,20 @@

    Use After Free

    • - Package Manager: alpine:3.20 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|redis@7.0.15-alpine and busybox/busybox@1.36.1-r28 - + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - alpine-baselayout/alpine-baselayout@3.6.5-r0 - - busybox/busybox-binsh@1.36.1-r28 - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - alpine-baselayout/alpine-baselayout@3.6.5-r0 - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/ssl_client@1.36.1-r28 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Use After Free

    -
    - -
    - medium severity -
    - -
    - -
    • - Package Manager: alpine:3.20 + Package Manager: golang
    • Vulnerable module: - busybox/busybox + google.golang.org/grpc/metadata
    • Introduced through: - docker-image|redis@7.0.15-alpine and busybox/busybox@1.36.1-r28 + github.com/hairyhenderson/gomplate/v4@* and google.golang.org/grpc/metadata@v1.64.0
    @@ -620,51 +517,9 @@

    Detailed paths

    • Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - alpine-baselayout/alpine-baselayout@3.6.5-r0 - - busybox/busybox-binsh@1.36.1-r28 - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - alpine-baselayout/alpine-baselayout@3.6.5-r0 - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine + github.com/hairyhenderson/gomplate/v4@* - busybox/ssl_client@1.36.1-r28 + google.golang.org/grpc/metadata@v1.64.0 @@ -675,26 +530,25 @@

      Detailed paths


      -

      NVD Description

      -

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

      -

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

      +

      Overview

      +

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

      +

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

      Remediation

      -

      Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

      +

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

      References


    -

    CVE-2024-4741

    +

    CVE-2024-6119

    @@ -715,7 +569,7 @@

    CVE-2024-4741

  • Introduced through: - docker-image|redis@7.0.15-alpine and openssl/libcrypto3@3.3.0-r2 + docker-image|ghcr.io/dexidp/dex@v2.41.1 and openssl/libcrypto3@3.3.1-r3
  • @@ -728,97 +582,75 @@

    Detailed paths

    • Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 - openssl/libcrypto3@3.3.0-r2 + openssl/libcrypto3@3.3.1-r3
    • Introduced through: - docker-image|redis@7.0.15-alpine - - .redis-rundeps@20240524.005525 - - openssl/libcrypto3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 apk-tools/apk-tools@2.14.4-r0 - openssl/libcrypto3@3.3.0-r2 + openssl/libcrypto3@3.3.1-r3
    • Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 - busybox/ssl_client@1.36.1-r28 + busybox/ssl_client@1.36.1-r29 - openssl/libcrypto3@3.3.0-r2 + openssl/libcrypto3@3.3.1-r3
    • Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 - .redis-rundeps@20240524.005525 + apk-tools/apk-tools@2.14.4-r0 - openssl/libssl3@3.3.0-r2 + openssl/libssl3@3.3.1-r3 - openssl/libcrypto3@3.3.0-r2 + openssl/libcrypto3@3.3.1-r3
    • Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 - openssl/libssl3@3.3.0-r2 + openssl/libssl3@3.3.1-r3
    • Introduced through: - docker-image|redis@7.0.15-alpine - - .redis-rundeps@20240524.005525 - - openssl/libssl3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 apk-tools/apk-tools@2.14.4-r0 - openssl/libssl3@3.3.0-r2 + openssl/libssl3@3.3.1-r3
    • Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 - busybox/ssl_client@1.36.1-r28 + busybox/ssl_client@1.36.1-r29 - openssl/libssl3@3.3.0-r2 + openssl/libssl3@3.3.1-r3 @@ -830,14 +662,42 @@

      Detailed paths


      NVD Description

      -

      This vulnerability has not been analyzed by NVD yet.

      +

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

      +

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

      +

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

      +

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

      +

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

      +

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

      +

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

      Remediation

      -

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

      +

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

      +

      References

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

    Snyk test report

    -

    June 16th 2024, 12:16:25 am (UTC+00:00)

    +

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

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

    Snyk test report

    -
    3 known vulnerabilities
    -
    22 vulnerable dependency paths
    +
    5 known vulnerabilities
    +
    42 vulnerable dependency paths
    18 dependencies
    @@ -882,6 +882,421 @@

    Remediation

    +
    +

    CVE-2024-5535

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

    Detailed paths

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

    NVD Description

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-6119

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

    Detailed paths

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

    NVD Description

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

    Remediation

    +

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

    +

    References

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

    Snyk test report

    -

    June 16th 2024, 12:16:29 am (UTC+00:00)

    +

    September 22nd 2024, 12:19:21 am (UTC+00:00)

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

    Snyk test report

    -
    3 known vulnerabilities
    -
    19 vulnerable dependency paths
    +
    0 known vulnerabilities
    +
    0 vulnerable dependency paths
    18 dependencies
    @@ -476,372 +476,7 @@

    Snyk test report

    -
    -
    -

    Use After Free

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.20 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine and busybox/busybox@1.36.1-r28 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - 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-r28 - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - 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-r28 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - - busybox/ssl_client@1.36.1-r28 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Use After Free

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.20 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine and busybox/busybox@1.36.1-r28 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - 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-r28 - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - 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-r28 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - - busybox/ssl_client@1.36.1-r28 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-4741

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

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - - openssl/libcrypto3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - - .redis-rundeps@20240524.005525 - - openssl/libcrypto3@3.3.0-r2 - - - -
    • -
    • - 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.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - - busybox/ssl_client@1.36.1-r28 - - openssl/libcrypto3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - - .redis-rundeps@20240524.005525 - - openssl/libssl3@3.3.0-r2 - - openssl/libcrypto3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - - openssl/libssl3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - - .redis-rundeps@20240524.005525 - - openssl/libssl3@3.3.0-r2 - - - -
    • -
    • - 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.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|public.ecr.aws/docker/library/redis@7.0.15-alpine - - busybox/ssl_client@1.36.1-r28 - - openssl/libssl3@3.3.0-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    -

    Remediation

    -

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

    - -
    - - - -
    -
    + No known vulnerabilities detected.
    diff --git a/docs/snyk/master/quay.io_argoproj_argocd_latest.html b/docs/snyk/master/quay.io_argoproj_argocd_latest.html index 39c8c86bb5d2d..b01bd7de71714 100644 --- a/docs/snyk/master/quay.io_argoproj_argocd_latest.html +++ b/docs/snyk/master/quay.io_argoproj_argocd_latest.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    June 16th 2024, 12:16:46 am (UTC+00:00)

    +

    September 22nd 2024, 12:19:38 am (UTC+00:00)

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

    Snyk test report

    -
    21 known vulnerabilities
    -
    98 vulnerable dependency paths
    -
    2290 dependencies
    +
    11 known vulnerabilities
    +
    65 vulnerable dependency paths
    +
    2355 dependencies
    @@ -481,7 +481,7 @@

    Snyk test report

    -

    CVE-2020-22916

    +

    CVE-2024-41996

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

    CVE-2020-22916

  • Vulnerable module: - xz-utils/liblzma5 + openssl/libssl3t64
  • Introduced through: - docker-image|quay.io/argoproj/argocd@latest and xz-utils/liblzma5@5.6.1+really5.4.5-1 + docker-image|quay.io/argoproj/argocd@latest and openssl/libssl3t64@3.0.13-0ubuntu3.4
  • @@ -520,7 +520,7 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - xz-utils/liblzma5@5.6.1+really5.4.5-1 + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -529,11 +529,9 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - apt@2.7.14build2 - - apt/libapt-pkg6.0t64@2.7.14build2 + coreutils@9.4-3ubuntu6 - xz-utils/liblzma5@5.6.1+really5.4.5-1 + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -542,11 +540,9 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - dash@0.5.12-6ubuntu5 - - dpkg@1.22.6ubuntu6 + cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 - xz-utils/liblzma5@5.6.1+really5.4.5-1 + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -555,93 +551,20 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - apt@2.7.14build2 - - adduser@3.137ubuntu1 - - shadow/passwd@1:4.13+dfsg1-4ubuntu3 - - pam/libpam-modules@1.5.3-5ubuntu5.1 - - systemd/libsystemd0@255.4-1ubuntu8.1 + libfido2/libfido2-1@1.14.0-1build3 - xz-utils/liblzma5@5.6.1+really5.4.5-1 + openssl/libssl3t64@3.0.13-0ubuntu3.4 - - -
    - -
    - -

    NVD Description

    -

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

    -

    An issue discovered in XZ 5.2.5 allows attackers to cause a denial of service via decompression of a crafted file. NOTE: the vendor disputes the claims of "endless output" and "denial of service" because decompression of the 17,486 bytes always results in 114,881,179 bytes, which is often a reasonable size increase.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:24.04 xz-utils.

    -

    References

    - - -
    - - - -
    -
    -

    Information Exposure

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

    Detailed paths

    - -
    • Introduced through: docker-image|quay.io/argoproj/argocd@latest - libgcrypt20@1.10.3-2build1 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -650,9 +573,11 @@

      Detailed paths

      Introduced through: docker-image|quay.io/argoproj/argocd@latest - gnupg2/dirmngr@2.4.4-2ubuntu17 + ca-certificates@20240203 - libgcrypt20@1.10.3-2build1 + openssl@3.0.13-0ubuntu3.4 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -661,20 +586,13 @@

      Detailed paths

      Introduced through: docker-image|quay.io/argoproj/argocd@latest - gnupg2/gpg@2.4.4-2ubuntu17 + git@1:2.43.0-1ubuntu7.1 - libgcrypt20@1.10.3-2build1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - gnupg2/gpg-agent@2.4.4-2ubuntu17 + libssh/libssh-4@0.10.6-2build2 - libgcrypt20@1.10.3-2build1 + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -683,11 +601,15 @@

      Detailed paths

      Introduced through: docker-image|quay.io/argoproj/argocd@latest - apt@2.7.14build2 + git@1:2.43.0-1ubuntu7.1 - apt/libapt-pkg6.0t64@2.7.14build2 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - libgcrypt20@1.10.3-2build1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -696,11 +618,15 @@

      Detailed paths

      Introduced through: docker-image|quay.io/argoproj/argocd@latest - apt@2.7.14build2 + git@1:2.43.0-1ubuntu7.1 - gnupg2/gpgv@2.4.4-2ubuntu17 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - libgcrypt20@1.10.3-2build1 + openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 + + cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.4 @@ -709,11 +635,7 @@

      Detailed paths

      Introduced through: docker-image|quay.io/argoproj/argocd@latest - gnupg2/gpg@2.4.4-2ubuntu17 - - gnupg2/gpgconf@2.4.4-2ubuntu17 - - libgcrypt20@1.10.3-2build1 + openssl@3.0.13-0ubuntu3.4 @@ -722,17 +644,9 @@

      Detailed paths

      Introduced through: docker-image|quay.io/argoproj/argocd@latest - apt@2.7.14build2 - - adduser@3.137ubuntu1 - - shadow/passwd@1:4.13+dfsg1-4ubuntu3 - - pam/libpam-modules@1.5.3-5ubuntu5.1 - - systemd/libsystemd0@255.4-1ubuntu8.1 + ca-certificates@20240203 - libgcrypt20@1.10.3-2build1 + openssl@3.0.13-0ubuntu3.4 @@ -744,28 +658,28 @@

      Detailed paths


      NVD Description

      -

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

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

      -

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

      +

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

      +

      There is no fixed version for Ubuntu:24.04 openssl.

      References


    -

    CVE-2024-26462

    +

    Information Exposure

    @@ -784,13 +698,13 @@

    CVE-2024-26462

  • Vulnerable module: - krb5/libk5crypto3 + libgcrypt20
  • Introduced through: + docker-image|quay.io/argoproj/argocd@latest and libgcrypt20@1.10.3-2build1 - docker-image|quay.io/argoproj/argocd@latest, git@1:2.43.0-1ubuntu7.1 and others
  • @@ -804,81 +718,7 @@

    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.1 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 - - krb5/libk5crypto3@1.20.1-6ubuntu2 - - - - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 - - krb5/libkrb5-3@1.20.1-6ubuntu2 - - krb5/libk5crypto3@1.20.1-6ubuntu2 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 - - krb5/libkrb5support0@1.20.1-6ubuntu2 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 - - krb5/libkrb5-3@1.20.1-6ubuntu2 - - krb5/libkrb5support0@1.20.1-6ubuntu2 - - - -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 - - krb5/libkrb5-3@1.20.1-6ubuntu2 - - krb5/libk5crypto3@1.20.1-6ubuntu2 - - krb5/libkrb5support0@1.20.1-6ubuntu2 + libgcrypt20@1.10.3-2build1 @@ -887,13 +727,9 @@

    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.1 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + gnupg2/dirmngr@2.4.4-2ubuntu17 - krb5/libkrb5-3@1.20.1-6ubuntu2 + libgcrypt20@1.10.3-2build1 @@ -902,9 +738,9 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - openssh/openssh-client@1:9.6p1-3ubuntu13 + gnupg2/gpg@2.4.4-2ubuntu17 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + libgcrypt20@1.10.3-2build1 @@ -913,11 +749,9 @@

    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.1 + gnupg2/gpg-agent@2.4.4-2ubuntu17 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + libgcrypt20@1.10.3-2build1 @@ -926,764 +760,24 @@

    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.1 + apt@2.7.14build2 - libssh/libssh-4@0.10.6-2build2 + apt/libapt-pkg6.0t64@2.7.14build2 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + libgcrypt20@1.10.3-2build1
  • Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - krb5/krb5-locales@1.20.1-6ubuntu2 - - - -
  • - - -
    - -
    - -

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:24.04 krb5.

    -

    References

    - - -
    - - - -
    -
    -

    LGPL-3.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - - gopkg.in/retry.v1@v1.0.3 - - - -
    • -
    - -
    - -
    - -

    LGPL-3.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - - github.com/r3labs/diff@v1.1.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - - github.com/hashicorp/go-version@v1.6.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    Release of Invalid Pointer or Reference

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

    Detailed paths

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

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:24.04 patch.

    -

    References

    - - -
    - - - -
    -
    -

    Double Free

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

    Detailed paths

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

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:24.04 patch.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-2511

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

    Detailed paths

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

      Detailed paths

      Introduced through: docker-image|quay.io/argoproj/argocd@latest - openssl@3.0.13-0ubuntu3.1 + gnupg2/gpg@2.4.4-2ubuntu17 + + gnupg2/gpgconf@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 @@ -1701,9 +799,17 @@

      Detailed paths

      Introduced through: docker-image|quay.io/argoproj/argocd@latest - ca-certificates@20240203 + apt@2.7.14build2 + + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3 - openssl@3.0.13-0ubuntu3.1 + pam/libpam-modules@1.5.3-5ubuntu5.1 + + systemd/libsystemd0@255.4-1ubuntu8.4 + + libgcrypt20@1.10.3-2build1 @@ -1715,50 +821,32 @@

      Detailed paths


      NVD Description

      -

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

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

      -

      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.

      +

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

      Remediation

      -

      There is no fixed version for Ubuntu:24.04 openssl.

      +

      There is no fixed version for Ubuntu:24.04 libgcrypt20.

      References


    -
    -

    CVE-2024-4603

    +
    +

    CVE-2024-26462

    -
    - low severity +
    + medium severity

    @@ -1773,13 +861,13 @@

    CVE-2024-4603

  • Vulnerable module: - openssl/libssl3t64 + krb5/libk5crypto3
  • Introduced through: - docker-image|quay.io/argoproj/argocd@latest and openssl/libssl3t64@3.0.13-0ubuntu3.1 + docker-image|quay.io/argoproj/argocd@latest, git@1:2.43.0-1ubuntu7.1 and others
  • @@ -1793,18 +881,13 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - openssl/libssl3t64@3.0.13-0ubuntu3.1 - - - - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest + git@1:2.43.0-1ubuntu7.1 - coreutils@9.4-3ubuntu6 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - openssl/libssl3t64@3.0.13-0ubuntu3.1 + krb5/libk5crypto3@1.20.1-6ubuntu2.1 @@ -1813,9 +896,15 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3 + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl/libssl3t64@3.0.13-0ubuntu3.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 @@ -1824,9 +913,13 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - libfido2/libfido2-1@1.14.0-1build3 + git@1:2.43.0-1ubuntu7.1 - openssl/libssl3t64@3.0.13-0ubuntu3.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 @@ -1835,9 +928,15 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - openssh/openssh-client@1:9.6p1-3ubuntu13 + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl/libssl3t64@3.0.13-0ubuntu3.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 @@ -1846,11 +945,17 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - ca-certificates@20240203 + git@1:2.43.0-1ubuntu7.1 - openssl@3.0.13-0ubuntu3.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl/libssl3t64@3.0.13-0ubuntu3.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 @@ -1861,11 +966,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - libssh/libssh-4@0.10.6-2build2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - openssl/libssl3t64@3.0.13-0ubuntu3.1 + krb5/libkrb5-3@1.20.1-6ubuntu2.1 @@ -1874,15 +979,9 @@

    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.1 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 - - krb5/libkrb5-3@1.20.1-6ubuntu2 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 - openssl/libssl3t64@3.0.13-0ubuntu3.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1893,13 +992,9 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 - - cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3 - - openssl/libssl3t64@3.0.13-0ubuntu3.1 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1908,7 +1003,13 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - openssl@3.0.13-0ubuntu3.1 + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + libssh/libssh-4@0.10.6-2build2 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -1917,9 +1018,7 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - ca-certificates@20240203 - - openssl@3.0.13-0ubuntu3.1 + krb5/krb5-locales@1.20.1-6ubuntu2.1 @@ -1931,53 +1030,27 @@

    Detailed paths


    NVD Description

    -

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

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

    -

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

    +

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

    +

    There is no fixed version for Ubuntu:24.04 krb5.

    References


  • -

    CVE-2024-4741

    +

    Release of Invalid Pointer or Reference

    @@ -1996,12 +1069,12 @@

    CVE-2024-4741

  • Vulnerable module: - openssl/libssl3t64 + patch
  • Introduced through: - docker-image|quay.io/argoproj/argocd@latest and openssl/libssl3t64@3.0.13-0ubuntu3.1 + docker-image|quay.io/argoproj/argocd@latest and patch@2.7.6-7build3
  • @@ -2016,133 +1089,77 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - openssl/libssl3t64@3.0.13-0ubuntu3.1 + patch@2.7.6-7build3 -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - coreutils@9.4-3ubuntu6 - - openssl/libssl3t64@3.0.13-0ubuntu3.1 - - + -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3 - - openssl/libssl3t64@3.0.13-0ubuntu3.1 - - +
  • - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - libfido2/libfido2-1@1.14.0-1build3 - - openssl/libssl3t64@3.0.13-0ubuntu3.1 - - +
    + +

    NVD Description

    +

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

    +

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

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 patch.

    +

    References

    + -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - openssh/openssh-client@1:9.6p1-3ubuntu13 - - openssl/libssl3t64@3.0.13-0ubuntu3.1 - - +
    -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - ca-certificates@20240203 - - openssl@3.0.13-0ubuntu3.1 - - openssl/libssl3t64@3.0.13-0ubuntu3.1 - - + -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 - - libssh/libssh-4@0.10.6-2build2 - - openssl/libssl3t64@3.0.13-0ubuntu3.1 - - +
  • +
    +

    Double Free

    +
    - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 - - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 - - krb5/libkrb5-3@1.20.1-6ubuntu2 - - openssl/libssl3t64@3.0.13-0ubuntu3.1 - - +
    + low severity +
    -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - git@1:2.43.0-1ubuntu7.1 - - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 - - openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 - - cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3 - - openssl/libssl3t64@3.0.13-0ubuntu3.1 - - +
    -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - openssl@3.0.13-0ubuntu3.1 - - +
      +
    • + Manifest file: quay.io/argoproj/argocd:latest/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: -
    • + patch + + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@latest and patch@2.7.6-7build3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
  • @@ -2211,11 +1236,11 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - krb5/libk5crypto3@1.20.1-6ubuntu2 + krb5/libk5crypto3@1.20.1-6ubuntu2.1 @@ -2226,13 +1251,13 @@

    Detailed paths

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

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - krb5/libkrb5support0@1.20.1-6ubuntu2 + krb5/libkrb5support0@1.20.1-6ubuntu2.1 @@ -2258,13 +1283,13 @@

    Detailed paths

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

    Detailed paths

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

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - krb5/libkrb5-3@1.20.1-6ubuntu2 + krb5/libkrb5-3@1.20.1-6ubuntu2.1 @@ -2307,9 +1332,9 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - openssh/openssh-client@1:9.6p1-3ubuntu13 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -2320,9 +1345,9 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -2333,11 +1358,11 @@

    Detailed paths

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

    Detailed paths

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

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - krb5/libk5crypto3@1.20.1-6ubuntu2 + krb5/libk5crypto3@1.20.1-6ubuntu2.1 @@ -2434,13 +1459,13 @@

    Detailed paths

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

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - krb5/libkrb5support0@1.20.1-6ubuntu2 + krb5/libkrb5support0@1.20.1-6ubuntu2.1 @@ -2466,13 +1491,13 @@

    Detailed paths

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

    Detailed paths

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

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - krb5/libkrb5-3@1.20.1-6ubuntu2 + krb5/libkrb5-3@1.20.1-6ubuntu2.1 @@ -2515,9 +1540,9 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - openssh/openssh-client@1:9.6p1-3ubuntu13 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -2528,9 +1553,9 @@

    Detailed paths

    git@1:2.43.0-1ubuntu7.1 - curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.1 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - krb5/libgssapi-krb5-2@1.20.1-6ubuntu2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 @@ -2541,11 +1566,11 @@

    Detailed paths

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

    Detailed paths

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

    Allocation of Resources Without Limits or Throttling

    Introduced through: - docker-image|quay.io/argoproj/argocd@latest and glibc/libc-bin@2.39-0ubuntu8.2 + docker-image|quay.io/argoproj/argocd@latest and glibc/libc-bin@2.39-0ubuntu8.3 @@ -2771,7 +1796,7 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - glibc/libc-bin@2.39-0ubuntu8.2 + glibc/libc-bin@2.39-0ubuntu8.3 @@ -2780,7 +1805,7 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - glibc/libc6@2.39-0ubuntu8.2 + glibc/libc6@2.39-0ubuntu8.3 @@ -2800,9 +1825,9 @@

    Remediation

    References


    @@ -2872,7 +1897,7 @@

    Detailed paths

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

    Snyk test report

    -

    June 16th 2024, 12:16:50 am (UTC+00:00)

    +

    September 22nd 2024, 12:19:42 am (UTC+00:00)

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

    Snyk test report

    -
    3 known vulnerabilities
    -
    19 vulnerable dependency paths
    +
    0 known vulnerabilities
    +
    0 vulnerable dependency paths
    18 dependencies
    @@ -476,372 +476,7 @@

    Snyk test report

    -
    -
    -

    Use After Free

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.20 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|redis@7.0.15-alpine and busybox/busybox@1.36.1-r28 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - alpine-baselayout/alpine-baselayout@3.6.5-r0 - - busybox/busybox-binsh@1.36.1-r28 - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - alpine-baselayout/alpine-baselayout@3.6.5-r0 - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/ssl_client@1.36.1-r28 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Use After Free

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.20 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|redis@7.0.15-alpine and busybox/busybox@1.36.1-r28 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - alpine-baselayout/alpine-baselayout@3.6.5-r0 - - busybox/busybox-binsh@1.36.1-r28 - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - alpine-baselayout/alpine-baselayout@3.6.5-r0 - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/ssl_client@1.36.1-r28 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-4741

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

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - openssl/libcrypto3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - .redis-rundeps@20240524.005525 - - openssl/libcrypto3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - apk-tools/apk-tools@2.14.4-r0 - - openssl/libcrypto3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/ssl_client@1.36.1-r28 - - openssl/libcrypto3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - .redis-rundeps@20240524.005525 - - openssl/libssl3@3.3.0-r2 - - openssl/libcrypto3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - openssl/libssl3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - .redis-rundeps@20240524.005525 - - openssl/libssl3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - apk-tools/apk-tools@2.14.4-r0 - - openssl/libssl3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/ssl_client@1.36.1-r28 - - openssl/libssl3@3.3.0-r2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    -

    Remediation

    -

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

    - -
    - - - -
    -
    + No known vulnerabilities detected.
    diff --git a/docs/snyk/v2.10.12/quay.io_argoproj_argocd_v2.10.12.html b/docs/snyk/v2.10.12/quay.io_argoproj_argocd_v2.10.12.html deleted file mode 100644 index ad04736403f86..0000000000000 --- a/docs/snyk/v2.10.12/quay.io_argoproj_argocd_v2.10.12.html +++ /dev/null @@ -1,4775 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
    -
    -
    -
    - - - Snyk - Open Source Security - - - - - - - -
    -

    Snyk test report

    - -

    June 16th 2024, 12:21:08 am (UTC+00:00)

    -
    -
    - Scanned the following paths: -
      -
    • quay.io/argoproj/argocd:v2.10.12/argoproj/argocd/Dockerfile (deb)
    • -
    • quay.io/argoproj/argocd:v2.10.12/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.10.12//usr/local/bin/kustomize (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.10.12/helm/v3//usr/local/bin/helm (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.10.12/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    • -
    -
    - -
    -
    31 known vulnerabilities
    -
    197 vulnerable dependency paths
    -
    2278 dependencies
    -
    -
    -
    -
    - -
    -
    -
    -

    Allocation of Resources Without Limits or Throttling

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - - golang.org/x/net/http2@v0.19.0 - - - -
    • -
    • - Introduced through: - helm.sh/helm/v3@* - - golang.org/x/net/http2@v0.17.0 - - - -
    • -
    - -
    - -
    - -

    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

    - - -
    - - - -
    -
    -

    CVE-2020-22916

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.12/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - xz-utils/liblzma5 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.12 and xz-utils/liblzma5@5.2.5-2ubuntu1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - xz-utils/liblzma5@5.2.5-2ubuntu1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    An issue discovered in XZ 5.2.5 allows attackers to cause a denial of service via decompression of a crafted file. NOTE: the vendor disputes the claims of "endless output" and "denial of service" because decompression of the 17,486 bytes always results in 114,881,179 bytes, which is often a reasonable size increase.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 xz-utils.

    -

    References

    - - -
    - - - -
    -
    -

    Resource Exhaustion

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

    Detailed paths

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

    NVD Description

    -

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

    -

    The Diffie-Hellman Key Agreement Protocol allows use of long exponents that arguably make certain calculations unnecessarily expensive, because the 1996 van Oorschot and Wiener paper found that "(appropriately) short exponents" can be used when there are adequate subgroup constraints, and these short exponents can lead to less expensive calculations than for long exponents. This issue is different from CVE-2002-20001 because it is based on an observation about exponent size, rather than an observation about numbers that are not public keys. The specific situations in which calculation expense would constitute a server-side vulnerability depend on the protocol (e.g., TLS, SSH, or IKE) and the DHE implementation details. In general, there might be an availability concern because of server-side resource consumption from DHE modular-exponentiation calculations. Finally, it is possible for an attacker to exploit this vulnerability and CVE-2002-20001 together.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssl.

    -

    References

    - - -
    - - - -
    -
    -

    Information Exposure

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.12/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - libgcrypt20 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.12 and libgcrypt20@1.9.4-3ubuntu3 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/dirmngr@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/gpg@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - apt@2.4.12 - - apt/libapt-pkg6.0@2.4.12 - - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - apt@2.4.12 - - gnupg2/gpgv@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/gpg@2.2.27-3ubuntu2.1 - - gnupg2/gpgconf@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 - - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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.10.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.10.12 - - apt@2.4.12 - - apt/libapt-pkg6.0@2.4.12 - - systemd/libsystemd0@249.11-0ubuntu3.12 - - libgcrypt20@1.9.4-3ubuntu3 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 libgcrypt20.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-26462

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

    Detailed paths

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

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 krb5.

    -

    References

    - - -
    - - - -
    -
    -

    LGPL-3.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.12/argoproj/argo-cd/v2 /usr/local/bin/argocd -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - gopkg.in/retry.v1 -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and gopkg.in/retry.v1@v1.0.3 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - - gopkg.in/retry.v1@v1.0.3 - - - -
    • -
    - -
    - -
    - -

    LGPL-3.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.12/argoproj/argo-cd/v2 /usr/local/bin/argocd -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/r3labs/diff -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/r3labs/diff@v1.1.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - - github.com/r3labs/diff@v1.1.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.12/argoproj/argo-cd/v2 /usr/local/bin/argocd -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-version -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-version@v1.2.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - - github.com/hashicorp/go-version@v1.2.1 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    CVE-2023-7008

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

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - systemd/libsystemd0@249.11-0ubuntu3.12 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - apt@2.4.12 - - systemd/libsystemd0@249.11-0ubuntu3.12 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - procps/libprocps8@2:3.3.17-6ubuntu2.1 - - systemd/libsystemd0@249.11-0ubuntu3.12 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - util-linux@2.37.2-4ubuntu3.4 - - systemd/libsystemd0@249.11-0ubuntu3.12 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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.10.12 - - apt@2.4.12 - - apt/libapt-pkg6.0@2.4.12 - - systemd/libsystemd0@249.11-0ubuntu3.12 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - systemd/libudev1@249.11-0ubuntu3.12 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - libfido2/libfido2-1@1.10.0-1 - - systemd/libudev1@249.11-0ubuntu3.12 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - util-linux@2.37.2-4ubuntu3.4 - - systemd/libudev1@249.11-0ubuntu3.12 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - apt@2.4.12 - - apt/libapt-pkg6.0@2.4.12 - - 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.10.12/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - shadow/passwd -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.12 and shadow/passwd@1:4.8.1-2ubuntu2.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - openssh/openssh-client@1:8.9p1-3ubuntu0.7 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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.10.12/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - pcre3/libpcre3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.12 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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

    - - -
    - - - -
    -
    -

    Release of Invalid Pointer or Reference

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.12/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - patch -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.12 and patch@2.7.6-7build2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - patch@2.7.6-7build2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 patch.

    -

    References

    - - -
    - - - -
    -
    -

    Double Free

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.12/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - patch -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.12 and patch@2.7.6-7build2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - patch@2.7.6-7build2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 patch.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-2511

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

    Detailed paths

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

    NVD Description

    -

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

    -

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

    -

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

    -

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

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssl.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-4603

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

    Detailed paths

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

    NVD Description

    -

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

    -

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

    -

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

    -

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

    -

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

    -

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

    -

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

    -

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

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssl.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-4741

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

    Detailed paths

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

    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssl.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2023-50495

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.12/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - ncurses/libtinfo6 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.12 and ncurses/libtinfo6@6.3-2ubuntu0.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - bash@5.1-6ubuntu1.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - less@590-1ubuntu0.22.04.3 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - libedit/libedit2@3.1-20210910-1build1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/libncurses6@6.3-2ubuntu0.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/ncurses-bin@6.3-2ubuntu0.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - procps@2:3.3.17-6ubuntu2.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - util-linux@2.37.2-4ubuntu3.4 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - 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.10.12 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 - - pinentry/pinentry-curses@1.1.1-1build2 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - procps@2:3.3.17-6ubuntu2.1 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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.10.12 - - ncurses/libncurses6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - procps@2:3.3.17-6ubuntu2.1 - - ncurses/libncurses6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/ncurses-base@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/ncurses-bin@6.3-2ubuntu0.1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 ncurses.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2023-45918

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.12/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - ncurses/libtinfo6 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.12 and ncurses/libtinfo6@6.3-2ubuntu0.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - bash@5.1-6ubuntu1.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - less@590-1ubuntu0.22.04.3 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - libedit/libedit2@3.1-20210910-1build1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/libncurses6@6.3-2ubuntu0.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/ncurses-bin@6.3-2ubuntu0.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - procps@2:3.3.17-6ubuntu2.1 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - util-linux@2.37.2-4ubuntu3.4 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - 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.10.12 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 - - pinentry/pinentry-curses@1.1.1-1build2 - - ncurses/libtinfo6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - procps@2:3.3.17-6ubuntu2.1 - - ncurses/libncursesw6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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.10.12 - - ncurses/libncurses6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - procps@2:3.3.17-6ubuntu2.1 - - ncurses/libncurses6@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/ncurses-base@6.3-2ubuntu0.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - ncurses/ncurses-bin@6.3-2ubuntu0.1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    ncurses 6.4-20230610 has a NULL pointer dereference in tgetstr in tinfo/lib_termcap.c.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 ncurses.

    -

    References

    - - -
    - - - -
    -
    -

    Resource Exhaustion

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

    Detailed paths

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

    - - -
    - - - -
    -
    -

    Integer Overflow or Wraparound

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

    Detailed paths

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

    NVD Description

    -

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

    -

    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

    -

    There is no fixed version for Ubuntu:22.04 krb5.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-26461

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

    Detailed paths

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

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 krb5.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-26458

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

    Detailed paths

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

    NVD Description

    -

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

    -

    Kerberos 5 (aka krb5) 1.21.2 contains a memory leak in /krb5/src/lib/rpc/pmap_rmt.c.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 krb5.

    -

    References

    - - -
    - - - -
    -
    -

    Out-of-bounds Write

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.12/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - gnupg2/gpgv -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.12 and gnupg2/gpgv@2.2.27-3ubuntu2.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/gpgv@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - apt@2.4.12 - - gnupg2/gpgv@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpgv@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/dirmngr@2.2.27-3ubuntu2.1 - - gnupg2/gpgconf@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/gpg@2.2.27-3ubuntu2.1 - - gnupg2/gpgconf@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - 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.10.12 - - 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.10.12 - - gnupg2/dirmngr@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/dirmngr@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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.10.12 - - gnupg2/gnupg-l10n@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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.10.12 - - gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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.10.12 - - gnupg2/gpg@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpg@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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.10.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.10.12 - - gnupg2/gpg-agent@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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.10.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.10.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.10.12 - - gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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.10.12 - - gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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.10.12 - - gnupg2/gpgsm@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - gnupg2/gpgsm@2.2.27-3ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gnupg2/gnupg@2.2.27-3ubuntu2.1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    GnuPG can be made to spin on a relatively small input by (for example) crafting a public key with thousands of signatures attached, compressed down to just a few KB.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 gnupg2.

    -

    References

    - - -
    - - - -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.12/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - glibc/libc-bin -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.12 and glibc/libc-bin@2.35-0ubuntu3.8 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - glibc/libc-bin@2.35-0ubuntu3.8 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - glibc/libc6@2.35-0ubuntu3.8 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    sha256crypt and sha512crypt through 0.6 allow attackers to cause a denial of service (CPU consumption) because the algorithm's runtime is proportional to the square of the length of the password.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 glibc.

    -

    References

    - - -
    - - - -
    -
    -

    Improper Input Validation

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

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - git@1:2.34.1-1ubuntu1.11 - - git/git-man@1:2.34.1-1ubuntu1.11 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - git@1:2.34.1-1ubuntu1.11 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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.10.12/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - gcc-12/libstdc++6 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.12 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - apt@2.4.12 - - gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - apt@2.4.12 - - apt/libapt-pkg6.0@2.4.12 - - gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - gcc-12/gcc-12-base@12.3.0-1ubuntu1~22.04 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.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

    - - -
    - - - -
    -
    -

    Improper Input Validation

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.10.12/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - coreutils -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.10.12 and coreutils@8.32-4.1ubuntu1.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.10.12 - - coreutils@8.32-4.1ubuntu1.2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    chroot in GNU coreutils, when used with --userspec, allows local users to escape to the parent session via a crafted TIOCSTI ioctl call, which pushes characters to the terminal's input buffer.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 coreutils.

    -

    References

    - - -
    - - - -
    -
    -
    -
    - - - diff --git a/docs/snyk/v2.10.12/argocd-iac-install.html b/docs/snyk/v2.10.16/argocd-iac-install.html similarity index 99% rename from docs/snyk/v2.10.12/argocd-iac-install.html rename to docs/snyk/v2.10.16/argocd-iac-install.html index 6a8ba1ca661f5..caf0aceb5972f 100644 --- a/docs/snyk/v2.10.12/argocd-iac-install.html +++ b/docs/snyk/v2.10.16/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    June 16th 2024, 12:22:32 am (UTC+00:00)

    +

    September 22nd 2024, 12:30:18 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.10.12/argocd-iac-namespace-install.html b/docs/snyk/v2.10.16/argocd-iac-namespace-install.html similarity index 99% rename from docs/snyk/v2.10.12/argocd-iac-namespace-install.html rename to docs/snyk/v2.10.16/argocd-iac-namespace-install.html index 3cd5485060f32..1a15c2d0c5416 100644 --- a/docs/snyk/v2.10.12/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.10.16/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    June 16th 2024, 12:22:41 am (UTC+00:00)

    +

    September 22nd 2024, 12:30:27 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.10.12/argocd-test.html b/docs/snyk/v2.10.16/argocd-test.html similarity index 91% rename from docs/snyk/v2.10.12/argocd-test.html rename to docs/snyk/v2.10.16/argocd-test.html index ddb502a8683df..82f63569dbd39 100644 --- a/docs/snyk/v2.10.12/argocd-test.html +++ b/docs/snyk/v2.10.16/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    June 16th 2024, 12:20:42 am (UTC+00:00)

    +

    September 22nd 2024, 12:28:24 am (UTC+00:00)

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

    Snyk test report

    -
    10 known vulnerabilities
    -
    171 vulnerable dependency paths
    +
    8 known vulnerabilities
    +
    164 vulnerable dependency paths
    2042 dependencies
    @@ -1130,7 +1130,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/common@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/common@#b6ec82aedce5 k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 @@ -1317,7 +1317,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/cache@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/cache@#b6ec82aedce5 k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -1334,7 +1334,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync@#b6ec82aedce5 k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -1351,7 +1351,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -1559,7 +1559,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/ignore@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/ignore@#b6ec82aedce5 k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 @@ -1578,7 +1578,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#b6ec82aedce5 k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 @@ -1597,7 +1597,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/utils/testing@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/testing@#b6ec82aedce5 k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 @@ -1692,7 +1692,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/health@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/health@#b6ec82aedce5 k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 @@ -1882,9 +1882,9 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/health@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/health@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -1901,9 +1901,9 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/common@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/common@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -2034,7 +2034,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/diff@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/diff@#b6ec82aedce5 k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 @@ -2139,11 +2139,11 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/hook@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/sync/common@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/common@#b6ec82aedce5 k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 @@ -2485,7 +2485,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/diff@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/diff@#b6ec82aedce5 k8s.io/kubectl/pkg/cmd/util@0.26.11 @@ -2508,13 +2508,13 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/hook@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/sync/common@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/common@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -2531,13 +2531,13 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/sync/common@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/common@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -2748,7 +2748,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#b6ec82aedce5 k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 @@ -2848,15 +2848,15 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/ignore@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/ignore@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/sync/hook@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/sync/common@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/common@#b6ec82aedce5 - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -2948,7 +2948,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/cache@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/cache@#b6ec82aedce5 k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -2975,7 +2975,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync@#b6ec82aedce5 k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -3002,7 +3002,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#b6ec82aedce5 k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -3139,9 +3139,163 @@

    References

    More about this vulnerability

    +
    +
    +

    Prototype Pollution

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

    Detailed paths

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

    Overview

    +

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

    +

    Affected versions of this package are vulnerable to Prototype Pollution due to improper user input sanitization through the depth-checking mechanism, an attacker can exploit this vulnerability by using special nesting techniques to create a malicious HTML file.

    +

    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 dompurify to version 2.5.4, 3.1.3 or higher.

    +

    References

    + + +
    + + +
    -

    LGPL-3.0 license

    +

    Regular Expression Denial of Service (ReDoS)

    @@ -3152,21 +3306,21 @@

    LGPL-3.0 license

    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod + Manifest file: /argo-cd ui/yarn.lock
    • - Package Manager: golang + Package Manager: npm
    • - Module: + Vulnerable module: - gopkg.in/retry.v1 + path-to-regexp
    • Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others + argo-cd-ui@1.0.0, react-router@4.3.1 and others
    @@ -3178,11 +3332,39 @@

    Detailed paths

    • Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 + argo-cd-ui@1.0.0 - github.com/Azure/kubelogin/pkg/token@0.0.20 + react-router@4.3.1 + + path-to-regexp@1.8.0 + + + +
    • +
    • + Introduced through: + argo-cd-ui@1.0.0 + + react-router-dom@4.3.1 + + react-router@4.3.1 + + path-to-regexp@1.8.0 + + + +
    • +
    • + Introduced through: + argo-cd-ui@1.0.0 + + argo-ui@1.0.0 + + react-router-dom@4.3.1 - gopkg.in/retry.v1@1.0.3 + react-router@4.3.1 + + path-to-regexp@1.8.0 @@ -3193,12 +3375,91 @@

      Detailed paths


      -

      LGPL-3.0 license

      +

      Overview

      +

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

      +

      Note: + While the 8.0.0 release has completely eliminated the vulnerable functionality, prior versions that have received the patch to mitigate backtracking may still be vulnerable if custom regular expressions are used. So it is strongly recommended for regular expression input to be controlled to avoid malicious performance degradation in those versions. This behavior is enforced as of version 7.1.0 via the strict option, which returns an error if a dangerous regular expression is detected.

      +

      Workaround

      +

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

      +

      PoC

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

      Details

      +

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

      +

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

      +

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

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

      This regular expression accomplishes the following:

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

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

      +

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

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

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

      +

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

      +

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

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

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

      +

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

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

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

      +

      Remediation

      +

      Upgrade path-to-regexp to version 0.1.10, 1.9.0, 3.3.0, 6.3.0, 8.0.0 or higher.

      +

      References

      +
    @@ -3418,7 +3679,7 @@

    References

    -

    MPL-2.0 license

    +

    Denial of Service (DoS)

    @@ -3435,15 +3696,15 @@

    MPL-2.0 license

    Package Manager: golang
  • - Module: + Vulnerable module: - github.com/r3labs/diff + github.com/rs/cors
  • Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/r3labs/diff@1.1.0 + github.com/argoproj/argo-cd/v2@0.0.0, github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 and others
  • @@ -3457,7 +3718,9 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/r3labs/diff@1.1.0 + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + github.com/rs/cors@1.9.0 @@ -3468,79 +3731,67 @@

    Detailed paths


    -

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

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

    MPL-2.0 license

    + 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

    +

    Insertion of Sensitive Information into Log File

    @@ -3557,7 +3808,7 @@

    MPL-2.0 license

    Package Manager: golang
  • - Module: + Vulnerable module: github.com/hashicorp/go-retryablehttp
  • @@ -3745,245 +3996,20 @@

    Detailed paths


    -

    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@#84b9f7913604 - - 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@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - github.com/hashicorp/go-cleanhttp@0.5.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.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@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - github.com/hashicorp/go-cleanhttp@0.5.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#84b9f7913604 - - github.com/argoproj/notifications-engine/pkg/services@#84b9f7913604 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.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

    +

    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

    +
    diff --git a/docs/snyk/v2.10.12/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.10.16/ghcr.io_dexidp_dex_v2.37.0.html similarity index 82% rename from docs/snyk/v2.10.12/ghcr.io_dexidp_dex_v2.37.0.html rename to docs/snyk/v2.10.16/ghcr.io_dexidp_dex_v2.37.0.html index 61dda6fca436a..f6beb50189acb 100644 --- a/docs/snyk/v2.10.12/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.10.16/ghcr.io_dexidp_dex_v2.37.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    June 16th 2024, 12:20:48 am (UTC+00:00)

    +

    September 22nd 2024, 12:28:32 am (UTC+00:00)

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

    Snyk test report

    -
    49 known vulnerabilities
    -
    157 vulnerable dependency paths
    +
    33 known vulnerabilities
    +
    138 vulnerable dependency paths
    786 dependencies
    @@ -821,9 +821,9 @@

    References

  • http://www.openwall.com/lists/oss-security/2023/10/24/1
  • https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=0df40630850fb2740e6be6890bb905d3fc623b2d
  • https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=5f69f5c65e483928c4b28ed16af6e5742929f1ee
  • +
  • https://security.netapp.com/advisory/ntap-20231027-0010/
  • https://www.debian.org/security/2023/dsa-5532
  • https://www.openssl.org/news/secadv/20231024.txt
  • -
  • https://security.netapp.com/advisory/ntap-20231027-0010/
  • https://security.netapp.com/advisory/ntap-20240201-0003/
  • https://security.netapp.com/advisory/ntap-20240201-0004/
  • @@ -1386,12 +1386,12 @@

    Remediation

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

    References

    @@ -1545,17 +1545,17 @@

    Remediation

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

    References

    @@ -1708,13 +1708,13 @@

    Remediation

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

    References


    @@ -1876,12 +1877,12 @@

    Remediation

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

    References

    @@ -2041,11 +2042,11 @@

    Remediation

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

    References

    -

    MPL-2.0 license

    +

    Insertion of Sensitive Information into Log File

    @@ -2774,14 +2775,14 @@

    MPL-2.0 license

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

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0 - - - - -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/compressutil@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/consts@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/jsonutil@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/pluginutil@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/strutil@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/logical@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/physical@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/physical/inmem@v0.5.0 + github.com/hashicorp/go-retryablehttp@v0.7.1 @@ -2879,17 +2808,25 @@

    Detailed paths


    -

    MPL-2.0 license

    +

    Overview

    +

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

    +

    Remediation

    +

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

    +

    References

    +
  • -

    MPL-2.0 license

    +

    Improper Handling of Highly Compressed Data (Data Amplification)

    @@ -2900,20 +2837,20 @@

    MPL-2.0 license

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.37.0/dexidp/dex /usr/local/bin/dex
    • Package Manager: golang
    • - Module: + Vulnerable module: - github.com/hashicorp/vault/api + github.com/go-jose/go-jose/v3
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/api@v1.6.0 + github.com/dexidp/dex@* and github.com/go-jose/go-jose/v3@v3.0.0
    @@ -2926,9 +2863,9 @@

    Detailed paths

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

      Detailed paths


      -

      MPL-2.0 license

      +

      Overview

      +

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

      +

      Remediation

      +

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

      +

      References

      +
    -

    MPL-2.0 license

    +

    Uncontrolled Resource Consumption ('Resource Exhaustion')

    @@ -2966,14 +2912,14 @@

    MPL-2.0 license

    Package Manager: golang
  • - Module: + Vulnerable module: - github.com/hashicorp/serf/coordinate + github.com/go-git/go-git/v5/plumbing
  • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/serf/coordinate@v0.9.7 + github.com/hairyhenderson/gomplate/v3@* and github.com/go-git/go-git/v5/plumbing@v5.4.2
  • @@ -2988,7 +2934,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - github.com/hashicorp/serf/coordinate@v0.9.7 + github.com/go-git/go-git/v5/plumbing@v5.4.2 @@ -2999,17 +2945,41 @@

    Detailed paths


    -

    MPL-2.0 license

    +

    Overview

    +

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

    +

    Affected versions of this package are vulnerable to Uncontrolled Resource Consumption ('Resource Exhaustion') via specially crafted responses from a Git server, which triggers resource exhaustion in clients.

    +

    Note + This is only exploitable if the client is not using the in-memory filesystem supported by the library.

    +

    Workaround

    +

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

    +

    Details

    +

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

    +

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

    +

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

    +

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

    +

    Two common types of DoS vulnerabilities:

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

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

      +
    • +
    +

    Remediation

    +

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

    +

    References

    +
    -

    MPL-2.0 license

    +

    Out-of-bounds Write

    @@ -3020,20 +2990,17 @@

    MPL-2.0 license

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/dexidp/dex /usr/local/bin/dex -
    • -
    • - Package Manager: golang + Package Manager: alpine:3.18
    • - Module: + Vulnerable module: - github.com/hashicorp/hcl/v2 + busybox/busybox
    • Introduced through: - github.com/dexidp/dex@* and github.com/hashicorp/hcl/v2@v2.13.0 + docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0
    @@ -3046,72 +3013,51 @@

    Detailed paths

    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.37.0 - github.com/hashicorp/hcl/v2@v2.13.0 + busybox/busybox@1.36.1-r0
    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.37.0 - github.com/hashicorp/hcl/v2/ext/customdecode@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* + alpine-baselayout/alpine-baselayout@3.4.3-r1 - github.com/hashicorp/hcl/v2/ext/tryfunc@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* + busybox/busybox-binsh@1.36.1-r0 - github.com/hashicorp/hcl/v2/gohcl@v2.13.0 + busybox/busybox@1.36.1-r0
    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.37.0 - github.com/hashicorp/hcl/v2/hclparse@v2.13.0 + busybox/busybox-binsh@1.36.1-r0
    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.37.0 - github.com/hashicorp/hcl/v2/hclsyntax@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* + alpine-baselayout/alpine-baselayout@3.4.3-r1 - github.com/hashicorp/hcl/v2/hclwrite@v2.13.0 + busybox/busybox-binsh@1.36.1-r0
    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.37.0 - github.com/hashicorp/hcl/v2/json@v2.13.0 + busybox/ssl_client@1.36.1-r0 @@ -3122,17 +3068,26 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      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

      +
    -

    MPL-2.0 license

    +

    Use After Free

    @@ -3143,20 +3098,17 @@

    MPL-2.0 license

    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang + Package Manager: alpine:3.18
    • - Module: + Vulnerable module: - github.com/hashicorp/hcl + busybox/busybox
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/hcl@v1.0.0 + docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0
    @@ -3169,45 +3121,51 @@

    Detailed paths

    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + docker-image|ghcr.io/dexidp/dex@v2.37.0 - github.com/hashicorp/hcl@v1.0.0 + busybox/busybox@1.36.1-r0
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + alpine-baselayout/alpine-baselayout@3.4.3-r1 + + busybox/busybox-binsh@1.36.1-r0 - github.com/hashicorp/hcl/hcl/parser@v1.0.0 + busybox/busybox@1.36.1-r0
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + docker-image|ghcr.io/dexidp/dex@v2.37.0 - github.com/hashicorp/hcl/hcl/strconv@v1.0.0 + busybox/busybox-binsh@1.36.1-r0
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + alpine-baselayout/alpine-baselayout@3.4.3-r1 - github.com/hashicorp/hcl/hcl/token@v1.0.0 + busybox/busybox-binsh@1.36.1-r0
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + docker-image|ghcr.io/dexidp/dex@v2.37.0 - github.com/hashicorp/hcl/json/parser@v1.0.0 + busybox/ssl_client@1.36.1-r0 @@ -3218,17 +3176,26 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      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

      +
    -

    MPL-2.0 license

    +

    Use After Free

    @@ -3239,938 +3206,17 @@

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/golang-lru/simplelru@v0.5.4 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-version@v1.5.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-sockaddr@v1.0.2 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-sockaddr/template@v1.0.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-retryablehttp@v0.7.1 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-plugin@v1.4.4 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-plugin/internal/plugin@v1.4.4 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    Improper Handling of Highly Compressed Data (Data Amplification)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/dexidp/dex /usr/local/bin/dex -
    • -
    • - Package Manager: golang + Package Manager: alpine:3.18
    • Vulnerable module: - github.com/go-jose/go-jose/v3 + busybox/busybox
    • Introduced through: - github.com/dexidp/dex@* and github.com/go-jose/go-jose/v3@v3.0.0 + docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0
    @@ -4183,78 +3229,51 @@

    Detailed paths

    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.37.0 - github.com/go-jose/go-jose/v3@v3.0.0 + busybox/busybox@1.36.1-r0
    • -
    - -
    - -
    - -

    Overview

    -

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

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    Uncontrolled Resource Consumption ('Resource Exhaustion')

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-git/go-git/v5/plumbing -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/go-git/go-git/v5/plumbing@v5.4.2 - -
    • -
    - -
    +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + alpine-baselayout/alpine-baselayout@3.4.3-r1 + + busybox/busybox-binsh@1.36.1-r0 + + busybox/busybox@1.36.1-r0 + + +
  • +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/busybox-binsh@1.36.1-r0 + + -

    Detailed paths

    +
  • +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + alpine-baselayout/alpine-baselayout@3.4.3-r1 + + busybox/busybox-binsh@1.36.1-r0 + + -
      +
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + docker-image|ghcr.io/dexidp/dex@v2.37.0 - github.com/go-git/go-git/v5/plumbing@v5.4.2 + busybox/ssl_client@1.36.1-r0 @@ -4265,41 +3284,26 @@

      Detailed paths


      -

      Overview

      -

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

      -

      Affected versions of this package are vulnerable to Uncontrolled Resource Consumption ('Resource Exhaustion') via specially crafted responses from a Git server, which triggers resource exhaustion in clients.

      -

      Note - This is only exploitable if the client is not using the in-memory filesystem supported by the library.

      -

      Workaround

      -

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

      -

      Details

      -

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

      -

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

      -

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

      -

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

      -

      Two common types of DoS vulnerabilities:

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

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

        -
      • -
      +

      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 github.com/go-git/go-git/v5/plumbing to version 5.11.0 or higher.

      +

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

      References


  • -

    Out-of-bounds Write

    +

    Use After Free

    @@ -4391,27 +3395,27 @@

    Detailed paths

    NVD Description

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

    -

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

    +

    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-r6 or higher.

    +

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

    References


    -
    -

    Use After Free

    +
    +

    CVE-2023-6237

    -
    - medium severity +
    + low severity

    @@ -4423,12 +3427,12 @@

    Use After Free

  • Vulnerable module: - busybox/busybox + openssl/libcrypto3
  • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 + docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1
  • @@ -4443,7 +3447,7 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.37.0 - busybox/busybox@1.36.1-r0 + openssl/libcrypto3@3.1.1-r1 @@ -4452,11 +3456,20 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.37.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + apk-tools/apk-tools@2.14.0-r2 - busybox/busybox-binsh@1.36.1-r0 + openssl/libcrypto3@3.1.1-r1 + + + + +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 - busybox/busybox@1.36.1-r0 + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 @@ -4465,7 +3478,11 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.37.0 - busybox/busybox-binsh@1.36.1-r0 + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 @@ -4474,9 +3491,18 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.37.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + openssl/libssl3@3.1.1-r1 + + + +
  • +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 - busybox/busybox-binsh@1.36.1-r0 + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 @@ -4486,6 +3512,8 @@

    Detailed paths

    docker-image|ghcr.io/dexidp/dex@v2.37.0 busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 @@ -4497,29 +3525,53 @@

    Detailed paths


    NVD Description

    -

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

    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.

    -

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

    +

    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 busybox to version 1.36.1-r7 or higher.

    +

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

    References


  • -
    -

    Use After Free

    +
    +

    CVE-2024-2511

    -
    - medium severity +
    + low severity

    @@ -4531,12 +3583,12 @@

    Use After Free

  • Vulnerable module: - busybox/busybox + openssl/libcrypto3
  • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 + docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1
  • @@ -4551,7 +3603,7 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.37.0 - busybox/busybox@1.36.1-r0 + openssl/libcrypto3@3.1.1-r1 @@ -4560,11 +3612,20 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.37.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + apk-tools/apk-tools@2.14.0-r2 - busybox/busybox-binsh@1.36.1-r0 + openssl/libcrypto3@3.1.1-r1 + + + + +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 - busybox/busybox@1.36.1-r0 + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 @@ -4573,7 +3634,11 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.37.0 - busybox/busybox-binsh@1.36.1-r0 + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 @@ -4582,9 +3647,18 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.37.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + openssl/libssl3@3.1.1-r1 + + + +
  • +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 - busybox/busybox-binsh@1.36.1-r0 + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 @@ -4594,6 +3668,8 @@

    Detailed paths

    docker-image|ghcr.io/dexidp/dex@v2.37.0 busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 @@ -4605,29 +3681,49 @@

    Detailed paths


    NVD Description

    -

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

    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.

    -

    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.

    +

    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 busybox to version 1.36.1-r7 or higher.

    +

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

    References


  • -
    -

    Use After Free

    +
    +

    CVE-2024-4603

    -
    - medium severity +
    + low severity

    @@ -4639,12 +3735,12 @@

    Use After Free

  • Vulnerable module: - busybox/busybox + openssl/libcrypto3
  • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 + docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1
  • @@ -4659,7 +3755,7 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.37.0 - busybox/busybox@1.36.1-r0 + openssl/libcrypto3@3.1.1-r1 @@ -4668,11 +3764,20 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.37.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + apk-tools/apk-tools@2.14.0-r2 - busybox/busybox-binsh@1.36.1-r0 + openssl/libcrypto3@3.1.1-r1 + + + + +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 - busybox/busybox@1.36.1-r0 + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 @@ -4681,7 +3786,11 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.37.0 - busybox/busybox-binsh@1.36.1-r0 + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 @@ -4690,9 +3799,18 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.37.0 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + openssl/libssl3@3.1.1-r1 + + + +
  • +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 - busybox/busybox-binsh@1.36.1-r0 + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 @@ -4702,6 +3820,8 @@

    Detailed paths

    docker-image|ghcr.io/dexidp/dex@v2.37.0 busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 @@ -4713,25 +3833,53 @@

    Detailed paths


    NVD Description

    -

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

    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.

    -

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

    +

    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 busybox to version 1.36.1-r7 or higher.

    +

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

    References


  • -

    CVE-2023-6237

    +

    CVE-2024-5535

    @@ -4847,47 +3995,86 @@

    Detailed paths

    NVD Description

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

    -

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

    +

    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.4-r4 or higher.

    +

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

    References


    -

    CVE-2024-2511

    +

    CVE-2024-4741

    @@ -5001,45 +4188,19 @@

    Detailed paths


    NVD Description

    -

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

    -

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

    +

    This vulnerability has not been analyzed by NVD yet.

    Remediation

    -

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

    -

    References

    - +

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


    -

    CVE-2024-4603

    +

    CVE-2024-6119

    @@ -5155,45 +4316,40 @@

    Detailed paths

    NVD Description

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

    -

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

    +

    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.5-r0 or higher.

    +

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

    References


    diff --git a/docs/snyk/v2.9.17/haproxy_2.6.14-alpine.html b/docs/snyk/v2.10.16/haproxy_2.6.14-alpine.html similarity index 77% rename from docs/snyk/v2.9.17/haproxy_2.6.14-alpine.html rename to docs/snyk/v2.10.16/haproxy_2.6.14-alpine.html index 052909ea91cb3..9020dc61d54b1 100644 --- a/docs/snyk/v2.9.17/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.10.16/haproxy_2.6.14-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    June 16th 2024, 12:23:06 am (UTC+00:00)

    +

    September 22nd 2024, 12:28:38 am (UTC+00:00)

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

    Snyk test report

    -
    11 known vulnerabilities
    -
    83 vulnerable dependency paths
    +
    14 known vulnerabilities
    +
    110 vulnerable dependency paths
    18 dependencies
    @@ -663,9 +663,9 @@

    References

  • http://www.openwall.com/lists/oss-security/2023/10/24/1
  • https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=0df40630850fb2740e6be6890bb905d3fc623b2d
  • https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=5f69f5c65e483928c4b28ed16af6e5742929f1ee
  • +
  • https://security.netapp.com/advisory/ntap-20231027-0010/
  • https://www.debian.org/security/2023/dsa-5532
  • https://www.openssl.org/news/secadv/20231024.txt
  • -
  • https://security.netapp.com/advisory/ntap-20231027-0010/
  • https://security.netapp.com/advisory/ntap-20240201-0003/
  • https://security.netapp.com/advisory/ntap-20240201-0004/
  • @@ -844,12 +844,12 @@

    Remediation

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

    References

    @@ -1031,11 +1031,11 @@

    Remediation

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

    References


    @@ -2191,6 +2192,547 @@

    References

    +
    +

    CVE-2024-5535

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

    Detailed paths

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

    NVD Description

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-4741

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

    Detailed paths

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

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

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

    + +
    + + + +
    +
    +

    CVE-2024-6119

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

    Detailed paths

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

    NVD Description

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/v2.9.17/quay.io_argoproj_argocd_v2.9.17.html b/docs/snyk/v2.10.16/quay.io_argoproj_argocd_v2.10.16.html similarity index 74% rename from docs/snyk/v2.9.17/quay.io_argoproj_argocd_v2.9.17.html rename to docs/snyk/v2.10.16/quay.io_argoproj_argocd_v2.10.16.html index fd7178f489899..8ba1cd553e6c1 100644 --- a/docs/snyk/v2.9.17/quay.io_argoproj_argocd_v2.9.17.html +++ b/docs/snyk/v2.10.16/quay.io_argoproj_argocd_v2.10.16.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,23 +456,23 @@

    Snyk test report

    -

    June 16th 2024, 12:23:24 am (UTC+00:00)

    +

    September 22nd 2024, 12:28:55 am (UTC+00:00)

    Scanned the following paths:
      -
    • quay.io/argoproj/argocd:v2.9.17/argoproj/argocd/Dockerfile (deb)
    • -
    • quay.io/argoproj/argocd:v2.9.17/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.9.17//usr/local/bin/kustomize (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.9.17/helm/v3//usr/local/bin/helm (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.9.17/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.10.16/argoproj/argocd/Dockerfile (deb)
    • +
    • quay.io/argoproj/argocd:v2.10.16/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.10.16//usr/local/bin/kustomize (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.10.16/helm/v3//usr/local/bin/helm (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.10.16/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    -
    32 known vulnerabilities
    -
    198 vulnerable dependency paths
    -
    2190 dependencies
    +
    35 known vulnerabilities
    +
    241 vulnerable dependency paths
    +
    2278 dependencies
    @@ -480,88 +480,6 @@

    Snyk test report

    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argo-cd/v2 /usr/local/bin/argocd -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - google.golang.org/grpc -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and google.golang.org/grpc@v1.56.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - - google.golang.org/grpc@v1.56.2 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    google.golang.org/grpc is a Go implementation of gRPC

    -

    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.

    -

    Remediation

    -

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    -

    References

    - - -
    - - - -

    Allocation of Resources Without Limits or Throttling

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

    Allocation of Resources Without Limits or Throttling

  • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argo-cd/v2 /usr/local/bin/argocd
  • Package Manager: golang @@ -643,7 +561,7 @@

    References

  • -

    CVE-2020-22916

    +

    CVE-2024-41996

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

    CVE-2020-22916

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

      CVE-2020-22916

    • Vulnerable module: - xz-utils/liblzma5 + openssl/libssl3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and xz-utils/liblzma5@5.2.5-2ubuntu1 + docker-image|quay.io/argoproj/argocd@v2.10.16 and openssl/libssl3@3.0.2-0ubuntu1.16
    @@ -680,9 +598,113 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + openssh/openssh-client@1:8.9p1-3ubuntu0.10 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.16 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + git@1:2.34.1-1ubuntu1.11 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.2 + + pam/libpam-modules@1.4.0-11ubuntu2.4 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + krb5/libkrb5-3@1.19.2-2ubuntu0.3 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + openssl@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 - xz-utils/liblzma5@5.2.5-2ubuntu1 + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.16 @@ -694,32 +716,28 @@

      Detailed paths


      NVD Description

      -

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

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

      -

      An issue discovered in XZ 5.2.5 allows attackers to cause a denial of service via decompression of a crafted file. NOTE: the vendor disputes the claims of "endless output" and "denial of service" because decompression of the 17,486 bytes always results in 114,881,179 bytes, which is often a reasonable size increase.

      +

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

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 xz-utils.

      +

      There is no fixed version for Ubuntu:22.04 openssl.

      References


    -

    Resource Exhaustion

    +

    CVE-2024-6119

    @@ -730,7 +748,7 @@

    Resource Exhaustion

    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -743,7 +761,7 @@

      Resource Exhaustion

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and openssl/libssl3@3.0.2-0ubuntu1.15 + docker-image|quay.io/argoproj/argocd@v2.10.16 and openssl/libssl3@3.0.2-0ubuntu1.16
    @@ -756,62 +774,62 @@

    Detailed paths

    @@ -915,7 +944,7 @@

    Information Exposure

    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -928,7 +957,7 @@

      Information Exposure

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and libgcrypt20@1.9.4-3ubuntu3 + docker-image|quay.io/argoproj/argocd@v2.10.16 and libgcrypt20@1.9.4-3ubuntu3
    @@ -941,7 +970,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 libgcrypt20@1.9.4-3ubuntu3 @@ -950,7 +979,7 @@

      Detailed paths

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

      Detailed paths

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

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 apt@2.4.12 @@ -985,7 +1014,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 apt@2.4.12 @@ -998,7 +1027,7 @@

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 apt@2.4.12 @@ -1128,7 +1157,7 @@

      CVE-2024-26462

      • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -1141,7 +1170,7 @@

        CVE-2024-26462

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3
      @@ -1154,7 +1183,7 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libk5crypto3@1.19.2-2ubuntu0.3 @@ -1163,7 +1192,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -1184,7 +1213,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -1207,7 +1236,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libkrb5-3@1.19.2-2ubuntu0.3 @@ -1216,7 +1245,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -1237,7 +1266,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 @@ -1246,9 +1275,9 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssh/openssh-client@1:8.9p1-3ubuntu0.7 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 @@ -1257,7 +1286,7 @@

        Detailed paths

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

        Detailed paths

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

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -1304,7 +1333,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libkrb5support0@1.19.2-2ubuntu0.3 @@ -1338,7 +1367,7 @@

        References

    -

    LGPL-3.0 license

    +

    CVE-2024-37371

    @@ -1349,20 +1378,20 @@

    LGPL-3.0 license

    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
    • - Package Manager: golang + Package Manager: ubuntu:22.04
    • - Module: + Vulnerable module: - gopkg.in/retry.v1 + krb5/libk5crypto3
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and gopkg.in/retry.v1@v1.0.3 + docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3
    @@ -1375,54 +1404,546 @@

    Detailed paths

    • Introduced through: - github.com/argoproj/argo-cd/v2@* + docker-image|quay.io/argoproj/argocd@v2.10.16 - gopkg.in/retry.v1@v1.0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.3
    • -
    - -
    - -
    - -

    LGPL-3.0 license

    +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.2 + + pam/libpam-modules@1.4.0-11ubuntu2.4 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + krb5/libk5crypto3@1.19.2-2ubuntu0.3 + + -
    +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.2 + + pam/libpam-modules@1.4.0-11ubuntu2.4 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + krb5/libkrb5-3@1.19.2-2ubuntu0.3 + + krb5/libk5crypto3@1.19.2-2ubuntu0.3 + + - +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + krb5/libkrb5-3@1.19.2-2ubuntu0.3 + + -
  • -
    -

    MPL-2.0 license

    -
    + +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.2 + + pam/libpam-modules@1.4.0-11ubuntu2.4 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + krb5/libkrb5-3@1.19.2-2ubuntu0.3 + + -
    - medium severity -
    +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + -
    +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + openssh/openssh-client@1:8.9p1-3ubuntu0.10 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argo-cd/v2 /usr/local/bin/argocd -
    • -
    • +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + git@1:2.34.1-1ubuntu1.11 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + git@1:2.34.1-1ubuntu1.11 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.2 + + pam/libpam-modules@1.4.0-11ubuntu2.4 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + krb5/libkrb5support0@1.19.2-2ubuntu0.3 + + + +
    • +
    + +
  • + +
    + +

    NVD Description

    +

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

    +

    In MIT Kerberos 5 (aka krb5) before 1.21.3, an attacker can cause invalid memory reads during GSS message token handling by sending message tokens with invalid length fields.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 krb5 to version 1.19.2-2ubuntu0.4 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-37370

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

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + krb5/libk5crypto3@1.19.2-2ubuntu0.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.2 + + pam/libpam-modules@1.4.0-11ubuntu2.4 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + krb5/libk5crypto3@1.19.2-2ubuntu0.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.2 + + pam/libpam-modules@1.4.0-11ubuntu2.4 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + krb5/libkrb5-3@1.19.2-2ubuntu0.3 + + krb5/libk5crypto3@1.19.2-2ubuntu0.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + krb5/libkrb5-3@1.19.2-2ubuntu0.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.2 + + pam/libpam-modules@1.4.0-11ubuntu2.4 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + krb5/libkrb5-3@1.19.2-2ubuntu0.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + openssh/openssh-client@1:8.9p1-3ubuntu0.10 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + git@1:2.34.1-1ubuntu1.11 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + git@1:2.34.1-1ubuntu1.11 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.2 + + pam/libpam-modules@1.4.0-11ubuntu2.4 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + krb5/libkrb5support0@1.19.2-2ubuntu0.3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    In MIT Kerberos 5 (aka krb5) before 1.21.3, an attacker can modify the plaintext Extra Count field of a confidential GSS krb5 wrap token, causing the unwrapped token to appear truncated to the application.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 krb5 to version 1.19.2-2ubuntu0.4 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/rs/cors +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/rs/cors@v1.9.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/rs/cors@v1.9.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

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

    +

    PoC

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

    Details

    +

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

    +

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

    +

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

    +

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

    +

    Two common types of DoS vulnerabilities:

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

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

      +
    • +
    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    Insertion of Sensitive Information into Log File

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • Package Manager: golang
    • - Module: + Vulnerable module: - github.com/r3labs/diff + github.com/hashicorp/go-retryablehttp
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/r3labs/diff@v1.1.0 + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.4
    @@ -1430,14 +1951,124 @@

    MPL-2.0 license


    -

    Detailed paths

    +

    Detailed paths

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

    Overview

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-4039

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

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + apt@2.4.12 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + apt@2.4.12 + + apt/libapt-pkg6.0@2.4.12 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + gcc-12/gcc-12-base@12.3.0-1ubuntu1~22.04 + + -
        +
      • Introduced through: - github.com/argoproj/argo-cd/v2@* + docker-image|quay.io/argoproj/argocd@v2.10.16 - github.com/r3labs/diff@v1.1.0 + gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 @@ -1448,17 +2079,40 @@

        Detailed paths


        -

        MPL-2.0 license

        +

        NVD Description

        +

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

        +

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

        +

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

        +

        Remediation

        +

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

        +

        References

        +
    -

    MPL-2.0 license

    +

    Integer Overflow or Wraparound

    @@ -1469,21 +2123,21 @@

    MPL-2.0 license

    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
    • - Package Manager: golang + Package Manager: ubuntu:22.04
    • - Module: + Vulnerable module: - github.com/hashicorp/go-version + expat/libexpat1
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-version@v1.2.1 + docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1495,9 +2149,11 @@

    Detailed paths

    -

    MPL-2.0 license

    +

    XML External Entity (XXE) Injection

    @@ -1529,21 +2196,21 @@

    MPL-2.0 license

    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
    • - Package Manager: golang + Package Manager: ubuntu:22.04
    • - Module: + Vulnerable module: - github.com/hashicorp/go-retryablehttp + expat/libexpat1
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.4 + docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1555,9 +2222,11 @@

    Detailed paths

    -

    MPL-2.0 license

    +

    Integer Overflow or Wraparound

    @@ -1589,21 +2269,21 @@

    MPL-2.0 license

    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/helm/v3 /usr/local/bin/helm + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
    • - Package Manager: golang + Package Manager: ubuntu:22.04
    • - Module: + Vulnerable module: - github.com/hashicorp/go-multierror + expat/libexpat1
    • Introduced through: - helm.sh/helm/v3@* and github.com/hashicorp/go-multierror@v1.1.1 + docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1615,9 +2295,11 @@

    Detailed paths

    -

    MPL-2.0 license

    +

    Out-of-bounds Read

    @@ -1649,21 +2342,21 @@

    MPL-2.0 license

    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
    • - Package Manager: golang + Package Manager: ubuntu:22.04
    • - Module: + Vulnerable module: - github.com/hashicorp/go-cleanhttp + curl/libcurl3-gnutls
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-cleanhttp@v0.5.2 + docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1675,9 +2368,11 @@

    Detailed paths

    -

    MPL-2.0 license

    +

    CVE-2024-8096

    @@ -1709,21 +2424,21 @@

    MPL-2.0 license

    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
    • - Package Manager: golang + Package Manager: ubuntu:22.04
    • - Module: + Vulnerable module: - github.com/gosimple/slug + curl/libcurl3-gnutls
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.13.1 + docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1735,9 +2450,11 @@

    Detailed paths

    • Introduced through: - github.com/argoproj/argo-cd/v2@* + docker-image|quay.io/argoproj/argocd@v2.10.16 - github.com/gosimple/slug@v1.13.1 + git@1:2.34.1-1ubuntu1.11 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 @@ -1748,12 +2465,24 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      NVD Description

      +

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

      +

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

      +

      Remediation

      +

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

      +

      References

      +
    @@ -1769,7 +2498,7 @@

    CVE-2023-7008

    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -1782,7 +2511,7 @@

      CVE-2023-7008

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and systemd/libsystemd0@249.11-0ubuntu3.12 + docker-image|quay.io/argoproj/argocd@v2.10.16 and systemd/libsystemd0@249.11-0ubuntu3.12
    @@ -1795,7 +2524,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 systemd/libsystemd0@249.11-0ubuntu3.12 @@ -1804,7 +2533,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 apt@2.4.12 @@ -1815,7 +2544,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 procps/libprocps8@2:3.3.17-6ubuntu2.1 @@ -1826,7 +2555,7 @@

      Detailed paths

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

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 util-linux/bsdutils@1:2.37.2-4ubuntu3.4 @@ -1848,7 +2577,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 apt@2.4.12 @@ -1861,7 +2590,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 systemd/libudev1@249.11-0ubuntu3.12 @@ -1870,7 +2599,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 libfido2/libfido2-1@1.10.0-1 @@ -1881,7 +2610,7 @@

      Detailed paths

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

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 apt@2.4.12 @@ -1947,7 +2676,7 @@

      Arbitrary Code Injection

      • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -1960,7 +2689,7 @@

        Arbitrary Code Injection

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and shadow/passwd@1:4.8.1-2ubuntu2.2 + docker-image|quay.io/argoproj/argocd@v2.10.16 and shadow/passwd@1:4.8.1-2ubuntu2.2
      @@ -1973,7 +2702,7 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 shadow/passwd@1:4.8.1-2ubuntu2.2 @@ -1982,7 +2711,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -1993,9 +2722,9 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssh/openssh-client@1:8.9p1-3ubuntu0.7 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 shadow/passwd@1:4.8.1-2ubuntu2.2 @@ -2004,7 +2733,7 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 shadow/login@1:4.8.1-2ubuntu2.2 @@ -2051,7 +2780,7 @@

        Uncontrolled Recursion

        • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
        • Package Manager: ubuntu:22.04 @@ -2064,7 +2793,7 @@

          Uncontrolled Recursion

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + docker-image|quay.io/argoproj/argocd@v2.10.16 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1
        @@ -2077,7 +2806,7 @@

        Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 @@ -2086,7 +2815,7 @@

          Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 grep@3.7-1build1 @@ -2139,7 +2868,7 @@

          Release of Invalid Pointer or Reference

          • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
          • Package Manager: ubuntu:22.04 @@ -2152,7 +2881,7 @@

            Release of Invalid Pointer or Reference

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and patch@2.7.6-7build2 + docker-image|quay.io/argoproj/argocd@v2.10.16 and patch@2.7.6-7build2
          @@ -2165,7 +2894,7 @@

          Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 patch@2.7.6-7build2 @@ -2209,7 +2938,7 @@

            Double Free

            • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
            • Package Manager: ubuntu:22.04 @@ -2222,7 +2951,7 @@

              Double Free

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and patch@2.7.6-7build2 + docker-image|quay.io/argoproj/argocd@v2.10.16 and patch@2.7.6-7build2
            @@ -2235,7 +2964,7 @@

            Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 patch@2.7.6-7build2 @@ -2284,7 +3013,7 @@

              CVE-2024-2511

              • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
              • Package Manager: ubuntu:22.04 @@ -2297,7 +3026,7 @@

                CVE-2024-2511

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and openssl/libssl3@3.0.2-0ubuntu1.15 + docker-image|quay.io/argoproj/argocd@v2.10.16 and openssl/libssl3@3.0.2-0ubuntu1.16
              @@ -2310,62 +3039,62 @@

              Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 libfido2/libfido2-1@1.10.0-1 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssh/openssh-client@1:8.9p1-3ubuntu0.7 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 ca-certificates@20230311ubuntu0.22.04.1 - openssl@3.0.2-0ubuntu1.15 + openssl@3.0.2-0ubuntu1.16 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 git@1:2.34.1-1ubuntu1.11 @@ -2373,14 +3102,14 @@

                Detailed paths

                libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -2396,27 +3125,27 @@

                Detailed paths

                krb5/libkrb5-3@1.19.2-2ubuntu0.3 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssl@3.0.2-0ubuntu1.15 + openssl@3.0.2-0ubuntu1.16
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 ca-certificates@20230311ubuntu0.22.04.1 - openssl@3.0.2-0ubuntu1.15 + openssl@3.0.2-0ubuntu1.16 @@ -2446,7 +3175,7 @@

                NVD Description

                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

                -

                There is no fixed version for Ubuntu:22.04 openssl.

                +

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

                References

                • http://people.ubuntu.com/~ubuntu-security/cve/CVE-2024-2511
                • @@ -2478,7 +3207,7 @@

                  CVE-2024-4603

                  • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
                  • Package Manager: ubuntu:22.04 @@ -2491,7 +3220,7 @@

                    CVE-2024-4603

                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and openssl/libssl3@3.0.2-0ubuntu1.15 + docker-image|quay.io/argoproj/argocd@v2.10.16 and openssl/libssl3@3.0.2-0ubuntu1.16
                  @@ -2504,62 +3233,62 @@

                  Detailed paths

                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 libfido2/libfido2-1@1.10.0-1 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssh/openssh-client@1:8.9p1-3ubuntu0.7 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 ca-certificates@20230311ubuntu0.22.04.1 - openssl@3.0.2-0ubuntu1.15 + openssl@3.0.2-0ubuntu1.16 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 git@1:2.34.1-1ubuntu1.11 @@ -2567,14 +3296,14 @@

                    Detailed paths

                    libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -2590,27 +3319,27 @@

                    Detailed paths

                    krb5/libkrb5-3@1.19.2-2ubuntu0.3 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssl@3.0.2-0ubuntu1.15 + openssl@3.0.2-0ubuntu1.16
                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 ca-certificates@20230311ubuntu0.22.04.1 - openssl@3.0.2-0ubuntu1.15 + openssl@3.0.2-0ubuntu1.16 @@ -2648,7 +3377,7 @@

                    NVD Description

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

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

                    Remediation

                    -

                    There is no fixed version for Ubuntu:22.04 openssl.

                    +

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

                    References


                    @@ -2679,7 +3409,7 @@

                    CVE-2024-4741

                    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
                    • Package Manager: ubuntu:22.04 @@ -2692,7 +3422,7 @@

                      CVE-2024-4741

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and openssl/libssl3@3.0.2-0ubuntu1.15 + docker-image|quay.io/argoproj/argocd@v2.10.16 and openssl/libssl3@3.0.2-0ubuntu1.16
                    @@ -2705,62 +3435,62 @@

                    Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 libfido2/libfido2-1@1.10.0-1 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssh/openssh-client@1:8.9p1-3ubuntu0.7 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 ca-certificates@20230311ubuntu0.22.04.1 - openssl@3.0.2-0ubuntu1.15 + openssl@3.0.2-0ubuntu1.16 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 git@1:2.34.1-1ubuntu1.11 @@ -2768,14 +3498,14 @@

                      Detailed paths

                      libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -2791,27 +3521,27 @@

                      Detailed paths

                      krb5/libkrb5-3@1.19.2-2ubuntu0.3 - openssl/libssl3@3.0.2-0ubuntu1.15 + openssl/libssl3@3.0.2-0ubuntu1.16
                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssl@3.0.2-0ubuntu1.15 + openssl@3.0.2-0ubuntu1.16
                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 ca-certificates@20230311ubuntu0.22.04.1 - openssl@3.0.2-0ubuntu1.15 + openssl@3.0.2-0ubuntu1.16 @@ -2825,7 +3555,7 @@

                      Detailed paths

                      NVD Description

                      This vulnerability has not been analyzed by NVD yet.

                      Remediation

                      -

                      There is no fixed version for Ubuntu:22.04 openssl.

                      +

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

                      References

    +
    +
    +

    CVE-2024-5535

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

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + openssh/openssh-client@1:8.9p1-3ubuntu0.10 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.16 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + git@1:2.34.1-1ubuntu1.11 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.2 + + pam/libpam-modules@1.4.0-11ubuntu2.4 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + + krb5/libkrb5-3@1.19.2-2ubuntu0.3 + + openssl/libssl3@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + openssl@3.0.2-0ubuntu1.16 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.10.16 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.16 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

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

    +

    Issue summary: 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 Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.17 or higher.

    +

    References

    + + +
    + + +

    CVE-2023-50495

    @@ -2850,7 +3817,7 @@

    CVE-2023-50495

    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -2863,7 +3830,7 @@

      CVE-2023-50495

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and ncurses/libtinfo6@6.3-2ubuntu0.1 + docker-image|quay.io/argoproj/argocd@v2.10.16 and ncurses/libtinfo6@6.3-2ubuntu0.1
    @@ -2876,7 +3843,7 @@

    Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      CVE-2023-45918

      • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -3127,7 +4094,7 @@

        CVE-2023-45918

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and ncurses/libtinfo6@6.3-2ubuntu0.1 + docker-image|quay.io/argoproj/argocd@v2.10.16 and ncurses/libtinfo6@6.3-2ubuntu0.1
      @@ -3140,7 +4107,7 @@

      Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Resource Exhaustion

        • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
        • Package Manager: ubuntu:22.04 @@ -3389,7 +4356,7 @@

          Resource Exhaustion

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and libzstd/libzstd1@1.4.8+dfsg-3build1 + docker-image|quay.io/argoproj/argocd@v2.10.16 and libzstd/libzstd1@1.4.8+dfsg-3build1
        @@ -3402,7 +4369,7 @@

        Detailed paths

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 libzstd/libzstd1@1.4.8+dfsg-3build1 @@ -3453,7 +4420,7 @@

          Integer Overflow or Wraparound

          • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
          • Package Manager: ubuntu:22.04 @@ -3466,7 +4433,7 @@

            Integer Overflow or Wraparound

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3
          @@ -3479,7 +4446,7 @@

          Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libk5crypto3@1.19.2-2ubuntu0.3 @@ -3488,7 +4455,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -3509,7 +4476,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -3532,7 +4499,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libkrb5-3@1.19.2-2ubuntu0.3 @@ -3541,7 +4508,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -3562,7 +4529,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 @@ -3571,9 +4538,9 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssh/openssh-client@1:8.9p1-3ubuntu0.7 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 @@ -3582,7 +4549,7 @@

            Detailed paths

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

            Detailed paths

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

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -3629,7 +4596,7 @@

            Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libkrb5support0@1.19.2-2ubuntu0.3 @@ -3677,7 +4644,7 @@

            CVE-2024-26461

            • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
            • Package Manager: ubuntu:22.04 @@ -3690,7 +4657,7 @@

              CVE-2024-26461

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3
            @@ -3703,7 +4670,7 @@

            Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libk5crypto3@1.19.2-2ubuntu0.3 @@ -3712,7 +4679,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -3733,7 +4700,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -3756,7 +4723,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libkrb5-3@1.19.2-2ubuntu0.3 @@ -3765,7 +4732,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -3786,7 +4753,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 @@ -3795,9 +4762,9 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssh/openssh-client@1:8.9p1-3ubuntu0.7 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 @@ -3806,7 +4773,7 @@

              Detailed paths

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

              Detailed paths

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

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -3853,7 +4820,7 @@

              Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libkrb5support0@1.19.2-2ubuntu0.3 @@ -3898,7 +4865,7 @@

              CVE-2024-26458

              • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
              • Package Manager: ubuntu:22.04 @@ -3911,7 +4878,7 @@

                CVE-2024-26458

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.10.16 and krb5/libk5crypto3@1.19.2-2ubuntu0.3
              @@ -3924,7 +4891,7 @@

              Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libk5crypto3@1.19.2-2ubuntu0.3 @@ -3933,7 +4900,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -3954,7 +4921,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -3977,7 +4944,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libkrb5-3@1.19.2-2ubuntu0.3 @@ -3986,7 +4953,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -4007,7 +4974,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 @@ -4016,9 +4983,9 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 - openssh/openssh-client@1:8.9p1-3ubuntu0.7 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 @@ -4027,7 +4994,7 @@

                Detailed paths

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

                Detailed paths

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

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 adduser@3.118ubuntu5 @@ -4074,7 +5041,7 @@

                Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 krb5/libkrb5support0@1.19.2-2ubuntu0.3 @@ -4119,7 +5086,7 @@

                Out-of-bounds Write

                • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
                • Package Manager: ubuntu:22.04 @@ -4132,7 +5099,7 @@

                  Out-of-bounds Write

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and gnupg2/gpgv@2.2.27-3ubuntu2.1 + docker-image|quay.io/argoproj/argocd@v2.10.16 and gnupg2/gpgv@2.2.27-3ubuntu2.1
                @@ -4145,7 +5112,7 @@

                Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 gnupg2/gpgv@2.2.27-3ubuntu2.1 @@ -4154,7 +5121,7 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 apt@2.4.12 @@ -4165,7 +5132,7 @@

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Allocation of Resources Without Limits or Throttling

                • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
                • Package Manager: ubuntu:22.04 @@ -4511,7 +5478,7 @@

                  Allocation of Resources Without Limits or Throttling

                  Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and glibc/libc-bin@2.35-0ubuntu3.8 + docker-image|quay.io/argoproj/argocd@v2.10.16 and glibc/libc-bin@2.35-0ubuntu3.8
                @@ -4524,7 +5491,7 @@

                Detailed paths

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

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 glibc/libc6@2.35-0ubuntu3.8 @@ -4555,9 +5522,9 @@

                  Remediation

                  References


                  @@ -4579,7 +5546,7 @@

                  Improper Input Validation

                  • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
                  • Package Manager: ubuntu:22.04 @@ -4593,7 +5560,7 @@

                    Improper Input Validation

                  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17, git@1:2.34.1-1ubuntu1.11 and others + docker-image|quay.io/argoproj/argocd@v2.10.16, git@1:2.34.1-1ubuntu1.11 and others
                  @@ -4605,7 +5572,7 @@

                  Detailed paths

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

                    Detailed paths

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

                    Detailed paths

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

                    Uncontrolled Recursion

                    • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
                    • Package Manager: ubuntu:22.04 @@ -4685,7 +5652,7 @@

                      Uncontrolled Recursion

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + docker-image|quay.io/argoproj/argocd@v2.10.16 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04
                    @@ -4698,7 +5665,7 @@

                    Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 @@ -4707,7 +5674,7 @@

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 apt@2.4.12 @@ -4718,7 +5685,7 @@

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 apt@2.4.12 @@ -4731,7 +5698,7 @@

                      Detailed paths

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

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 @@ -4763,8 +5730,8 @@

                      References

                      @@ -4787,7 +5754,7 @@

                      Improper Input Validation

                      • - Manifest file: quay.io/argoproj/argocd:v2.9.17/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.10.16/argoproj/argocd Dockerfile
                      • Package Manager: ubuntu:22.04 @@ -4800,7 +5767,7 @@

                        Improper Input Validation

                      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 and coreutils@8.32-4.1ubuntu1.2 + docker-image|quay.io/argoproj/argocd@v2.10.16 and coreutils@8.32-4.1ubuntu1.2
                      @@ -4813,7 +5780,7 @@

                      Detailed paths

                      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.17 + docker-image|quay.io/argoproj/argocd@v2.10.16 coreutils@8.32-4.1ubuntu1.2 diff --git a/docs/snyk/v2.10.16/redis_7.0.15-alpine.html b/docs/snyk/v2.10.16/redis_7.0.15-alpine.html new file mode 100644 index 0000000000000..a425e2171384a --- /dev/null +++ b/docs/snyk/v2.10.16/redis_7.0.15-alpine.html @@ -0,0 +1,484 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
                        +
                        +
                        +
                        + + + Snyk - Open Source Security + + + + + + + +
                        +

                        Snyk test report

                        + +

                        September 22nd 2024, 12:28:59 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)
                        • +
                        +
                        + +
                        +
                        0 known vulnerabilities
                        +
                        0 vulnerable dependency paths
                        +
                        18 dependencies
                        +
                        +
                        +
                        +
                        + +
                        + No known vulnerabilities detected. +
                        +
                        + + + diff --git a/docs/snyk/v2.11.3/redis_7.0.14-alpine.html b/docs/snyk/v2.11.3/redis_7.0.14-alpine.html deleted file mode 100644 index 76b8256a89710..0000000000000 --- a/docs/snyk/v2.11.3/redis_7.0.14-alpine.html +++ /dev/null @@ -1,1815 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
                        -
                        -
                        -
                        - - - Snyk - Open Source Security - - - - - - - -
                        -

                        Snyk test report

                        - -

                        June 16th 2024, 12:19:04 am (UTC+00:00)

                        -
                        -
                        - Scanned the following paths: -
                          -
                        • redis:7.0.14-alpine (apk)
                        • -
                        • redis:7.0.14-alpine/tianon/gosu//usr/local/bin/gosu (gomodules)
                        • -
                        -
                        - -
                        -
                        9 known vulnerabilities
                        -
                        65 vulnerable dependency paths
                        -
                        19 dependencies
                        -
                        -
                        -
                        -
                        - -
                        -
                        -
                        -

                        Out-of-bounds Write

                        -
                        - -
                        - medium severity -
                        - -
                        - -
                          -
                        • - Package Manager: alpine:3.19 -
                        • -
                        • - Vulnerable module: - - openssl/libcrypto3 -
                        • - -
                        • Introduced through: - - docker-image|redis@7.0.14-alpine and openssl/libcrypto3@3.1.4-r2 - -
                        • -
                        - -
                        - - -

                        Detailed paths

                        - -
                          -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - busybox/ssl_client@1.36.1-r15 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libssl3@3.1.4-r2 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - 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|redis@7.0.14-alpine and openssl/libcrypto3@3.1.4-r2 - -
                        • -
                        - -
                        - - -

                        Detailed paths

                        - -
                          -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - busybox/ssl_client@1.36.1-r15 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libssl3@3.1.4-r2 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - 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

                        - - -
                        - - - -
                        -
                        -

                        Out-of-bounds Write

                        -
                        - -
                        - medium severity -
                        - -
                        - -
                          -
                        • - Package Manager: alpine:3.19 -
                        • -
                        • - Vulnerable module: - - busybox/busybox -
                        • - -
                        • Introduced through: - - docker-image|redis@7.0.14-alpine and busybox/busybox@1.36.1-r15 - -
                        • -
                        - -
                        - - -

                        Detailed paths

                        - -
                          -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - busybox/busybox@1.36.1-r15 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - 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|redis@7.0.14-alpine - - busybox/busybox-binsh@1.36.1-r15 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - alpine-baselayout/alpine-baselayout@3.4.3-r2 - - busybox/busybox-binsh@1.36.1-r15 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - 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|redis@7.0.14-alpine and busybox/busybox@1.36.1-r15 - -
                        • -
                        - -
                        - - -

                        Detailed paths

                        - -
                          -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - busybox/busybox@1.36.1-r15 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - 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|redis@7.0.14-alpine - - busybox/busybox-binsh@1.36.1-r15 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - alpine-baselayout/alpine-baselayout@3.4.3-r2 - - busybox/busybox-binsh@1.36.1-r15 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - 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|redis@7.0.14-alpine and busybox/busybox@1.36.1-r15 - -
                        • -
                        - -
                        - - -

                        Detailed paths

                        - -
                          -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - busybox/busybox@1.36.1-r15 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - 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|redis@7.0.14-alpine - - busybox/busybox-binsh@1.36.1-r15 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - alpine-baselayout/alpine-baselayout@3.4.3-r2 - - busybox/busybox-binsh@1.36.1-r15 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - 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|redis@7.0.14-alpine and busybox/busybox@1.36.1-r15 - -
                        • -
                        - -
                        - - -

                        Detailed paths

                        - -
                          -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - busybox/busybox@1.36.1-r15 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - 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|redis@7.0.14-alpine - - busybox/busybox-binsh@1.36.1-r15 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - alpine-baselayout/alpine-baselayout@3.4.3-r2 - - busybox/busybox-binsh@1.36.1-r15 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - 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|redis@7.0.14-alpine and openssl/libcrypto3@3.1.4-r2 - -
                        • -
                        - -
                        - - -

                        Detailed paths

                        - -
                          -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - busybox/ssl_client@1.36.1-r15 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libssl3@3.1.4-r2 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - 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|redis@7.0.14-alpine and openssl/libcrypto3@3.1.4-r2 - -
                        • -
                        - -
                        - - -

                        Detailed paths

                        - -
                          -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - busybox/ssl_client@1.36.1-r15 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libssl3@3.1.4-r2 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - 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|redis@7.0.14-alpine and openssl/libcrypto3@3.1.4-r2 - -
                        • -
                        - -
                        - - -

                        Detailed paths

                        - -
                          -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - busybox/ssl_client@1.36.1-r15 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libssl3@3.1.4-r2 - - openssl/libcrypto3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - .redis-rundeps@20231208.201137 - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - apk-tools/apk-tools@2.14.0-r5 - - openssl/libssl3@3.1.4-r2 - - - -
                        • -
                        • - Introduced through: - docker-image|redis@7.0.14-alpine - - 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

                        - - -
                        - - - -
                        -
                        -
                        -
                        - - - diff --git a/docs/snyk/v2.11.3/argocd-iac-install.html b/docs/snyk/v2.11.8/argocd-iac-install.html similarity index 99% rename from docs/snyk/v2.11.3/argocd-iac-install.html rename to docs/snyk/v2.11.8/argocd-iac-install.html index 2dc45d9f164b0..e3753708b8045 100644 --- a/docs/snyk/v2.11.3/argocd-iac-install.html +++ b/docs/snyk/v2.11.8/argocd-iac-install.html @@ -456,7 +456,7 @@

                        Snyk test report

                        -

                        June 16th 2024, 12:20:24 am (UTC+00:00)

                        +

                        September 22nd 2024, 12:28:02 am (UTC+00:00)

                        Scanned the following path: diff --git a/docs/snyk/v2.11.3/argocd-iac-namespace-install.html b/docs/snyk/v2.11.8/argocd-iac-namespace-install.html similarity index 99% rename from docs/snyk/v2.11.3/argocd-iac-namespace-install.html rename to docs/snyk/v2.11.8/argocd-iac-namespace-install.html index cb97e86b53b51..1e254b4038b83 100644 --- a/docs/snyk/v2.11.3/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.11.8/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

                        Snyk test report

                        -

                        June 16th 2024, 12:20:33 am (UTC+00:00)

                        +

                        September 22nd 2024, 12:28:10 am (UTC+00:00)

                        Scanned the following path: diff --git a/docs/snyk/v2.11.3/argocd-test.html b/docs/snyk/v2.11.8/argocd-test.html similarity index 90% rename from docs/snyk/v2.11.3/argocd-test.html rename to docs/snyk/v2.11.8/argocd-test.html index 3ee33ce5e4888..ed53a51bfbfd9 100644 --- a/docs/snyk/v2.11.3/argocd-test.html +++ b/docs/snyk/v2.11.8/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

                        Snyk test report

                        -

                        June 16th 2024, 12:18:30 am (UTC+00:00)

                        +

                        September 22nd 2024, 12:26:11 am (UTC+00:00)

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

                        Snyk test report

                        -
                        9 known vulnerabilities
                        -
                        165 vulnerable dependency paths
                        +
                        7 known vulnerabilities
                        +
                        158 vulnerable dependency paths
                        2041 dependencies
                        @@ -1130,7 +1130,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/common@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 @@ -1317,7 +1317,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/cache@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -1334,7 +1334,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -1351,7 +1351,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -1559,7 +1559,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/ignore@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 @@ -1578,7 +1578,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 @@ -1597,7 +1597,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/utils/testing@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/testing@#18ba62e1f1fb k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 @@ -1692,7 +1692,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/health@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.26.11 @@ -1882,9 +1882,9 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/health@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/health@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -1901,9 +1901,9 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/common@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -2034,7 +2034,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/diff@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb k8s.io/apimachinery/pkg/util/strategicpatch@0.26.11 @@ -2139,11 +2139,11 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/hook@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/sync/common@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb k8s.io/apimachinery/pkg/apis/meta/v1@0.26.11 @@ -2485,7 +2485,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/diff@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/diff@#18ba62e1f1fb k8s.io/kubectl/pkg/cmd/util@0.26.11 @@ -2508,13 +2508,13 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/hook@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/sync/common@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -2531,13 +2531,13 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/sync/common@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -2748,7 +2748,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#18ba62e1f1fb k8s.io/kubernetes/pkg/apis/storage/install@1.26.11 @@ -2848,15 +2848,15 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync/ignore@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/ignore@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/sync/hook@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/sync/common@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync/common@#18ba62e1f1fb - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -2948,7 +2948,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/cache@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/cache@#18ba62e1f1fb k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -2975,7 +2975,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/sync@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/sync@#18ba62e1f1fb k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -3002,7 +3002,7 @@

                        Detailed paths

                        Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/gitops-engine/pkg/utils/kube@#fbecbb86e412 + github.com/argoproj/gitops-engine/pkg/utils/kube@#18ba62e1f1fb k8s.io/kubectl/pkg/util/openapi@0.26.11 @@ -3140,33 +3140,33 @@

                        References

    -
    -

    LGPL-3.0 license

    +
    +

    Prototype Pollution

    -
    - medium severity +
    + high severity

    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod + Manifest file: /argo-cd ui/yarn.lock
    • - Package Manager: golang + Package Manager: npm
    • - Module: + Vulnerable module: - gopkg.in/retry.v1 + dompurify
    • Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others + argo-cd-ui@1.0.0, redoc@2.0.0-rc.64 and others
    @@ -3178,11 +3178,11 @@

    Detailed paths

    • Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 + argo-cd-ui@1.0.0 - github.com/Azure/kubelogin/pkg/token@0.0.20 + redoc@2.0.0-rc.64 - gopkg.in/retry.v1@1.0.3 + dompurify@2.3.6 @@ -3193,17 +3193,109 @@

      Detailed paths


      -

      LGPL-3.0 license

      +

      Overview

      +

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

      +

      Affected versions of this package are vulnerable to Prototype Pollution due to improper user input sanitization through the depth-checking mechanism, an attacker can exploit this vulnerability by using special nesting techniques to create a malicious HTML file.

      +

      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 dompurify to version 2.5.4, 3.1.3 or higher.

      +

      References

      +
    -

    MPL-2.0 license

    +

    Regular Expression Denial of Service (ReDoS)

    @@ -3214,21 +3306,21 @@

    MPL-2.0 license

    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod + Manifest file: /argo-cd ui/yarn.lock
    • - Package Manager: golang + Package Manager: npm
    • - Module: + Vulnerable module: - github.com/r3labs/diff + path-to-regexp
    • Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/r3labs/diff@1.1.0 + argo-cd-ui@1.0.0, react-router@4.3.1 and others
    @@ -3240,9 +3332,39 @@

    Detailed paths

    • Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 + argo-cd-ui@1.0.0 + + react-router@4.3.1 + + path-to-regexp@1.8.0 + + + +
    • +
    • + Introduced through: + argo-cd-ui@1.0.0 + + react-router-dom@4.3.1 + + react-router@4.3.1 + + path-to-regexp@1.8.0 + + + +
    • +
    • + Introduced through: + argo-cd-ui@1.0.0 + + argo-ui@1.0.0 + + react-router-dom@4.3.1 + + react-router@4.3.1 - github.com/r3labs/diff@1.1.0 + path-to-regexp@1.8.0 @@ -3253,17 +3375,96 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      Overview

      +

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

      +

      Note: + While the 8.0.0 release has completely eliminated the vulnerable functionality, prior versions that have received the patch to mitigate backtracking may still be vulnerable if custom regular expressions are used. So it is strongly recommended for regular expression input to be controlled to avoid malicious performance degradation in those versions. This behavior is enforced as of version 7.1.0 via the strict option, which returns an error if a dangerous regular expression is detected.

      +

      Workaround

      +

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

      +

      PoC

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

      Details

      +

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

      +

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

      +

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

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

      This regular expression accomplishes the following:

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

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

      +

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

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

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

      +

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

      +

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

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

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

      +

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

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

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

      +

      Remediation

      +

      Upgrade path-to-regexp to version 0.1.10, 1.9.0, 3.3.0, 6.3.0, 8.0.0 or higher.

      +

      References

      +
    -

    MPL-2.0 license

    +

    Denial of Service (DoS)

    @@ -3280,15 +3481,15 @@

    MPL-2.0 license

    Package Manager: golang
  • - Module: + Vulnerable module: - github.com/hashicorp/go-version + github.com/rs/cors
  • Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0, code.gitea.io/sdk/gitea@0.15.1 and others + github.com/argoproj/argo-cd/v2@0.0.0, github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 and others
  • @@ -3302,9 +3503,9 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - code.gitea.io/sdk/gitea@0.15.1 + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 - github.com/hashicorp/go-version@1.2.1 + github.com/rs/cors@1.9.0 @@ -3315,17 +3516,67 @@

    Detailed paths


    -

    MPL-2.0 license

    +

    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

    +

    Insertion of Sensitive Information into Log File

    @@ -3342,7 +3593,7 @@

    MPL-2.0 license

    Package Manager: golang
  • - Module: + Vulnerable module: github.com/hashicorp/go-retryablehttp
  • @@ -3530,245 +3781,20 @@

    Detailed paths


    -

    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

    +

    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

    +
    diff --git a/docs/snyk/master/ghcr.io_dexidp_dex_v2.38.0.html b/docs/snyk/v2.11.8/ghcr.io_dexidp_dex_v2.38.0.html similarity index 73% rename from docs/snyk/master/ghcr.io_dexidp_dex_v2.38.0.html rename to docs/snyk/v2.11.8/ghcr.io_dexidp_dex_v2.38.0.html index ab099a1d4273b..3c41c7b540880 100644 --- a/docs/snyk/master/ghcr.io_dexidp_dex_v2.38.0.html +++ b/docs/snyk/v2.11.8/ghcr.io_dexidp_dex_v2.38.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    June 16th 2024, 12:16:20 am (UTC+00:00)

    +

    September 22nd 2024, 12:26:16 am (UTC+00:00)

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

    Snyk test report

    -
    34 known vulnerabilities
    -
    98 vulnerable dependency paths
    +
    18 known vulnerabilities
    +
    85 vulnerable dependency paths
    829 dependencies
    @@ -707,11 +707,11 @@

    Remediation

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

    References

    -

    MPL-2.0 license

    +

    Insertion of Sensitive Information into Log File

    @@ -1126,14 +1126,14 @@

    MPL-2.0 license

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

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0 - - - - -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/compressutil@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/jsonutil@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/pluginutil@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/strutil@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/logical@v0.5.0 + github.com/hashicorp/go-retryablehttp@v0.7.1 @@ -1204,17 +1159,25 @@

    Detailed paths


    -

    MPL-2.0 license

    +

    Overview

    +

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

    +

    Remediation

    +

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

    +

    References

    +
  • -

    MPL-2.0 license

    +

    Improper Handling of Highly Compressed Data (Data Amplification)

    @@ -1225,20 +1188,20 @@

    MPL-2.0 license

    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex /usr/local/bin/dex
    • Package Manager: golang
    • - Module: + Vulnerable module: - github.com/hashicorp/vault/api + github.com/go-jose/go-jose/v3
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/api@v1.6.0 + github.com/dexidp/dex@* and github.com/go-jose/go-jose/v3@v3.0.1
    @@ -1251,9 +1214,9 @@

    Detailed paths

    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + github.com/dexidp/dex@* - github.com/hashicorp/vault/api@v1.6.0 + github.com/go-jose/go-jose/v3@v3.0.1 @@ -1264,17 +1227,26 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      Overview

      +

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

      +

      Remediation

      +

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

      +

      References

      +
    -

    MPL-2.0 license

    +

    Out-of-bounds Write

    @@ -1285,20 +1257,17 @@

    MPL-2.0 license

    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang + Package Manager: alpine:3.19
    • - Module: + Vulnerable module: - github.com/hashicorp/serf/coordinate + busybox/busybox
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/serf/coordinate@v0.9.7 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15
    @@ -1311,9 +1280,51 @@

    Detailed paths

    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + 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 - github.com/hashicorp/serf/coordinate@v0.9.7 + busybox/ssl_client@1.36.1-r15 @@ -1324,17 +1335,26 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      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

      +
    -

    MPL-2.0 license

    +

    Use After Free

    @@ -1345,20 +1365,17 @@

    MPL-2.0 license

    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex /usr/local/bin/dex -
    • -
    • - Package Manager: golang + Package Manager: alpine:3.19
    • - Module: + Vulnerable module: - github.com/hashicorp/hcl/v2 + busybox/busybox
    • Introduced through: - github.com/dexidp/dex@* and github.com/hashicorp/hcl/v2@v2.13.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15
    @@ -1371,72 +1388,51 @@

    Detailed paths

    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.38.0 - github.com/hashicorp/hcl/v2@v2.13.0 + busybox/busybox@1.36.1-r15
    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.38.0 - github.com/hashicorp/hcl/v2/ext/customdecode@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* + alpine-baselayout/alpine-baselayout@3.4.3-r2 - github.com/hashicorp/hcl/v2/ext/tryfunc@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* + busybox/busybox-binsh@1.36.1-r15 - github.com/hashicorp/hcl/v2/gohcl@v2.13.0 + busybox/busybox@1.36.1-r15
    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.38.0 - github.com/hashicorp/hcl/v2/hclparse@v2.13.0 + busybox/busybox-binsh@1.36.1-r15
    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.38.0 - github.com/hashicorp/hcl/v2/hclsyntax@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* + alpine-baselayout/alpine-baselayout@3.4.3-r2 - github.com/hashicorp/hcl/v2/hclwrite@v2.13.0 + busybox/busybox-binsh@1.36.1-r15
    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.38.0 - github.com/hashicorp/hcl/v2/json@v2.13.0 + busybox/ssl_client@1.36.1-r15 @@ -1447,17 +1443,26 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      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

      +
    -

    MPL-2.0 license

    +

    Use After Free

    @@ -1468,20 +1473,17 @@

    MPL-2.0 license

    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang + Package Manager: alpine:3.19
    • - Module: + Vulnerable module: - github.com/hashicorp/hcl + busybox/busybox
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/hcl@v1.0.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15
    @@ -1494,18 +1496,51 @@

    Detailed paths

    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + docker-image|ghcr.io/dexidp/dex@v2.38.0 - github.com/hashicorp/hcl@v1.0.0 + busybox/busybox@1.36.1-r15
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + 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 - github.com/hashicorp/hcl/hcl/token@v1.0.0 + busybox/ssl_client@1.36.1-r15 @@ -1516,1004 +1551,26 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      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

      +
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/golang-lru/simplelru@v0.5.4 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-version@v1.5.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-sockaddr@v1.0.2 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-sockaddr/template@v1.0.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-retryablehttp@v0.7.1 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-plugin@v1.4.4 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-plugin/internal/plugin@v1.4.4 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

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

    Detailed paths

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

    MPL-2.0 license

    - -
    - - - -
    -
    -

    Improper Handling of Highly Compressed Data (Data Amplification)

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

    Detailed paths

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

    Overview

    -

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

    -

    Remediation

    -

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

    -

    References

    - - -
    - - - -
    -
    -

    Out-of-bounds Write

    +

    Use After Free

    @@ -2605,27 +1662,27 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. See How to fix? for Alpine:3.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.

    +

    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-r16 or higher.

    +

    Upgrade Alpine:3.19 busybox to version 1.36.1-r17 or higher.

    References


    -
    -

    Use After Free

    +
    +

    CVE-2023-6237

    -
    - medium severity +
    + low severity

    @@ -2637,12 +1694,12 @@

    Use After Free

  • Vulnerable module: - busybox/busybox + openssl/libcrypto3
  • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
  • @@ -2657,7 +1714,7 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r15 + openssl/libcrypto3@3.1.4-r2 @@ -2666,11 +1723,20 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r2 + apk-tools/apk-tools@2.14.0-r5 - busybox/busybox-binsh@1.36.1-r15 + openssl/libcrypto3@3.1.4-r2 + + + + +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r15 + busybox/ssl_client@1.36.1-r15 + + openssl/libcrypto3@3.1.4-r2 @@ -2679,7 +1745,11 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r15 + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 + + openssl/libcrypto3@3.1.4-r2 @@ -2688,9 +1758,18 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r2 + openssl/libssl3@3.1.4-r2 + + + +
  • +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r15 + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 @@ -2700,6 +1779,8 @@

    Detailed paths

    docker-image|ghcr.io/dexidp/dex@v2.38.0 busybox/ssl_client@1.36.1-r15 + + openssl/libssl3@3.1.4-r2 @@ -2711,29 +1792,53 @@

    Detailed paths


    NVD Description

    -

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

    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.

    -

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

    +

    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 busybox to version 1.36.1-r19 or higher.

    +

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

    References


  • -
    -

    Use After Free

    +
    +

    CVE-2024-2511

    -
    - medium severity +
    + low severity

    @@ -2745,12 +1850,12 @@

    Use After Free

  • Vulnerable module: - busybox/busybox + openssl/libcrypto3
  • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
  • @@ -2765,7 +1870,7 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r15 + openssl/libcrypto3@3.1.4-r2 @@ -2774,11 +1879,20 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r2 + apk-tools/apk-tools@2.14.0-r5 - busybox/busybox-binsh@1.36.1-r15 + openssl/libcrypto3@3.1.4-r2 + + + + +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r15 + busybox/ssl_client@1.36.1-r15 + + openssl/libcrypto3@3.1.4-r2 @@ -2787,7 +1901,11 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r15 + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 + + openssl/libcrypto3@3.1.4-r2 @@ -2796,9 +1914,18 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r2 + openssl/libssl3@3.1.4-r2 + + + +
  • +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r15 + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 @@ -2808,6 +1935,8 @@

    Detailed paths

    docker-image|ghcr.io/dexidp/dex@v2.38.0 busybox/ssl_client@1.36.1-r15 + + openssl/libssl3@3.1.4-r2 @@ -2819,29 +1948,49 @@

    Detailed paths


    NVD Description

    -

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

    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.

    -

    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.

    +

    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 busybox to version 1.36.1-r19 or higher.

    +

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

    References


  • -
    -

    Use After Free

    +
    +

    CVE-2024-4603

    -
    - medium severity +
    + low severity

    @@ -2853,12 +2002,12 @@

    Use After Free

  • Vulnerable module: - busybox/busybox + openssl/libcrypto3
  • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
  • @@ -2873,7 +2022,7 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r15 + openssl/libcrypto3@3.1.4-r2 @@ -2882,11 +2031,20 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r2 + apk-tools/apk-tools@2.14.0-r5 - busybox/busybox-binsh@1.36.1-r15 + openssl/libcrypto3@3.1.4-r2 + + + + +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r15 + busybox/ssl_client@1.36.1-r15 + + openssl/libcrypto3@3.1.4-r2 @@ -2895,7 +2053,11 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r15 + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 + + openssl/libcrypto3@3.1.4-r2 @@ -2904,9 +2066,18 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r2 + openssl/libssl3@3.1.4-r2 + + + +
  • +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r15 + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 @@ -2916,6 +2087,8 @@

    Detailed paths

    docker-image|ghcr.io/dexidp/dex@v2.38.0 busybox/ssl_client@1.36.1-r15 + + openssl/libssl3@3.1.4-r2 @@ -2927,25 +2100,53 @@

    Detailed paths


    NVD Description

    -

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

    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.

    -

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

    +

    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 busybox to version 1.36.1-r17 or higher.

    +

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

    References


  • -

    CVE-2023-6237

    +

    CVE-2024-5535

    @@ -3061,47 +2262,86 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.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.

    +

    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.4-r4 or higher.

    +

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

    References


    -

    CVE-2024-2511

    +

    CVE-2024-4741

    @@ -3215,45 +2455,19 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.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.

    +

    This vulnerability has not been analyzed by NVD yet.

    Remediation

    -

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

    -

    References

    - +

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


    -

    CVE-2024-4603

    +

    CVE-2024-6119

    @@ -3369,45 +2583,40 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.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.

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    Remediation

    -

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

    +

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

    References


    diff --git a/docs/snyk/v2.11.3/haproxy_2.6.14-alpine.html b/docs/snyk/v2.11.8/haproxy_2.6.14-alpine.html similarity index 77% rename from docs/snyk/v2.11.3/haproxy_2.6.14-alpine.html rename to docs/snyk/v2.11.8/haproxy_2.6.14-alpine.html index fa33763c2c255..51e9cc5e39b95 100644 --- a/docs/snyk/v2.11.3/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.11.8/haproxy_2.6.14-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    June 16th 2024, 12:18:41 am (UTC+00:00)

    +

    September 22nd 2024, 12:26:22 am (UTC+00:00)

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

    Snyk test report

    -
    11 known vulnerabilities
    -
    83 vulnerable dependency paths
    +
    14 known vulnerabilities
    +
    110 vulnerable dependency paths
    18 dependencies
    @@ -663,9 +663,9 @@

    References

  • http://www.openwall.com/lists/oss-security/2023/10/24/1
  • https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=0df40630850fb2740e6be6890bb905d3fc623b2d
  • https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=5f69f5c65e483928c4b28ed16af6e5742929f1ee
  • +
  • https://security.netapp.com/advisory/ntap-20231027-0010/
  • https://www.debian.org/security/2023/dsa-5532
  • https://www.openssl.org/news/secadv/20231024.txt
  • -
  • https://security.netapp.com/advisory/ntap-20231027-0010/
  • https://security.netapp.com/advisory/ntap-20240201-0003/
  • https://security.netapp.com/advisory/ntap-20240201-0004/
  • @@ -844,12 +844,12 @@

    Remediation

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

    References

    @@ -1031,11 +1031,11 @@

    Remediation

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

    References


    @@ -2191,6 +2192,547 @@

    References

    +
    +

    CVE-2024-5535

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

    Detailed paths

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

    NVD Description

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-4741

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

    Detailed paths

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

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

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

    + +
    + + + +
    +
    +

    CVE-2024-6119

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

    Detailed paths

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

    NVD Description

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

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

    +

    Remediation

    +

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

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/v2.11.3/quay.io_argoproj_argocd_v2.11.3.html b/docs/snyk/v2.11.8/quay.io_argoproj_argocd_v2.11.8.html similarity index 81% rename from docs/snyk/v2.11.3/quay.io_argoproj_argocd_v2.11.3.html rename to docs/snyk/v2.11.8/quay.io_argoproj_argocd_v2.11.8.html index f4f1f66704dd0..0a77724bd2238 100644 --- a/docs/snyk/v2.11.3/quay.io_argoproj_argocd_v2.11.3.html +++ b/docs/snyk/v2.11.8/quay.io_argoproj_argocd_v2.11.8.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,22 +456,22 @@

    Snyk test report

    -

    June 16th 2024, 12:18:59 am (UTC+00:00)

    +

    September 22nd 2024, 12:26:39 am (UTC+00:00)

    Scanned the following paths:
      -
    • quay.io/argoproj/argocd:v2.11.3/argoproj/argocd/Dockerfile (deb)
    • -
    • quay.io/argoproj/argocd:v2.11.3/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.11.3//usr/local/bin/kustomize (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.11.3/helm/v3//usr/local/bin/helm (gomodules)
    • -
    • quay.io/argoproj/argocd:v2.11.3/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.8/argoproj/argocd/Dockerfile (deb)
    • +
    • quay.io/argoproj/argocd:v2.11.8/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.8//usr/local/bin/kustomize (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.8/helm/v3//usr/local/bin/helm (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.11.8/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    -
    31 known vulnerabilities
    -
    197 vulnerable dependency paths
    +
    27 known vulnerabilities
    +
    173 vulnerable dependency paths
    2280 dependencies
    @@ -492,7 +492,7 @@

    Allocation of Resources Without Limits or Throttling

  • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argo-cd/v2 /usr/local/bin/argocd
  • Package Manager: golang @@ -561,7 +561,7 @@

    References

  • -

    CVE-2020-22916

    +

    CVE-2024-41996

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

    CVE-2020-22916

    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - xz-utils/liblzma5 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.11.3 and xz-utils/liblzma5@5.2.5-2ubuntu1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - xz-utils/liblzma5@5.2.5-2ubuntu1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

    An issue discovered in XZ 5.2.5 allows attackers to cause a denial of service via decompression of a crafted file. NOTE: the vendor disputes the claims of "endless output" and "denial of service" because decompression of the 17,486 bytes always results in 114,881,179 bytes, which is often a reasonable size increase.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 xz-utils.

    -

    References

    - - -
    - - - -
    -
    -

    Resource Exhaustion

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -661,7 +585,7 @@

      Resource Exhaustion

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 and openssl/libssl3@3.0.2-0ubuntu1.15 + docker-image|quay.io/argoproj/argocd@v2.11.8 and openssl/libssl3@3.0.2-0ubuntu1.18
    @@ -674,77 +598,77 @@

    Detailed paths

    @@ -833,7 +748,7 @@

    Information Exposure

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

      Information Exposure

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

    Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - apt@2.4.12 + apt@2.4.13 - apt/libapt-pkg6.0@2.4.12 + apt/libapt-pkg6.0@2.4.13 libgcrypt20@1.9.4-3ubuntu3 @@ -903,9 +818,9 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - apt@2.4.12 + apt@2.4.13 gnupg2/gpgv@2.2.27-3ubuntu2.1 @@ -916,7 +831,7 @@

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - apt@2.4.12 + apt@2.4.13 - apt/libapt-pkg6.0@2.4.12 + apt/libapt-pkg6.0@2.4.13 systemd/libsystemd0@249.11-0ubuntu3.12 @@ -1046,7 +961,7 @@

      CVE-2024-26462

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

        CVE-2024-26462

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
      @@ -1072,16 +987,16 @@

      Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -1093,16 +1008,16 @@

        Detailed paths

        libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -1114,27 +1029,27 @@

        Detailed paths

        libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -1146,64 +1061,64 @@

        Detailed paths

        libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - openssh/openssh-client@1:8.9p1-3ubuntu0.7 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -1215,16 +1130,16 @@

        Detailed paths

        libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libkrb5support0@1.19.2-2ubuntu0.3 + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -1256,7 +1171,7 @@

        References

    -

    LGPL-3.0 license

    +

    Denial of Service (DoS)

    @@ -1267,20 +1182,20 @@

    LGPL-3.0 license

    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • Package Manager: golang
    • - Module: + Vulnerable module: - gopkg.in/retry.v1 + github.com/rs/cors
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and gopkg.in/retry.v1@v1.0.3 + github.com/argoproj/argo-cd/v2@* and github.com/rs/cors@v1.9.0
    @@ -1295,7 +1210,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@* - gopkg.in/retry.v1@v1.0.3 + github.com/rs/cors@v1.9.0 @@ -1306,17 +1221,67 @@

    Detailed paths


    -

    LGPL-3.0 license

    +

    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

    +

    Insertion of Sensitive Information into Log File

    @@ -1327,20 +1292,20 @@

    MPL-2.0 license

    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argo-cd/v2 /usr/local/bin/argocd
    • Package Manager: golang
    • - Module: + Vulnerable module: - github.com/r3labs/diff + github.com/hashicorp/go-retryablehttp
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/r3labs/diff@v1.1.0 + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.4
    @@ -1355,7 +1320,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@* - github.com/r3labs/diff@v1.1.0 + github.com/hashicorp/go-retryablehttp@v0.7.4 @@ -1366,17 +1331,25 @@

    Detailed paths


    -

    MPL-2.0 license

    +

    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

    +

    CVE-2023-4039

    @@ -1387,20 +1360,20 @@

    MPL-2.0 license

    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
    • - Package Manager: golang + Package Manager: ubuntu:22.04
    • - Module: + Vulnerable module: - github.com/hashicorp/go-version + gcc-12/libstdc++6
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-version@v1.2.1 + docker-image|quay.io/argoproj/argocd@v2.11.8 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04
    @@ -1413,9 +1386,51 @@

    Detailed paths

    • Introduced through: - github.com/argoproj/argo-cd/v2@* + docker-image|quay.io/argoproj/argocd@v2.11.8 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.8 + + apt@2.4.13 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.8 + + 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.8 + + gcc-12/gcc-12-base@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.11.8 - github.com/hashicorp/go-version@v1.2.1 + gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 @@ -1426,17 +1441,40 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      NVD Description

      +

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

      +

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

      +

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

      +

      Remediation

      +

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

      +

      References

      +
    -

    MPL-2.0 license

    +

    Integer Overflow or Wraparound

    @@ -1447,21 +1485,21 @@

    MPL-2.0 license

    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
    • - Package Manager: golang + Package Manager: ubuntu:22.04
    • - Module: + Vulnerable module: - github.com/hashicorp/go-retryablehttp + expat/libexpat1
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.4 + docker-image|quay.io/argoproj/argocd@v2.11.8, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1473,9 +1511,11 @@

    Detailed paths

    -

    MPL-2.0 license

    +

    XML External Entity (XXE) Injection

    @@ -1507,21 +1558,21 @@

    MPL-2.0 license

    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/helm/v3 /usr/local/bin/helm + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
    • - Package Manager: golang + Package Manager: ubuntu:22.04
    • - Module: + Vulnerable module: - github.com/hashicorp/go-multierror + expat/libexpat1
    • Introduced through: - helm.sh/helm/v3@* and github.com/hashicorp/go-multierror@v1.1.1 + docker-image|quay.io/argoproj/argocd@v2.11.8, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1533,9 +1584,11 @@

    Detailed paths

    -

    MPL-2.0 license

    +

    Integer Overflow or Wraparound

    @@ -1567,21 +1631,21 @@

    MPL-2.0 license

    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
    • - Package Manager: golang + Package Manager: ubuntu:22.04
    • - Module: + Vulnerable module: - github.com/hashicorp/go-cleanhttp + expat/libexpat1
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-cleanhttp@v0.5.2 + docker-image|quay.io/argoproj/argocd@v2.11.8, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1593,9 +1657,11 @@

    Detailed paths

    -

    MPL-2.0 license

    +

    CVE-2024-8096

    @@ -1627,21 +1704,21 @@

    MPL-2.0 license

    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argo-cd/v2 /usr/local/bin/argocd + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
    • - Package Manager: golang + Package Manager: ubuntu:22.04
    • - Module: + Vulnerable module: - github.com/gosimple/slug + curl/libcurl3-gnutls
    • Introduced through: - github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.13.1 + docker-image|quay.io/argoproj/argocd@v2.11.8, git@1:2.34.1-1ubuntu1.11 and others
    @@ -1653,9 +1730,11 @@

    Detailed paths

    • Introduced through: - github.com/argoproj/argo-cd/v2@* + docker-image|quay.io/argoproj/argocd@v2.11.8 + + git@1:2.34.1-1ubuntu1.11 - github.com/gosimple/slug@v1.13.1 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 @@ -1666,12 +1745,24 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      NVD Description

      +

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

      +

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

      +

      Remediation

      +

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

      +

      References

      +
    @@ -1687,7 +1778,7 @@

    CVE-2023-7008

    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -1700,7 +1791,7 @@

      CVE-2023-7008

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

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 systemd/libsystemd0@249.11-0ubuntu3.12 @@ -1722,9 +1813,9 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - apt@2.4.12 + apt@2.4.13 systemd/libsystemd0@249.11-0ubuntu3.12 @@ -1733,7 +1824,7 @@

      Detailed paths

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

      Detailed paths

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

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 util-linux/bsdutils@1:2.37.2-4ubuntu3.4 @@ -1766,11 +1857,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - apt@2.4.12 + apt@2.4.13 - apt/libapt-pkg6.0@2.4.12 + apt/libapt-pkg6.0@2.4.13 systemd/libsystemd0@249.11-0ubuntu3.12 @@ -1779,7 +1870,7 @@

      Detailed paths

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

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 libfido2/libfido2-1@1.10.0-1 @@ -1799,7 +1890,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 util-linux@2.37.2-4ubuntu3.4 @@ -1810,11 +1901,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - apt@2.4.12 + apt@2.4.13 - apt/libapt-pkg6.0@2.4.12 + apt/libapt-pkg6.0@2.4.13 systemd/libudev1@249.11-0ubuntu3.12 @@ -1865,7 +1956,7 @@

      Arbitrary Code Injection

      • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -1878,7 +1969,7 @@

        Arbitrary Code Injection

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

      Detailed paths

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

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -1911,430 +2002,20 @@

        Detailed paths

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - openssh/openssh-client@1:8.9p1-3ubuntu0.7 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - - -
      • -
      • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - shadow/login@1:4.8.1-2ubuntu2.2 - - - -
      • -
      - -
    - -
    - -

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 shadow.

    -

    References

    - - -
    - - - -
    -
    -

    Uncontrolled Recursion

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

    Detailed paths

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

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 pcre3.

    -

    References

    - - -
    - - - -
    -
    -

    Release of Invalid Pointer or Reference

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - patch -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.11.3 and patch@2.7.6-7build2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - patch@2.7.6-7build2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 patch.

    -

    References

    - - -
    - - - -
    -
    -

    Double Free

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile -
    • -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - patch -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.11.3 and patch@2.7.6-7build2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - patch@2.7.6-7build2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

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

    -

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

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 patch.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2024-2511

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

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - openssl/libssl3@3.0.2-0ubuntu1.15 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.15 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.15 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - openssh/openssh-client@1:8.9p1-3ubuntu0.7 - - openssl/libssl3@3.0.2-0ubuntu1.15 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.15 - - openssl/libssl3@3.0.2-0ubuntu1.15 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - git@1:2.34.1-1ubuntu1.11 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - - openssl/libssl3@3.0.2-0ubuntu1.15 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - krb5/libkrb5-3@1.19.2-2ubuntu0.3 - - openssl/libssl3@3.0.2-0ubuntu1.15 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 - openssl@3.0.2-0ubuntu1.15 + shadow/passwd@1:4.8.1-2ubuntu2.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - ca-certificates@20230311ubuntu0.22.04.1 + docker-image|quay.io/argoproj/argocd@v2.11.8 - openssl@3.0.2-0ubuntu1.15 + shadow/login@1:4.8.1-2ubuntu2.2 @@ -2346,46 +2027,29 @@

      Detailed paths


      NVD Description

      -

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

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

      -

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

      -

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

      -

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

      -

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

      -

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

      +

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

      +

      There is no fixed version for Ubuntu:22.04 shadow.

      References


    -

    CVE-2024-4603

    +

    Uncontrolled Recursion

    @@ -2396,7 +2060,7 @@

    CVE-2024-4603

    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -2404,12 +2068,12 @@

      CVE-2024-4603

    • Vulnerable module: - openssl/libssl3 + pcre3/libpcre3
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 and openssl/libssl3@3.0.2-0ubuntu1.15 + docker-image|quay.io/argoproj/argocd@v2.11.8 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1
    @@ -2422,113 +2086,20 @@

    Detailed paths

    -

    CVE-2024-4741

    +

    Release of Invalid Pointer or Reference

    @@ -2597,7 +2148,7 @@

    CVE-2024-4741

    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -2605,12 +2156,12 @@

      CVE-2024-4741

    • Vulnerable module: - openssl/libssl3 + patch
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 and openssl/libssl3@3.0.2-0ubuntu1.15 + docker-image|quay.io/argoproj/argocd@v2.11.8 and patch@2.7.6-7build2
    @@ -2623,113 +2174,79 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - openssl/libssl3@3.0.2-0ubuntu1.15 + patch@2.7.6-7build2
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.15 - - +
    - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.15 - - +
  • - -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - openssh/openssh-client@1:8.9p1-3ubuntu0.7 - - openssl/libssl3@3.0.2-0ubuntu1.15 - - +
    + +

    NVD Description

    +

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

    +

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

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 patch.

    +

    References

    + -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.15 - - openssl/libssl3@3.0.2-0ubuntu1.15 - - +
    -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - git@1:2.34.1-1ubuntu1.11 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - - openssl/libssl3@3.0.2-0ubuntu1.15 - - + -
  • -
  • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.2 - - pam/libpam-modules@1.4.0-11ubuntu2.4 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 - - krb5/libkrb5-3@1.19.2-2ubuntu0.3 - - openssl/libssl3@3.0.2-0ubuntu1.15 - - +
  • +
    +

    Double Free

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

    Detailed paths

    + +
    @@ -2768,7 +2293,7 @@

    CVE-2023-50495

    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
    • Package Manager: ubuntu:22.04 @@ -2781,7 +2306,7 @@

      CVE-2023-50495

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 and ncurses/libtinfo6@6.3-2ubuntu0.1 + docker-image|quay.io/argoproj/argocd@v2.11.8 and ncurses/libtinfo6@6.3-2ubuntu0.1
    @@ -2794,7 +2319,7 @@

    Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      Detailed paths

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

      CVE-2023-45918

      • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
      • Package Manager: ubuntu:22.04 @@ -3045,7 +2570,7 @@

        CVE-2023-45918

      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 and ncurses/libtinfo6@6.3-2ubuntu0.1 + docker-image|quay.io/argoproj/argocd@v2.11.8 and ncurses/libtinfo6@6.3-2ubuntu0.1
      @@ -3058,7 +2583,7 @@

      Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Detailed paths

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

        Resource Exhaustion

        • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
        • Package Manager: ubuntu:22.04 @@ -3307,7 +2832,7 @@

          Resource Exhaustion

        • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 and libzstd/libzstd1@1.4.8+dfsg-3build1 + docker-image|quay.io/argoproj/argocd@v2.11.8 and libzstd/libzstd1@1.4.8+dfsg-3build1
        @@ -3320,7 +2845,7 @@

        Detailed paths

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

          Integer Overflow or Wraparound

          • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
          • Package Manager: ubuntu:22.04 @@ -3384,7 +2909,7 @@

            Integer Overflow or Wraparound

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
          @@ -3397,16 +2922,16 @@

          Detailed paths

          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -3418,16 +2943,16 @@

            Detailed paths

            libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -3439,27 +2964,27 @@

            Detailed paths

            libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -3471,64 +2996,64 @@

            Detailed paths

            libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - openssh/openssh-client@1:8.9p1-3ubuntu0.7 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -3540,16 +3065,16 @@

            Detailed paths

            libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
          • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libkrb5support0@1.19.2-2ubuntu0.3 + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -3595,7 +3120,7 @@

            CVE-2024-26461

            • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
            • Package Manager: ubuntu:22.04 @@ -3608,7 +3133,7 @@

              CVE-2024-26461

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
            @@ -3621,16 +3146,16 @@

            Detailed paths

            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -3642,16 +3167,16 @@

              Detailed paths

              libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -3663,27 +3188,27 @@

              Detailed paths

              libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -3695,64 +3220,64 @@

              Detailed paths

              libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - openssh/openssh-client@1:8.9p1-3ubuntu0.7 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -3764,16 +3289,16 @@

              Detailed paths

              libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
            • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libkrb5support0@1.19.2-2ubuntu0.3 + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -3816,7 +3341,7 @@

              CVE-2024-26458

              • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
              • Package Manager: ubuntu:22.04 @@ -3829,7 +3354,7 @@

                CVE-2024-26458

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 and krb5/libk5crypto3@1.19.2-2ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 and krb5/libk5crypto3@1.19.2-2ubuntu0.4
              @@ -3842,16 +3367,16 @@

              Detailed paths

              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -3863,16 +3388,16 @@

                Detailed paths

                libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -3884,27 +3409,27 @@

                Detailed paths

                libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4 - krb5/libk5crypto3@1.19.2-2ubuntu0.3 + krb5/libk5crypto3@1.19.2-2ubuntu0.4
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -3916,64 +3441,64 @@

                Detailed paths

                libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4 - krb5/libkrb5-3@1.19.2-2ubuntu0.3 + krb5/libkrb5-3@1.19.2-2ubuntu0.4
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - openssh/openssh-client@1:8.9p1-3ubuntu0.7 + openssh/openssh-client@1:8.9p1-3ubuntu0.10 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 git@1:2.34.1-1ubuntu1.11 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.16 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.17 libssh/libssh-4@0.9.6-2ubuntu0.22.04.3 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 adduser@3.118ubuntu5 @@ -3985,16 +3510,16 @@

                Detailed paths

                libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.3 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.4
              • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - krb5/libkrb5support0@1.19.2-2ubuntu0.3 + krb5/libkrb5support0@1.19.2-2ubuntu0.4 @@ -4037,7 +3562,7 @@

                Out-of-bounds Write

                • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
                • Package Manager: ubuntu:22.04 @@ -4050,7 +3575,7 @@

                  Out-of-bounds Write

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 and gnupg2/gpgv@2.2.27-3ubuntu2.1 + docker-image|quay.io/argoproj/argocd@v2.11.8 and gnupg2/gpgv@2.2.27-3ubuntu2.1
                @@ -4063,7 +3588,7 @@

                Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 gnupg2/gpgv@2.2.27-3ubuntu2.1 @@ -4072,9 +3597,9 @@

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - apt@2.4.12 + apt@2.4.13 gnupg2/gpgv@2.2.27-3ubuntu2.1 @@ -4083,7 +3608,7 @@

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Detailed paths

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

                  Allocation of Resources Without Limits or Throttling

                • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
                • Package Manager: ubuntu:22.04 @@ -4429,7 +3954,7 @@

                  Allocation of Resources Without Limits or Throttling

                  Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 and glibc/libc-bin@2.35-0ubuntu3.8 + docker-image|quay.io/argoproj/argocd@v2.11.8 and glibc/libc-bin@2.35-0ubuntu3.8
                @@ -4442,7 +3967,7 @@

                Detailed paths

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

                  Detailed paths

                • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 glibc/libc6@2.35-0ubuntu3.8 @@ -4473,9 +3998,9 @@

                  Remediation

                  References


                  @@ -4497,7 +4022,7 @@

                  Improper Input Validation

                  • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
                  • Package Manager: ubuntu:22.04 @@ -4511,7 +4036,7 @@

                    Improper Input Validation

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

                  Detailed paths

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

                    Detailed paths

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

                    Detailed paths

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

                    Uncontrolled Recursion

                    • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
                    • Package Manager: ubuntu:22.04 @@ -4603,7 +4128,7 @@

                      Uncontrolled Recursion

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

                    Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 @@ -4625,9 +4150,9 @@

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - apt@2.4.12 + apt@2.4.13 gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 @@ -4636,11 +4161,11 @@

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 - apt@2.4.12 + apt@2.4.13 - apt/libapt-pkg6.0@2.4.12 + apt/libapt-pkg6.0@2.4.13 gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 @@ -4649,7 +4174,7 @@

                      Detailed paths

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

                      Detailed paths

                    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 @@ -4681,8 +4206,8 @@

                      References

                      @@ -4705,7 +4230,7 @@

                      Improper Input Validation

                      • - Manifest file: quay.io/argoproj/argocd:v2.11.3/argoproj/argocd Dockerfile + Manifest file: quay.io/argoproj/argocd:v2.11.8/argoproj/argocd Dockerfile
                      • Package Manager: ubuntu:22.04 @@ -4718,7 +4243,7 @@

                        Improper Input Validation

                      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 and coreutils@8.32-4.1ubuntu1.2 + docker-image|quay.io/argoproj/argocd@v2.11.8 and coreutils@8.32-4.1ubuntu1.2
                      @@ -4731,7 +4256,7 @@

                      Detailed paths

                      • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.11.3 + docker-image|quay.io/argoproj/argocd@v2.11.8 coreutils@8.32-4.1ubuntu1.2 diff --git a/docs/snyk/v2.11.8/redis_7.0.15-alpine.html b/docs/snyk/v2.11.8/redis_7.0.15-alpine.html new file mode 100644 index 0000000000000..1a6806f71cefa --- /dev/null +++ b/docs/snyk/v2.11.8/redis_7.0.15-alpine.html @@ -0,0 +1,484 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
                        +
                        +
                        +
                        + + + Snyk - Open Source Security + + + + + + + +
                        +

                        Snyk test report

                        + +

                        September 22nd 2024, 12:26:43 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)
                        • +
                        +
                        + +
                        +
                        0 known vulnerabilities
                        +
                        0 vulnerable dependency paths
                        +
                        18 dependencies
                        +
                        +
                        +
                        +
                        + +
                        + No known vulnerabilities detected. +
                        +
                        + + + diff --git a/docs/snyk/v2.12.3/argocd-iac-install.html b/docs/snyk/v2.12.3/argocd-iac-install.html new file mode 100644 index 0000000000000..268b77b876e08 --- /dev/null +++ b/docs/snyk/v2.12.3/argocd-iac-install.html @@ -0,0 +1,2891 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
                        +
                        +
                        +
                        + + + Snyk - Open Source Security + + + + + + + +
                        +

                        Snyk test report

                        + +

                        September 22nd 2024, 12:25:50 am (UTC+00:00)

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

                        Role or ClusterRole with dangerous permissions

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

                        Consider removing these permissions

                        + + +
                        +
                        + + + +
                        +
                        +

                        Role or ClusterRole with dangerous permissions

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

                        Consider removing these permissions

                        + + +
                        +
                        + + + +
                        +
                        +

                        Role or ClusterRole with dangerous permissions

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

                        Consider removing these permissions

                        + + +
                        +
                        + + + +
                        +
                        +

                        Role or ClusterRole with dangerous permissions

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

                        Consider removing these permissions

                        + + +
                        +
                        + + + +
                        +
                        +

                        Role or ClusterRole with dangerous permissions

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

                        Consider removing these permissions

                        + + +
                        +
                        + + + +
                        +
                        +

                        Role or ClusterRole with dangerous permissions

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

                        Consider removing these permissions

                        + + +
                        +
                        + + + +
                        +
                        +

                        Role or ClusterRole with dangerous permissions

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

                        Consider removing these permissions

                        + + +
                        +
                        + + + +
                        +
                        +

                        Role or ClusterRole with dangerous permissions

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

                        Consider removing these permissions

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container could be running with outdated image

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

                        Impact

                        +

                        The container may run with outdated or unauthorized image

                        + +

                        Remediation

                        +

                        Set `imagePullPolicy` attribute to `Always`

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container could be running with outdated image

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

                        Impact

                        +

                        The container may run with outdated or unauthorized image

                        + +

                        Remediation

                        +

                        Set `imagePullPolicy` attribute to `Always`

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container has no CPU limit

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

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

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container has no CPU limit

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

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

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container has no CPU limit

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

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

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container has no CPU limit

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

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

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container has no CPU limit

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

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

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container has no CPU limit

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

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

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container has no CPU limit

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

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

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container has no CPU limit

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

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

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container has no CPU limit

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

                        Impact

                        +

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

                        + +

                        Remediation

                        +

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

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container has no CPU limit

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

                        Impact

                        +

                        CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

                        + +

                        Remediation

                        +

                        Add `resources.limits.cpu` field with required CPU limit value

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running with multiple open ports

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-36 +
                        • + +
                        • Introduced through: + [DocId: 46] + + spec + + template + + spec + + containers[dex] + + ports + +
                        • + +
                        • + Line number: 21831 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Increases the attack surface of the application and the container.

                        + +

                        Remediation

                        +

                        Reduce `ports` count to 2

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running without liveness probe

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-41 +
                        • + +
                        • Introduced through: + [DocId: 45] + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + livenessProbe + +
                        • + +
                        • + Line number: 21600 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

                        + +

                        Remediation

                        +

                        Add `livenessProbe` attribute

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running without liveness probe

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-41 +
                        • + +
                        • Introduced through: + [DocId: 46] + + spec + + template + + spec + + containers[dex] + + livenessProbe + +
                        • + +
                        • + Line number: 21817 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

                        + +

                        Remediation

                        +

                        Add `livenessProbe` attribute

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running without liveness probe

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-41 +
                        • + +
                        • Introduced through: + [DocId: 48] + + spec + + template + + spec + + containers[redis] + + livenessProbe + +
                        • + +
                        • + Line number: 22010 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

                        + +

                        Remediation

                        +

                        Add `livenessProbe` attribute

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running without memory limit

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-4 +
                        • + +
                        • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + resources + + limits + + memory + +
                        • + +
                        • + Line number: 21600 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Containers without memory limits are more likely to be terminated when the node runs out of memory

                        + +

                        Remediation

                        +

                        Set `resources.limits.memory` value

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running without memory limit

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-4 +
                        • + +
                        • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + containers[dex] + + resources + + limits + + memory + +
                        • + +
                        • + Line number: 21817 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Containers without memory limits are more likely to be terminated when the node runs out of memory

                        + +

                        Remediation

                        +

                        Set `resources.limits.memory` value

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running without memory limit

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-4 +
                        • + +
                        • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + memory + +
                        • + +
                        • + Line number: 21851 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Containers without memory limits are more likely to be terminated when the node runs out of memory

                        + +

                        Remediation

                        +

                        Set `resources.limits.memory` value

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running without memory limit

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-4 +
                        • + +
                        • Introduced through: + [DocId: 47] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + resources + + limits + + memory + +
                        • + +
                        • + Line number: 21911 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Containers without memory limits are more likely to be terminated when the node runs out of memory

                        + +

                        Remediation

                        +

                        Set `resources.limits.memory` value

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running without memory limit

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-4 +
                        • + +
                        • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + containers[redis] + + resources + + limits + + memory + +
                        • + +
                        • + Line number: 22010 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Containers without memory limits are more likely to be terminated when the node runs out of memory

                        + +

                        Remediation

                        +

                        Set `resources.limits.memory` value

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running without memory limit

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-4 +
                        • + +
                        • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + initContainers[secret-init] + + resources + + limits + + memory + +
                        • + +
                        • + Line number: 22034 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Containers without memory limits are more likely to be terminated when the node runs out of memory

                        + +

                        Remediation

                        +

                        Set `resources.limits.memory` value

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running without memory limit

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-4 +
                        • + +
                        • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + memory + +
                        • + +
                        • + Line number: 22338 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Containers without memory limits are more likely to be terminated when the node runs out of memory

                        + +

                        Remediation

                        +

                        Set `resources.limits.memory` value

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running without memory limit

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-4 +
                        • + +
                        • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + resources + + limits + + memory + +
                        • + +
                        • + Line number: 22091 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Containers without memory limits are more likely to be terminated when the node runs out of memory

                        + +

                        Remediation

                        +

                        Set `resources.limits.memory` value

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running without memory limit

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-4 +
                        • + +
                        • Introduced through: + [DocId: 50] + + input + + spec + + template + + spec + + containers[argocd-server] + + resources + + limits + + memory + +
                        • + +
                        • + Line number: 22423 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Containers without memory limits are more likely to be terminated when the node runs out of memory

                        + +

                        Remediation

                        +

                        Set `resources.limits.memory` value

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container is running without memory limit

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-4 +
                        • + +
                        • Introduced through: + [DocId: 51] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + resources + + limits + + memory + +
                        • + +
                        • + Line number: 22774 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        Containers without memory limits are more likely to be terminated when the node runs out of memory

                        + +

                        Remediation

                        +

                        Set `resources.limits.memory` value

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container's or Pod's UID could clash with host's UID

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-11 +
                        • + +
                        • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + securityContext + + runAsUser + +
                        • + +
                        • + Line number: 21741 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

                        + +

                        Remediation

                        +

                        Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container's or Pod's UID could clash with host's UID

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-11 +
                        • + +
                        • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + initContainers[copyutil] + + securityContext + + runAsUser + +
                        • + +
                        • + Line number: 21859 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

                        + +

                        Remediation

                        +

                        Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container's or Pod's UID could clash with host's UID

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-11 +
                        • + +
                        • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + containers[dex] + + securityContext + + runAsUser + +
                        • + +
                        • + Line number: 21834 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

                        + +

                        Remediation

                        +

                        Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container's or Pod's UID could clash with host's UID

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-11 +
                        • + +
                        • Introduced through: + [DocId: 47] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + securityContext + + runAsUser + +
                        • + +
                        • + Line number: 21944 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

                        + +

                        Remediation

                        +

                        Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container's or Pod's UID could clash with host's UID

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-11 +
                        • + +
                        • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + containers[redis] + + securityContext + + runAsUser + +
                        • + +
                        • + Line number: 22027 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

                        + +

                        Remediation

                        +

                        Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container's or Pod's UID could clash with host's UID

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-11 +
                        • + +
                        • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + initContainers[secret-init] + + securityContext + + runAsUser + +
                        • + +
                        • + Line number: 22041 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

                        + +

                        Remediation

                        +

                        Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container's or Pod's UID could clash with host's UID

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-11 +
                        • + +
                        • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + initContainers[copyutil] + + securityContext + + runAsUser + +
                        • + +
                        • + Line number: 22345 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

                        + +

                        Remediation

                        +

                        Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container's or Pod's UID could clash with host's UID

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-11 +
                        • + +
                        • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + securityContext + + runAsUser + +
                        • + +
                        • + Line number: 22311 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

                        + +

                        Remediation

                        +

                        Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container's or Pod's UID could clash with host's UID

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-11 +
                        • + +
                        • Introduced through: + [DocId: 50] + + input + + spec + + template + + spec + + containers[argocd-server] + + securityContext + + runAsUser + +
                        • + +
                        • + Line number: 22684 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

                        + +

                        Remediation

                        +

                        Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

                        + + +
                        +
                        + + + +
                        +
                        +

                        Container's or Pod's UID could clash with host's UID

                        +
                        + +
                        + low severity +
                        + +
                        + +
                          +
                        • + Public ID: SNYK-CC-K8S-11 +
                        • + +
                        • Introduced through: + [DocId: 51] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + securityContext + + runAsUser + +
                        • + +
                        • + Line number: 22975 +
                        • +
                        + +
                        + +

                        Impact

                        +

                        UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

                        + +

                        Remediation

                        +

                        Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

                        + + +
                        +
                        + + + +
                        +
                        +
                        + +
                        + + + diff --git a/docs/snyk/v2.9.17/argocd-iac-namespace-install.html b/docs/snyk/v2.12.3/argocd-iac-namespace-install.html similarity index 98% rename from docs/snyk/v2.9.17/argocd-iac-namespace-install.html rename to docs/snyk/v2.12.3/argocd-iac-namespace-install.html index e07f677ceb5da..aab9b5b3686cb 100644 --- a/docs/snyk/v2.9.17/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.12.3/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

                        Snyk test report

                        -

                        June 16th 2024, 12:24:52 am (UTC+00:00)

                        +

                        September 22nd 2024, 12:25:59 am (UTC+00:00)

                        Scanned the following path: @@ -553,7 +553,7 @@

                        Role or ClusterRole with dangerous permissions

                      • - Line number: 162 + Line number: 164
                      @@ -599,7 +599,7 @@

                      Role or ClusterRole with dangerous permissions

                    • - Line number: 190 + Line number: 192
                    @@ -645,7 +645,7 @@

                    Role or ClusterRole with dangerous permissions

                  • - Line number: 220 + Line number: 222
                  @@ -691,7 +691,7 @@

                  Role or ClusterRole with dangerous permissions

                • - Line number: 238 + Line number: 240
                @@ -737,7 +737,7 @@

                Role or ClusterRole with dangerous permissions

              • - Line number: 256 + Line number: 258
              @@ -783,7 +783,7 @@

              Role or ClusterRole with dangerous permissions

            • - Line number: 278 + Line number: 280
            @@ -835,7 +835,7 @@

            Container could be running with outdated image

          • - Line number: 1100 + Line number: 1114
          @@ -887,7 +887,7 @@

          Container could be running with outdated image

        • - Line number: 1357 + Line number: 1413
        @@ -945,7 +945,7 @@

        Container has no CPU limit

      • - Line number: 673 + Line number: 675
      @@ -1003,7 +1003,7 @@

      Container has no CPU limit

    • - Line number: 918 + Line number: 926
    @@ -1061,7 +1061,7 @@

    Container has no CPU limit

  • - Line number: 884 + Line number: 892
  • @@ -1119,7 +1119,7 @@

    Container has no CPU limit

  • - Line number: 978 + Line number: 986
  • @@ -1177,7 +1177,7 @@

    Container has no CPU limit

  • - Line number: 1071 + Line number: 1085
  • @@ -1235,7 +1235,7 @@

    Container has no CPU limit

  • - Line number: 1095 + Line number: 1109
  • @@ -1293,7 +1293,7 @@

    Container has no CPU limit

  • - Line number: 1357 + Line number: 1413
  • @@ -1351,7 +1351,7 @@

    Container has no CPU limit

  • - Line number: 1152 + Line number: 1166
  • @@ -1409,7 +1409,7 @@

    Container has no CPU limit

  • - Line number: 1442 + Line number: 1498
  • @@ -1467,7 +1467,7 @@

    Container has no CPU limit

  • - Line number: 1769 + Line number: 1849
  • @@ -1519,7 +1519,7 @@

    Container is running with multiple open ports

  • - Line number: 898 + Line number: 906
  • @@ -1571,7 +1571,7 @@

    Container is running without liveness probe

  • - Line number: 673 + Line number: 675
  • @@ -1623,7 +1623,7 @@

    Container is running without liveness probe

  • - Line number: 884 + Line number: 892
  • @@ -1675,7 +1675,7 @@

    Container is running without liveness probe

  • - Line number: 1071 + Line number: 1085
  • @@ -1733,7 +1733,7 @@

    Container is running without memory limit

  • - Line number: 673 + Line number: 675
  • @@ -1791,7 +1791,7 @@

    Container is running without memory limit

  • - Line number: 884 + Line number: 892
  • @@ -1849,7 +1849,7 @@

    Container is running without memory limit

  • - Line number: 918 + Line number: 926
  • @@ -1907,7 +1907,7 @@

    Container is running without memory limit

  • - Line number: 978 + Line number: 986
  • @@ -1965,7 +1965,7 @@

    Container is running without memory limit

  • - Line number: 1071 + Line number: 1085
  • @@ -2023,7 +2023,7 @@

    Container is running without memory limit

  • - Line number: 1095 + Line number: 1109
  • @@ -2081,7 +2081,7 @@

    Container is running without memory limit

  • - Line number: 1357 + Line number: 1413
  • @@ -2139,7 +2139,7 @@

    Container is running without memory limit

  • - Line number: 1152 + Line number: 1166
  • @@ -2197,7 +2197,7 @@

    Container is running without memory limit

  • - Line number: 1442 + Line number: 1498
  • @@ -2255,7 +2255,7 @@

    Container is running without memory limit

  • - Line number: 1769 + Line number: 1849
  • @@ -2311,7 +2311,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 808 + Line number: 816
  • @@ -2367,7 +2367,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 926 + Line number: 934
  • @@ -2423,7 +2423,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 901 + Line number: 909
  • @@ -2479,7 +2479,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1005 + Line number: 1019
  • @@ -2535,7 +2535,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1088 + Line number: 1102
  • @@ -2591,7 +2591,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1102 + Line number: 1116
  • @@ -2647,7 +2647,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1364 + Line number: 1420
  • @@ -2703,7 +2703,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1330 + Line number: 1386
  • @@ -2759,7 +2759,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1679 + Line number: 1759
  • @@ -2815,7 +2815,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1928 + Line number: 2050
  • diff --git a/docs/snyk/v2.12.3/argocd-test.html b/docs/snyk/v2.12.3/argocd-test.html new file mode 100644 index 0000000000000..c5ace95defe54 --- /dev/null +++ b/docs/snyk/v2.12.3/argocd-test.html @@ -0,0 +1,1086 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    September 22nd 2024, 12:23:57 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • /argo-cd/argoproj/argo-cd/v2/go.mod (gomodules)
    • +
    • /argo-cd/ui/yarn.lock (yarn)
    • +
    +
    + +
    +
    5 known vulnerabilities
    +
    7 vulnerable dependency paths
    +
    2061 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    Prototype Pollution

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd ui/yarn.lock +
    • +
    • + Package Manager: npm +
    • +
    • + Vulnerable module: + + dompurify +
    • + +
    • Introduced through: + + + argo-cd-ui@1.0.0, redoc@2.0.0-rc.64 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + argo-cd-ui@1.0.0 + + redoc@2.0.0-rc.64 + + dompurify@2.3.6 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    dompurify is a DOM-only XSS sanitizer for HTML, MathML and SVG.

    +

    Affected versions of this package are vulnerable to Prototype Pollution due to improper user input sanitization through the depth-checking mechanism, an attacker can exploit this vulnerability by using special nesting techniques to create a malicious HTML file.

    +

    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 dompurify to version 2.5.4, 3.1.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Regular Expression Denial of Service (ReDoS)

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd ui/yarn.lock +
    • +
    • + Package Manager: npm +
    • +
    • + Vulnerable module: + + path-to-regexp +
    • + +
    • Introduced through: + + + argo-cd-ui@1.0.0, react-router@4.3.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + argo-cd-ui@1.0.0 + + react-router@4.3.1 + + path-to-regexp@1.8.0 + + + +
    • +
    • + Introduced through: + argo-cd-ui@1.0.0 + + react-router-dom@4.3.1 + + react-router@4.3.1 + + path-to-regexp@1.8.0 + + + +
    • +
    • + Introduced through: + argo-cd-ui@1.0.0 + + argo-ui@1.0.0 + + react-router-dom@4.3.1 + + react-router@4.3.1 + + path-to-regexp@1.8.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) when including multiple regular expression parameters in a single segment, which will produce the regular expression /^\/([^\/]+?)-([^\/]+?)\/?$/, if two parameters within a single segment are separated by a character other than a / or .. Poor performance will block the event loop and can lead to a DoS.

    +

    Note: + While the 8.0.0 release has completely eliminated the vulnerable functionality, prior versions that have received the patch to mitigate backtracking may still be vulnerable if custom regular expressions are used. So it is strongly recommended for regular expression input to be controlled to avoid malicious performance degradation in those versions. This behavior is enforced as of version 7.1.0 via the strict option, which returns an error if a dangerous regular expression is detected.

    +

    Workaround

    +

    This vulnerability can be avoided by using a custom regular expression for parameters after the first in a segment, which excludes - and /.

    +

    PoC

    +
    /a${'-a'.repeat(8_000)}/a
    +        
    +

    Details

    +

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.

    +

    The Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.

    +

    Let’s take the following regular expression as an example:

    +
    regex = /A(B|C+)+D/
    +        
    +

    This regular expression accomplishes the following:

    +
      +
    • A The string must start with the letter 'A'
    • +
    • (B|C+)+ The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the + matches one or more times). The + at the end of this section states that we can look for one or more matches of this section.
    • +
    • D Finally, we ensure this section of the string ends with a 'D'
    • +
    +

    The expression would match inputs such as ABBD, ABCCCCD, ABCBCCCD and ACCCCCD

    +

    It most cases, it doesn't take very long for a regex engine to find a match:

    +
    $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD")'
    +        0.04s user 0.01s system 95% cpu 0.052 total
    +        
    +        $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX")'
    +        1.79s user 0.02s system 99% cpu 1.812 total
    +        
    +

    The entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.

    +

    Most Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as catastrophic backtracking.

    +

    Let's look at how our expression runs into this problem, using a shorter string: "ACCCX". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:

    +
      +
    1. CCC
    2. +
    3. CC+C
    4. +
    5. C+CC
    6. +
    7. C+C+C.
    8. +
    +

    The engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use RegEx 101 debugger to see the engine has to take a total of 38 steps before it can determine the string doesn't match.

    +

    From there, the number of steps the engine must use to validate a string just continues to grow.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    StringNumber of C'sNumber of steps
    ACCCX338
    ACCCCX471
    ACCCCCX5136
    ACCCCCCCCCCCCCCX1465,553
    +

    By the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.

    +

    Remediation

    +

    Upgrade path-to-regexp to version 0.1.10, 1.9.0, 3.3.0, 6.3.0, 8.0.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/rs/cors +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + github.com/rs/cors@1.9.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) through the processing of malicious preflight requests that include a Access-Control-Request-Headers header with excessive commas. An attacker can induce excessive memory consumption and potentially crash the server by sending specially crafted requests.

    +

    PoC

    +
    
    +        func BenchmarkPreflightAdversarialACRH(b *testing.B) {
    +            resps := makeFakeResponses(b.N)
    +            req, _ := http.NewRequest(http.MethodOptions, dummyEndpoint, nil)
    +            req.Header.Add(headerOrigin, dummyOrigin)
    +            req.Header.Add(headerACRM, http.MethodGet)
    +            req.Header[headerACRH] = adversarialACRH
    +            handler := Default().Handler(testHandler)
    +        
    +            b.ReportAllocs()
    +            b.ResetTimer()
    +            for i := 0; i < b.N; i++ {
    +                handler.ServeHTTP(resps[i], req)
    +            }
    +        }
    +        
    +        var adversarialACRH []string
    +        
    +        func init() { // populates adversarialACRH
    +            n := int(math.Floor(math.Sqrt(http.DefaultMaxHeaderBytes)))
    +            commas := strings.Repeat(",", n)
    +            res := make([]string, n)
    +            for i := range res {
    +                res[i] = commas
    +            }
    +            adversarialACRH = res
    +        }
    +        
    +

    Details

    +

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.

    +

    Unlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.

    +

    One popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.

    +

    When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

    +

    Two common types of DoS vulnerabilities:

    +
      +
    • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

      +
    • +
    • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

      +
    • +
    +

    Remediation

    +

    Upgrade github.com/rs/cors to version 1.11.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/Azure/azure-sdk-for-go/sdk/azidentity +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + github.com/Azure/azure-sdk-for-go/sdk/azidentity@1.1.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    github.com/Azure/azure-sdk-for-go/sdk/azidentity is a module that provides Microsoft Entra ID (formerly Azure Active Directory) token authentication support across the Azure SDK. It includes a set of TokenCredential implementations, which can be used with Azure SDK clients supporting token authentication.

    +

    Affected versions of this package are vulnerable to Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') in the authentication process. An attacker can elevate privileges by exploiting race conditions during the token validation steps. This is only exploitable if the application is configured to use multiple threads or processes for handling authentication requests.

    +

    Notes:

    +
      +
    1. An attacker who successfully exploited the vulnerability could elevate privileges and read any file on the file system with SYSTEM access permissions;

      +
    2. +
    3. An attacker who successfully exploits this vulnerability can only obtain read access to the system files by exploiting this vulnerability. The attacker cannot perform write or delete operations on the files;

      +
    4. +
    5. The vulnerability exists in the following credential types: DefaultAzureCredential and ManagedIdentityCredential;

      +
    6. +
    7. The vulnerability exists in the following credential types:

      +
    8. +
    +

    ManagedIdentityApplication (.NET)

    +

    ManagedIdentityApplication (Java)

    +

    ManagedIdentityApplication (Node.js)

    +

    Remediation

    +

    Upgrade github.com/Azure/azure-sdk-for-go/sdk/azidentity to version 1.6.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Template Injection

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd ui/yarn.lock +
    • +
    • + Package Manager: npm +
    • +
    • + Vulnerable module: + + dompurify +
    • + +
    • Introduced through: + + + argo-cd-ui@1.0.0, redoc@2.0.0-rc.64 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + argo-cd-ui@1.0.0 + + redoc@2.0.0-rc.64 + + dompurify@2.3.6 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    dompurify is a DOM-only XSS sanitizer for HTML, MathML and SVG.

    +

    Affected versions of this package are vulnerable to Template Injection in purify.js, due to inconsistencies in the parsing of XML and HTML tags. Executable code can be injected in HTML inside XML CDATA blocks.

    +

    PoC

    +
    <![CDATA[ ><img src onerror=alert(1)> ]]>
    +        
    +

    Remediation

    +

    Upgrade dompurify to version 2.4.9, 3.0.11 or higher.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.11.3/ghcr.io_dexidp_dex_v2.38.0.html b/docs/snyk/v2.12.3/ghcr.io_dexidp_dex_v2.38.0.html similarity index 73% rename from docs/snyk/v2.11.3/ghcr.io_dexidp_dex_v2.38.0.html rename to docs/snyk/v2.12.3/ghcr.io_dexidp_dex_v2.38.0.html index ef7e16fc72a57..c40058cb449a2 100644 --- a/docs/snyk/v2.11.3/ghcr.io_dexidp_dex_v2.38.0.html +++ b/docs/snyk/v2.12.3/ghcr.io_dexidp_dex_v2.38.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    June 16th 2024, 12:18:36 am (UTC+00:00)

    +

    September 22nd 2024, 12:24:06 am (UTC+00:00)

    Scanned the following paths: @@ -469,8 +469,8 @@

    Snyk test report

    -
    34 known vulnerabilities
    -
    98 vulnerable dependency paths
    +
    18 known vulnerabilities
    +
    85 vulnerable dependency paths
    829 dependencies

    @@ -707,11 +707,11 @@

    Remediation

    Upgrade Alpine:3.19 openssl to version 3.1.4-r3 or higher.

    References

    -

    MPL-2.0 license

    +

    Insertion of Sensitive Information into Log File

    @@ -1126,14 +1126,14 @@

    MPL-2.0 license

    Package Manager: golang
  • - Module: + Vulnerable module: - github.com/hashicorp/vault/sdk/helper/certutil + github.com/hashicorp/go-retryablehttp
  • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0 + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1
  • @@ -1148,52 +1148,7 @@

    Detailed paths

    Introduced through: github.com/hairyhenderson/gomplate/v3@* - github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0 - - - - -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/compressutil@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/jsonutil@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/pluginutil@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/strutil@v0.5.0 - - - -
  • -
  • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/logical@v0.5.0 + github.com/hashicorp/go-retryablehttp@v0.7.1 @@ -1204,17 +1159,25 @@

    Detailed paths


    -

    MPL-2.0 license

    +

    Overview

    +

    Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File due to not sanitizing urls when writing them to the log file. This could lead to an attacker writing sensitive HTTP basic auth credentials to the log file.

    +

    Remediation

    +

    Upgrade github.com/hashicorp/go-retryablehttp to version 0.7.7 or higher.

    +

    References

    +
  • -

    MPL-2.0 license

    +

    Improper Handling of Highly Compressed Data (Data Amplification)

    @@ -1225,20 +1188,20 @@

    MPL-2.0 license

    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate + Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex /usr/local/bin/dex
    • Package Manager: golang
    • - Module: + Vulnerable module: - github.com/hashicorp/vault/api + github.com/go-jose/go-jose/v3
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/api@v1.6.0 + github.com/dexidp/dex@* and github.com/go-jose/go-jose/v3@v3.0.1
    @@ -1251,9 +1214,9 @@

    Detailed paths

    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + github.com/dexidp/dex@* - github.com/hashicorp/vault/api@v1.6.0 + github.com/go-jose/go-jose/v3@v3.0.1 @@ -1264,17 +1227,26 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      Overview

      +

      Affected versions of this package are vulnerable to Improper Handling of Highly Compressed Data (Data Amplification). An attacker could send a JWE containing compressed data that, when decompressed by Decrypt or DecryptMulti, would use large amounts of memory and CPU.

      +

      Remediation

      +

      Upgrade github.com/go-jose/go-jose/v3 to version 3.0.3 or higher.

      +

      References

      +
    -

    MPL-2.0 license

    +

    Out-of-bounds Write

    @@ -1285,20 +1257,17 @@

    MPL-2.0 license

    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang + Package Manager: alpine:3.19
    • - Module: + Vulnerable module: - github.com/hashicorp/serf/coordinate + busybox/busybox
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/serf/coordinate@v0.9.7 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15
    @@ -1311,9 +1280,51 @@

    Detailed paths

    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + 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 - github.com/hashicorp/serf/coordinate@v0.9.7 + busybox/ssl_client@1.36.1-r15 @@ -1324,17 +1335,26 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      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

      +
    -

    MPL-2.0 license

    +

    Use After Free

    @@ -1345,20 +1365,17 @@

    MPL-2.0 license

    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex /usr/local/bin/dex -
    • -
    • - Package Manager: golang + Package Manager: alpine:3.19
    • - Module: + Vulnerable module: - github.com/hashicorp/hcl/v2 + busybox/busybox
    • Introduced through: - github.com/dexidp/dex@* and github.com/hashicorp/hcl/v2@v2.13.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15
    @@ -1371,72 +1388,51 @@

    Detailed paths

    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.38.0 - github.com/hashicorp/hcl/v2@v2.13.0 + busybox/busybox@1.36.1-r15
    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.38.0 - github.com/hashicorp/hcl/v2/ext/customdecode@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* + alpine-baselayout/alpine-baselayout@3.4.3-r2 - github.com/hashicorp/hcl/v2/ext/tryfunc@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* + busybox/busybox-binsh@1.36.1-r15 - github.com/hashicorp/hcl/v2/gohcl@v2.13.0 + busybox/busybox@1.36.1-r15
    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.38.0 - github.com/hashicorp/hcl/v2/hclparse@v2.13.0 + busybox/busybox-binsh@1.36.1-r15
    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.38.0 - github.com/hashicorp/hcl/v2/hclsyntax@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* + alpine-baselayout/alpine-baselayout@3.4.3-r2 - github.com/hashicorp/hcl/v2/hclwrite@v2.13.0 + busybox/busybox-binsh@1.36.1-r15
    • Introduced through: - github.com/dexidp/dex@* + docker-image|ghcr.io/dexidp/dex@v2.38.0 - github.com/hashicorp/hcl/v2/json@v2.13.0 + busybox/ssl_client@1.36.1-r15 @@ -1447,17 +1443,26 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      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

      +
    -

    MPL-2.0 license

    +

    Use After Free

    @@ -1468,20 +1473,17 @@

    MPL-2.0 license

    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang + Package Manager: alpine:3.19
    • - Module: + Vulnerable module: - github.com/hashicorp/hcl + busybox/busybox
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/hcl@v1.0.0 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15
    @@ -1494,18 +1496,51 @@

    Detailed paths

    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + docker-image|ghcr.io/dexidp/dex@v2.38.0 - github.com/hashicorp/hcl@v1.0.0 + busybox/busybox@1.36.1-r15
    • Introduced through: - github.com/hairyhenderson/gomplate/v3@* + 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 - github.com/hashicorp/hcl/hcl/token@v1.0.0 + busybox/ssl_client@1.36.1-r15 @@ -1516,1004 +1551,26 @@

      Detailed paths


      -

      MPL-2.0 license

      +

      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

      +
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/golang-lru/simplelru -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/golang-lru/simplelru@v0.5.4 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/golang-lru/simplelru@v0.5.4 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-version -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-version@v1.5.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-version@v1.5.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-sockaddr -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-sockaddr@v1.0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-sockaddr@v1.0.2 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-sockaddr/template@v1.0.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-secure-stdlib/strutil -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-secure-stdlib/parseutil -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-secure-stdlib/mlock -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-rootcerts -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-rootcerts@v1.0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-rootcerts@v1.0.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-retryablehttp -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-retryablehttp@v0.7.1 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-plugin -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-plugin@v1.4.4 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-plugin@v1.4.4 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-plugin/internal/plugin@v1.4.4 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-immutable-radix -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-immutable-radix@v1.3.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-immutable-radix@v1.3.1 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-cleanhttp -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-cleanhttp@v0.5.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-cleanhttp@v0.5.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/errwrap -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/errwrap@v1.1.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/errwrap@v1.1.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/consul/api -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/consul/api@v1.13.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/consul/api@v1.13.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/gosimple/slug -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/gosimple/slug@v1.12.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/gosimple/slug@v1.12.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex /usr/local/bin/dex -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/go-sql-driver/mysql -
    • - -
    • Introduced through: - - github.com/dexidp/dex@* and github.com/go-sql-driver/mysql@v1.7.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/go-sql-driver/mysql@v1.7.1 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    Improper Handling of Highly Compressed Data (Data Amplification)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.38.0/dexidp/dex /usr/local/bin/dex -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-jose/go-jose/v3 -
    • - -
    • Introduced through: - - github.com/dexidp/dex@* and github.com/go-jose/go-jose/v3@v3.0.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/go-jose/go-jose/v3@v3.0.1 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Improper Handling of Highly Compressed Data (Data Amplification). An attacker could send a JWE containing compressed data that, when decompressed by Decrypt or DecryptMulti, would use large amounts of memory and CPU.

    -

    Remediation

    -

    Upgrade github.com/go-jose/go-jose/v3 to version 3.0.3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Out-of-bounds Write

    +

    Use After Free

    @@ -2605,27 +1662,27 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. See How to fix? for Alpine:3.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.

    +

    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-r16 or higher.

    +

    Upgrade Alpine:3.19 busybox to version 1.36.1-r17 or higher.

    References


    -
    -

    Use After Free

    +
    +

    CVE-2023-6237

    -
    - medium severity +
    + low severity

    @@ -2637,12 +1694,12 @@

    Use After Free

  • Vulnerable module: - busybox/busybox + openssl/libcrypto3
  • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
  • @@ -2657,7 +1714,7 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r15 + openssl/libcrypto3@3.1.4-r2 @@ -2666,11 +1723,20 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r2 + apk-tools/apk-tools@2.14.0-r5 - busybox/busybox-binsh@1.36.1-r15 + openssl/libcrypto3@3.1.4-r2 + + + + +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r15 + busybox/ssl_client@1.36.1-r15 + + openssl/libcrypto3@3.1.4-r2 @@ -2679,7 +1745,11 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r15 + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 + + openssl/libcrypto3@3.1.4-r2 @@ -2688,9 +1758,18 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r2 + openssl/libssl3@3.1.4-r2 + + + +
  • +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r15 + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 @@ -2700,6 +1779,8 @@

    Detailed paths

    docker-image|ghcr.io/dexidp/dex@v2.38.0 busybox/ssl_client@1.36.1-r15 + + openssl/libssl3@3.1.4-r2 @@ -2711,29 +1792,53 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. +

    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.

    -

    A use-after-free vulnerability was discovered in BusyBox v.1.36.1 via a crafted awk pattern in the awk.c copyvar function.

    +

    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 busybox to version 1.36.1-r19 or higher.

    +

    Upgrade Alpine:3.19 openssl to version 3.1.4-r4 or higher.

    References


  • -
    -

    Use After Free

    +
    +

    CVE-2024-2511

    -
    - medium severity +
    + low severity

    @@ -2745,12 +1850,12 @@

    Use After Free

  • Vulnerable module: - busybox/busybox + openssl/libcrypto3
  • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
  • @@ -2765,7 +1870,7 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r15 + openssl/libcrypto3@3.1.4-r2 @@ -2774,11 +1879,20 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r2 + apk-tools/apk-tools@2.14.0-r5 - busybox/busybox-binsh@1.36.1-r15 + openssl/libcrypto3@3.1.4-r2 + + + + +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r15 + busybox/ssl_client@1.36.1-r15 + + openssl/libcrypto3@3.1.4-r2 @@ -2787,7 +1901,11 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r15 + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 + + openssl/libcrypto3@3.1.4-r2 @@ -2796,9 +1914,18 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r2 + openssl/libssl3@3.1.4-r2 + + + +
  • +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r15 + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 @@ -2808,6 +1935,8 @@

    Detailed paths

    docker-image|ghcr.io/dexidp/dex@v2.38.0 busybox/ssl_client@1.36.1-r15 + + openssl/libssl3@3.1.4-r2 @@ -2819,29 +1948,49 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. +

    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.

    -

    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.

    +

    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 busybox to version 1.36.1-r19 or higher.

    +

    Upgrade Alpine:3.19 openssl to version 3.1.4-r6 or higher.

    References


  • -
    -

    Use After Free

    +
    +

    CVE-2024-4603

    -
    - medium severity +
    + low severity

    @@ -2853,12 +2002,12 @@

    Use After Free

  • Vulnerable module: - busybox/busybox + openssl/libcrypto3
  • Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.38.0 and busybox/busybox@1.36.1-r15 + docker-image|ghcr.io/dexidp/dex@v2.38.0 and openssl/libcrypto3@3.1.4-r2
  • @@ -2873,7 +2022,7 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r15 + openssl/libcrypto3@3.1.4-r2 @@ -2882,11 +2031,20 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r2 + apk-tools/apk-tools@2.14.0-r5 - busybox/busybox-binsh@1.36.1-r15 + openssl/libcrypto3@3.1.4-r2 + + + + +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox@1.36.1-r15 + busybox/ssl_client@1.36.1-r15 + + openssl/libcrypto3@3.1.4-r2 @@ -2895,7 +2053,11 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r15 + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 + + openssl/libcrypto3@3.1.4-r2 @@ -2904,9 +2066,18 @@

    Detailed paths

    Introduced through: docker-image|ghcr.io/dexidp/dex@v2.38.0 - alpine-baselayout/alpine-baselayout@3.4.3-r2 + openssl/libssl3@3.1.4-r2 + + + +
  • +
  • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.38.0 - busybox/busybox-binsh@1.36.1-r15 + apk-tools/apk-tools@2.14.0-r5 + + openssl/libssl3@3.1.4-r2 @@ -2916,6 +2087,8 @@

    Detailed paths

    docker-image|ghcr.io/dexidp/dex@v2.38.0 busybox/ssl_client@1.36.1-r15 + + openssl/libssl3@3.1.4-r2 @@ -2927,25 +2100,53 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. +

    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.

    -

    A use-after-free vulnerability was discovered in xasprintf function in xfuncs_printf.c:344 in BusyBox v.1.36.1.

    +

    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 busybox to version 1.36.1-r17 or higher.

    +

    Upgrade Alpine:3.19 openssl to version 3.1.5-r0 or higher.

    References


  • -

    CVE-2023-6237

    +

    CVE-2024-5535

    @@ -3061,47 +2262,86 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.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.

    +

    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.4-r4 or higher.

    +

    Upgrade Alpine:3.19 openssl to version 3.1.6-r0 or higher.

    References


    -

    CVE-2024-2511

    +

    CVE-2024-4741

    @@ -3215,45 +2455,19 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.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.

    +

    This vulnerability has not been analyzed by NVD yet.

    Remediation

    -

    Upgrade Alpine:3.19 openssl to version 3.1.4-r6 or higher.

    -

    References

    - +

    Upgrade Alpine:3.19 openssl to version 3.1.6-r0 or higher.


    -

    CVE-2024-4603

    +

    CVE-2024-6119

    @@ -3369,45 +2583,40 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.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.

    +

    Issue summary: Applications performing certificate name checks (e.g., TLS + clients checking server certificates) may attempt to read an invalid memory + address resulting in abnormal termination of the application process.

    +

    Impact summary: Abnormal termination of an application can a cause a denial of + service.

    +

    Applications performing certificate name checks (e.g., TLS clients checking + server certificates) may attempt to read an invalid memory address when + comparing the expected name with an otherName subject alternative name of an + X.509 certificate. This may result in an exception that terminates the + application program.

    +

    Note that basic certificate chain validation (signatures, dates, ...) is not + affected, the denial of service can occur only when the application also + specifies an expected DNS name, Email address or IP address.

    +

    TLS servers rarely solicit client certificates, and even when they do, they + generally don't perform a name check against a reference identifier (expected + identity), but rather extract the presented identity after checking the + certificate chain. So TLS servers are generally not affected and the severity + of the issue is Moderate.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    Remediation

    -

    Upgrade Alpine:3.19 openssl to version 3.1.5-r0 or higher.

    +

    Upgrade Alpine:3.19 openssl to version 3.1.7-r0 or higher.

    References


    diff --git a/docs/snyk/v2.12.3/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html b/docs/snyk/v2.12.3/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html new file mode 100644 index 0000000000000..bed01faa336f7 --- /dev/null +++ b/docs/snyk/v2.12.3/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html @@ -0,0 +1,1305 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    September 22nd 2024, 12:24:09 am (UTC+00:00)

    +
    +
    + Scanned the following path: +
      +
    • public.ecr.aws/docker/library/haproxy:2.6.17-alpine/docker/library/haproxy (apk)
    • +
    +
    + +
    +
    5 known vulnerabilities
    +
    42 vulnerable dependency paths
    +
    18 dependencies
    +
    +
    +
    +
    +
    + + + + + + + +
    Project docker-image|public.ecr.aws/docker/library/haproxy
    Path public.ecr.aws/docker/library/haproxy:2.6.17-alpine/docker/library/haproxy
    Package Manager apk
    +
    +
    +
    +
    +

    Use After Free

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and busybox/busybox@1.36.1-r28 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/busybox@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + alpine-baselayout/alpine-baselayout@3.6.5-r0 + + busybox/busybox-binsh@1.36.1-r28 + + busybox/busybox@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + alpine-baselayout/alpine-baselayout@3.6.5-r0 + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    A use-after-free vulnerability in BusyBox v.1.36.1 allows attackers to cause a denial of service via a crafted awk pattern in the awk.c evaluate function.

    +

    Remediation

    +

    Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Use After Free

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and busybox/busybox@1.36.1-r28 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/busybox@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + alpine-baselayout/alpine-baselayout@3.6.5-r0 + + busybox/busybox-binsh@1.36.1-r28 + + busybox/busybox@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + alpine-baselayout/alpine-baselayout@3.6.5-r0 + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    A use-after-free vulnerability was discovered in BusyBox v.1.36.1 via a crafted awk pattern in the awk.c copyvar function.

    +

    Remediation

    +

    Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-4741

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and openssl/libcrypto3@3.3.0-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.0-r3 or higher.

    + +
    + + + +
    +
    +

    CVE-2024-5535

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and openssl/libcrypto3@3.3.0-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Calling the OpenSSL API function SSL_select_next_proto with an + empty supported client protocols buffer may cause a crash or memory contents to + be sent to the peer.

    +

    Impact summary: A buffer overread can have a range of potential consequences + such as unexpected application beahviour or a crash. In particular this issue + could result in up to 255 bytes of arbitrary private data from memory being sent + to the peer leading to a loss of confidentiality. However, only applications + that directly call the SSL_select_next_proto function with a 0 length list of + supported client protocols are affected by this issue. This would normally never + be a valid scenario and is typically not under attacker control but may occur by + accident in the case of a configuration or programming error in the calling + application.

    +

    The OpenSSL API function SSL_select_next_proto is typically used by TLS + applications that support ALPN (Application Layer Protocol Negotiation) or NPN + (Next Protocol Negotiation). NPN is older, was never standardised and + is deprecated in favour of ALPN. We believe that ALPN is significantly more + widely deployed than NPN. The SSL_select_next_proto function accepts a list of + protocols from the server and a list of protocols from the client and returns + the first protocol that appears in the server list that also appears in the + client list. In the case of no overlap between the two lists it returns the + first item in the client list. In either case it will signal whether an overlap + between the two lists was found. In the case where SSL_select_next_proto is + called with a zero length client list it fails to notice this condition and + returns the memory immediately following the client list pointer (and reports + that there was no overlap in the lists).

    +

    This function is typically called from a server side application callback for + ALPN or a client side application callback for NPN. In the case of ALPN the list + of protocols supplied by the client is guaranteed by libssl to never be zero in + length. The list of server protocols comes from the application and should never + normally be expected to be of zero length. In this case if the + SSL_select_next_proto function has been called as expected (with the list + supplied by the client passed in the client/client_len parameters), then the + application will not be vulnerable to this issue. If the application has + accidentally been configured with a zero length server list, and has + accidentally passed that zero length server list in the client/client_len + parameters, and has additionally failed to correctly handle a "no overlap" + response (which would normally result in a handshake failure in ALPN) then it + will be vulnerable to this problem.

    +

    In the case of NPN, the protocol permits the client to opportunistically select + a protocol when there is no overlap. OpenSSL returns the first client protocol + in the no overlap case in support of this. The list of client protocols comes + from the application and should never normally be expected to be of zero length. + However if the SSL_select_next_proto function is accidentally called with a + client_len of 0 then an invalid memory pointer will be returned instead. If the + application uses this output as the opportunistic protocol then the loss of + confidentiality will occur.

    +

    This issue has been assessed as Low severity because applications are most + likely to be vulnerable if they are using NPN instead of ALPN - but NPN is not + widely used. It also requires an application configuration or programming error. + Finally, this issue would not typically be under attacker control making active + exploitation unlikely.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Due to the low severity of this issue we are not issuing new releases of + OpenSSL at this time. The fix will be included in the next releases when they + become available.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.1-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-6119

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and openssl/libcrypto3@3.3.0-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Applications performing certificate name checks (e.g., TLS + clients checking server certificates) may attempt to read an invalid memory + address resulting in abnormal termination of the application process.

    +

    Impact summary: Abnormal termination of an application can a cause a denial of + service.

    +

    Applications performing certificate name checks (e.g., TLS clients checking + server certificates) may attempt to read an invalid memory address when + comparing the expected name with an otherName subject alternative name of an + X.509 certificate. This may result in an exception that terminates the + application program.

    +

    Note that basic certificate chain validation (signatures, dates, ...) is not + affected, the denial of service can occur only when the application also + specifies an expected DNS name, Email address or IP address.

    +

    TLS servers rarely solicit client certificates, and even when they do, they + generally don't perform a name check against a reference identifier (expected + identity), but rather extract the presented identity after checking the + certificate chain. So TLS servers are generally not affected and the severity + of the issue is Moderate.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r0 or higher.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.12.3/public.ecr.aws_docker_library_redis_7.0.15-alpine.html b/docs/snyk/v2.12.3/public.ecr.aws_docker_library_redis_7.0.15-alpine.html new file mode 100644 index 0000000000000..dbc79e2e50588 --- /dev/null +++ b/docs/snyk/v2.12.3/public.ecr.aws_docker_library_redis_7.0.15-alpine.html @@ -0,0 +1,484 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    September 22nd 2024, 12:24:12 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)
    • +
    +
    + +
    +
    0 known vulnerabilities
    +
    0 vulnerable dependency paths
    +
    18 dependencies
    +
    +
    +
    +
    + +
    + No known vulnerabilities detected. +
    +
    + + + diff --git a/docs/snyk/v2.12.3/quay.io_argoproj_argocd_v2.12.3.html b/docs/snyk/v2.12.3/quay.io_argoproj_argocd_v2.12.3.html new file mode 100644 index 0000000000000..0bd0879c74d78 --- /dev/null +++ b/docs/snyk/v2.12.3/quay.io_argoproj_argocd_v2.12.3.html @@ -0,0 +1,2633 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    September 22nd 2024, 12:24:27 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • quay.io/argoproj/argocd:v2.12.3/argoproj/argocd/Dockerfile (deb)
    • +
    • quay.io/argoproj/argocd:v2.12.3/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.3//usr/local/bin/kustomize (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.3/helm/v3//usr/local/bin/helm (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.12.3/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    • +
    +
    + +
    +
    17 known vulnerabilities
    +
    81 vulnerable dependency paths
    +
    2292 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    CVE-2024-41996

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3t64 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.12.3 and openssl/libssl3t64@3.0.13-0ubuntu3.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + coreutils@9.4-3ubuntu6 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + libfido2/libfido2-1@1.14.0-1build3 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + ca-certificates@20240203 + + openssl@3.0.13-0ubuntu3.3 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + libssh/libssh-4@0.10.6-2build2 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 + + cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + openssl@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + ca-certificates@20240203 + + openssl@3.0.13-0ubuntu3.3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    Validating the order of the public keys in the Diffie-Hellman Key Agreement Protocol, when an approved safe prime is used, allows remote attackers (from the client side) to trigger unnecessarily expensive server-side DHE modular-exponentiation calculations. The client may cause asymmetric resource consumption. The basic attack scenario is that the client must claim that it can only communicate with DHE, and the server must be configured to allow DHE and validate the order of the public key.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 openssl.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-6119

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3t64 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.12.3 and openssl/libssl3t64@3.0.13-0ubuntu3.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + coreutils@9.4-3ubuntu6 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + libfido2/libfido2-1@1.14.0-1build3 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + ca-certificates@20240203 + + openssl@3.0.13-0ubuntu3.3 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + libssh/libssh-4@0.10.6-2build2 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 + + cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 + + openssl/libssl3t64@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + openssl@3.0.13-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + ca-certificates@20240203 + + openssl@3.0.13-0ubuntu3.3 + + + +
    • +
    + +
    + +
    + +

    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: 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 Ubuntu:24.04 openssl to version 3.0.13-0ubuntu3.4 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Information Exposure

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + libgcrypt20 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.12.3 and libgcrypt20@1.10.3-2build1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + gnupg2/dirmngr@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + gnupg2/gpg@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + gnupg2/gpg-agent@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + apt@2.7.14build2 + + apt/libapt-pkg6.0t64@2.7.14build2 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + apt@2.7.14build2 + + gnupg2/gpgv@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + gnupg2/gpg@2.4.4-2ubuntu17 + + gnupg2/gpgconf@2.4.4-2ubuntu17 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + apt@2.7.14build2 + + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + systemd/libsystemd0@255.4-1ubuntu8.4 + + libgcrypt20@1.10.3-2build1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream libgcrypt20 package and not the libgcrypt20 package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 libgcrypt20.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-26462

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + krb5/libk5crypto3 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + libssh/libssh-4@0.10.6-2build2 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + krb5/krb5-locales@1.20.1-6ubuntu2.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    Kerberos 5 (aka krb5) 1.21.2 contains a memory leak vulnerability in /krb5/src/kdc/ndr.c.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 krb5.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argo-cd/v2 /usr/local/bin/argocd +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/rs/cors +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/rs/cors@v1.9.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/rs/cors@v1.9.0 + + + +
    • +
    + +
    + +
    + +

    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

    + + +
    + + + +
    +
    +

    Integer Overflow or Wraparound

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + expat/libexpat1 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + expat/libexpat1@2.6.1-2build1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream expat package and not the expat package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    An issue was discovered in libexpat before 2.6.3. dtdCopy in xmlparse.c can have an integer overflow for nDefaultAtts on 32-bit platforms (where UINT_MAX equals SIZE_MAX).

    +

    Remediation

    +

    Upgrade Ubuntu:24.04 expat to version 2.6.1-2ubuntu0.1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    XML External Entity (XXE) Injection

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + expat/libexpat1 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + expat/libexpat1@2.6.1-2build1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream expat package and not the expat package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    An issue was discovered in libexpat before 2.6.3. xmlparse.c does not reject a negative length for XML_ParseBuffer.

    +

    Remediation

    +

    Upgrade Ubuntu:24.04 expat to version 2.6.1-2ubuntu0.1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Integer Overflow or Wraparound

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + expat/libexpat1 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + expat/libexpat1@2.6.1-2build1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream expat package and not the expat package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    An issue was discovered in libexpat before 2.6.3. nextScaffoldPart in xmlparse.c can have an integer overflow for m_groupSize on 32-bit platforms (where UINT_MAX equals SIZE_MAX).

    +

    Remediation

    +

    Upgrade Ubuntu:24.04 expat to version 2.6.1-2ubuntu0.1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-8096

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + curl/libcurl3t64-gnutls +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    When curl is told to use the Certificate Status Request TLS extension, often referred to as OCSP stapling, to verify that the server certificate is valid, it might fail to detect some OCSP problems and instead wrongly consider the response as fine. If the returned status reports another error than 'revoked' (like for example 'unauthorized') it is not treated as a bad certficate.

    +

    Remediation

    +

    Upgrade Ubuntu:24.04 curl to version 8.5.0-2ubuntu10.4 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Release of Invalid Pointer or Reference

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + patch +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.12.3 and patch@2.7.6-7build3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + patch@2.7.6-7build3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    An Invalid Pointer vulnerability exists in GNU patch 2.7 via the another_hunk function, which causes a Denial of Service.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 patch.

    +

    References

    + + +
    + + + +
    +
    +

    Double Free

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + patch +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.12.3 and patch@2.7.6-7build3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + patch@2.7.6-7build3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    A double free exists in the another_hunk function in pch.c in GNU patch through 2.7.6.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 patch.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-26458

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + krb5/libk5crypto3 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + libssh/libssh-4@0.10.6-2build2 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + krb5/krb5-locales@1.20.1-6ubuntu2.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    Kerberos 5 (aka krb5) 1.21.2 contains a memory leak in /krb5/src/lib/rpc/pmap_rmt.c.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 krb5.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-26461

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + krb5/libk5crypto3 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + openssh/openssh-client@1:9.6p1-3ubuntu13.5 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.3 + + libssh/libssh-4@0.10.6-2build2 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + krb5/krb5-locales@1.20.1-6ubuntu2.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    Kerberos 5 (aka krb5) 1.21.2 contains a memory leak vulnerability in /krb5/src/lib/gssapi/krb5/k5sealv3.c.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 krb5.

    +

    References

    + + +
    + + + +
    +
    +

    Out-of-bounds Write

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + gnupg2/gpgv +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.12.3 and gnupg2/gpgv@2.4.4-2ubuntu17 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + gnupg2/gpgv@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + apt@2.7.14build2 + + gnupg2/gpgv@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + gnupg2/dirmngr@2.4.4-2ubuntu17 + + gnupg2/gpgconf@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + gnupg2/gpg-agent@2.4.4-2ubuntu17 + + gnupg2/gpgconf@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + gnupg2/gpg@2.4.4-2ubuntu17 + + gnupg2/gpgconf@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + gnupg2/dirmngr@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + gnupg2/gpg@2.4.4-2ubuntu17 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + gnupg2/gpg-agent@2.4.4-2ubuntu17 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream gnupg2 package and not the gnupg2 package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    GnuPG can be made to spin on a relatively small input by (for example) crafting a public key with thousands of signatures attached, compressed down to just a few KB.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 gnupg2.

    +

    References

    + + +
    + + + +
    +
    +

    Allocation of Resources Without Limits or Throttling

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + glibc/libc-bin +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.12.3 and glibc/libc-bin@2.39-0ubuntu8.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + glibc/libc-bin@2.39-0ubuntu8.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + glibc/libc6@2.39-0ubuntu8.3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    sha256crypt and sha512crypt through 0.6 allow attackers to cause a denial of service (CPU consumption) because the algorithm's runtime is proportional to the square of the length of the password.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 glibc.

    +

    References

    + + +
    + + + +
    +
    +

    Improper Input Validation

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + git/git-man +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.12.3, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + 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.12.3 + + git@1:2.43.0-1ubuntu7.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + git-lfs@3.4.1-1ubuntu0.1 + + git@1:2.43.0-1ubuntu7.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream git package and not the git package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    GIT version 2.15.1 and earlier contains a Input Validation Error vulnerability in Client that can result in problems including messing up terminal configuration to RCE. This attack appear to be exploitable via The user must interact with a malicious git server, (or have their traffic modified in a MITM attack).

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 git.

    +

    References

    + + +
    + + + +
    +
    +

    Improper Input Validation

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.12.3/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + coreutils +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.12.3 and coreutils@9.4-3ubuntu6 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.12.3 + + coreutils@9.4-3ubuntu6 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream coreutils package and not the coreutils package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    chroot in GNU coreutils, when used with --userspec, allows local users to escape to the parent session via a crafted TIOCSTI ioctl call, which pushes characters to the terminal's input buffer.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 coreutils.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.12.3/redis_7.0.15-alpine.html b/docs/snyk/v2.12.3/redis_7.0.15-alpine.html new file mode 100644 index 0000000000000..e3cc28e76700f --- /dev/null +++ b/docs/snyk/v2.12.3/redis_7.0.15-alpine.html @@ -0,0 +1,484 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    September 22nd 2024, 12:24:31 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)
    • +
    +
    + +
    +
    0 known vulnerabilities
    +
    0 vulnerable dependency paths
    +
    18 dependencies
    +
    +
    +
    +
    + +
    + No known vulnerabilities detected. +
    +
    + + + diff --git a/docs/snyk/v2.13.0-rc2/argocd-iac-install.html b/docs/snyk/v2.13.0-rc2/argocd-iac-install.html new file mode 100644 index 0000000000000..1fb9ff7afdb66 --- /dev/null +++ b/docs/snyk/v2.13.0-rc2/argocd-iac-install.html @@ -0,0 +1,2891 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    September 22nd 2024, 12:23:23 am (UTC+00:00)

    +
    +
    + Scanned the following path: +
      +
    • /argo-cd/manifests/install.yaml (Kubernetes)
    • +
    +
    + +
    +
    44 total issues
    +
    +
    +
    +
    + +
    + + + + + + +
    Project manifests/install.yaml
    Path /argo-cd/manifests/install.yaml
    Project Type Kubernetes
    +
    +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 17] + + rules[5] + + resources + +
    • + +
    • + Line number: 22389 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 10] + + rules[0] + + resources + +
    • + +
    • + Line number: 22070 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 11] + + rules[4] + + resources + +
    • + +
    • + Line number: 22157 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 12] + + rules[0] + + resources + +
    • + +
    • + Line number: 22185 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 13] + + rules[1] + + resources + +
    • + +
    • + Line number: 22215 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 13] + + rules[3] + + resources + +
    • + +
    • + Line number: 22233 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 14] + + rules[0] + + resources + +
    • + +
    • + Line number: 22251 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Role or ClusterRole with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 15] + + rules[0] + + resources + +
    • + +
    • + Line number: 22273 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions. For a ClusterRole this would be considered high severity.

    + +

    Remediation

    +

    Consider removing these permissions

    + + +
    +
    + + + +
    +
    +

    Container could be running with outdated image

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-42 +
    • + +
    • Introduced through: + [DocId: 48] + + spec + + template + + spec + + initContainers[secret-init] + + imagePullPolicy + +
    • + +
    • + Line number: 23345 +
    • +
    + +
    + +

    Impact

    +

    The container may run with outdated or unauthorized image

    + +

    Remediation

    +

    Set `imagePullPolicy` attribute to `Always`

    + + +
    +
    + + + +
    +
    +

    Container could be running with outdated image

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-42 +
    • + +
    • Introduced through: + [DocId: 49] + + spec + + template + + spec + + initContainers[copyutil] + + imagePullPolicy + +
    • + +
    • + Line number: 23644 +
    • +
    + +
    + +

    Impact

    +

    The container may run with outdated or unauthorized image

    + +

    Remediation

    +

    Set `imagePullPolicy` attribute to `Always`

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 22882 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23151 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + containers[dex] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23105 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 47] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23211 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + containers[redis] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23316 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + initContainers[secret-init] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23340 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23644 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23397 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 50] + + input + + spec + + template + + spec + + containers[argocd-server] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 23729 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 51] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 24119 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container is running with multiple open ports

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-36 +
    • + +
    • Introduced through: + [DocId: 46] + + spec + + template + + spec + + containers[dex] + + ports + +
    • + +
    • + Line number: 23131 +
    • +
    + +
    + +

    Impact

    +

    Increases the attack surface of the application and the container.

    + +

    Remediation

    +

    Reduce `ports` count to 2

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 45] + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + livenessProbe + +
    • + +
    • + Line number: 22882 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 46] + + spec + + template + + spec + + containers[dex] + + livenessProbe + +
    • + +
    • + Line number: 23105 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 48] + + spec + + template + + spec + + containers[redis] + + livenessProbe + +
    • + +
    • + Line number: 23316 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 22882 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + containers[dex] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23105 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23151 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 47] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23211 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + containers[redis] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23316 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + initContainers[secret-init] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23340 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23644 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23397 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 50] + + input + + spec + + template + + spec + + containers[argocd-server] + + resources + + limits + + memory + +
    • + +
    • + Line number: 23729 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 51] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 24119 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23029 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + initContainers[copyutil] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23159 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + containers[dex] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23134 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 47] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23250 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + containers[redis] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23333 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 48] + + input + + spec + + template + + spec + + initContainers[secret-init] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23347 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + initContainers[copyutil] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23651 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 49] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 23617 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 50] + + input + + spec + + template + + spec + + containers[argocd-server] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 24020 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 51] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 24320 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +
    + +
    + + + diff --git a/docs/snyk/v2.9.17/argocd-iac-install.html b/docs/snyk/v2.13.0-rc2/argocd-iac-namespace-install.html similarity index 96% rename from docs/snyk/v2.9.17/argocd-iac-install.html rename to docs/snyk/v2.13.0-rc2/argocd-iac-namespace-install.html index 7c7157d625886..ecec28af1a8cd 100644 --- a/docs/snyk/v2.9.17/argocd-iac-install.html +++ b/docs/snyk/v2.13.0-rc2/argocd-iac-namespace-install.html @@ -456,12 +456,12 @@

    Snyk test report

    -

    June 16th 2024, 12:24:44 am (UTC+00:00)

    +

    September 22nd 2024, 12:23:32 am (UTC+00:00)

    Scanned the following path:
      -
    • /argo-cd/manifests/install.yaml (Kubernetes)
    • +
    • /argo-cd/manifests/namespace-install.yaml (Kubernetes)
    @@ -475,8 +475,8 @@

    Snyk test report

    - - + +
    Project manifests/install.yaml
    Path /argo-cd/manifests/install.yaml
    Project manifests/namespace-install.yaml
    Path /argo-cd/manifests/namespace-install.yaml
    Project Type Kubernetes
    @@ -498,7 +498,7 @@

    Role or ClusterRole with dangerous permissions

  • Introduced through: - [DocId: 10] + [DocId: 7] rules[0] @@ -507,7 +507,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20310 + Line number: 77
  • @@ -544,7 +544,7 @@

    Role or ClusterRole with dangerous permissions

  • Introduced through: - [DocId: 11] + [DocId: 8] rules[4] @@ -553,7 +553,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20395 + Line number: 164
  • @@ -590,7 +590,7 @@

    Role or ClusterRole with dangerous permissions

  • Introduced through: - [DocId: 12] + [DocId: 9] rules[0] @@ -599,7 +599,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20423 + Line number: 192
  • @@ -636,7 +636,7 @@

    Role or ClusterRole with dangerous permissions

  • Introduced through: - [DocId: 13] + [DocId: 10] rules[1] @@ -645,7 +645,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20453 + Line number: 222
  • @@ -682,7 +682,7 @@

    Role or ClusterRole with dangerous permissions

  • Introduced through: - [DocId: 13] + [DocId: 10] rules[3] @@ -691,7 +691,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20471 + Line number: 240
  • @@ -728,7 +728,7 @@

    Role or ClusterRole with dangerous permissions

  • Introduced through: - [DocId: 14] + [DocId: 11] rules[0] @@ -737,7 +737,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20489 + Line number: 258
  • @@ -774,7 +774,7 @@

    Role or ClusterRole with dangerous permissions

  • Introduced through: - [DocId: 15] + [DocId: 12] rules[0] @@ -783,7 +783,7 @@

    Role or ClusterRole with dangerous permissions

  • - Line number: 20511 + Line number: 280
  • @@ -820,7 +820,7 @@

    Container could be running with outdated image

  • Introduced through: - [DocId: 46] + [DocId: 39] spec @@ -835,7 +835,7 @@

    Container could be running with outdated image

  • - Line number: 21439 + Line number: 1138
  • @@ -872,7 +872,7 @@

    Container could be running with outdated image

  • Introduced through: - [DocId: 47] + [DocId: 40] spec @@ -887,7 +887,7 @@

    Container could be running with outdated image

  • - Line number: 21696 + Line number: 1437
  • @@ -924,7 +924,7 @@

    Container has no CPU limit

  • Introduced through: - [DocId: 43] + [DocId: 36] input @@ -945,7 +945,7 @@

    Container has no CPU limit

  • - Line number: 21012 + Line number: 675
  • @@ -982,7 +982,7 @@

    Container has no CPU limit

  • Introduced through: - [DocId: 44] + [DocId: 37] input @@ -1003,7 +1003,7 @@

    Container has no CPU limit

  • - Line number: 21257 + Line number: 944
  • @@ -1040,7 +1040,7 @@

    Container has no CPU limit

  • Introduced through: - [DocId: 44] + [DocId: 37] input @@ -1061,7 +1061,7 @@

    Container has no CPU limit

  • - Line number: 21223 + Line number: 898
  • @@ -1098,7 +1098,7 @@

    Container has no CPU limit

  • Introduced through: - [DocId: 45] + [DocId: 38] input @@ -1119,7 +1119,7 @@

    Container has no CPU limit

  • - Line number: 21317 + Line number: 1004
  • @@ -1156,7 +1156,7 @@

    Container has no CPU limit

  • Introduced through: - [DocId: 46] + [DocId: 39] input @@ -1177,7 +1177,7 @@

    Container has no CPU limit

  • - Line number: 21410 + Line number: 1109
  • @@ -1214,7 +1214,7 @@

    Container has no CPU limit

  • Introduced through: - [DocId: 46] + [DocId: 39] input @@ -1235,7 +1235,7 @@

    Container has no CPU limit

  • - Line number: 21434 + Line number: 1133
  • @@ -1272,7 +1272,7 @@

    Container has no CPU limit

  • Introduced through: - [DocId: 47] + [DocId: 40] input @@ -1293,7 +1293,7 @@

    Container has no CPU limit

  • - Line number: 21696 + Line number: 1437
  • @@ -1330,7 +1330,7 @@

    Container has no CPU limit

  • Introduced through: - [DocId: 47] + [DocId: 40] input @@ -1351,7 +1351,7 @@

    Container has no CPU limit

  • - Line number: 21491 + Line number: 1190
  • @@ -1388,7 +1388,7 @@

    Container has no CPU limit

  • Introduced through: - [DocId: 48] + [DocId: 41] input @@ -1409,7 +1409,7 @@

    Container has no CPU limit

  • - Line number: 21781 + Line number: 1522
  • @@ -1446,7 +1446,7 @@

    Container has no CPU limit

  • Introduced through: - [DocId: 49] + [DocId: 42] input @@ -1467,7 +1467,7 @@

    Container has no CPU limit

  • - Line number: 22108 + Line number: 1912
  • @@ -1504,7 +1504,7 @@

    Container is running with multiple open ports

  • Introduced through: - [DocId: 44] + [DocId: 37] spec @@ -1519,7 +1519,7 @@

    Container is running with multiple open ports

  • - Line number: 21237 + Line number: 924
  • @@ -1556,7 +1556,7 @@

    Container is running without liveness probe

  • Introduced through: - [DocId: 43] + [DocId: 36] spec @@ -1571,7 +1571,7 @@

    Container is running without liveness probe

  • - Line number: 21012 + Line number: 675
  • @@ -1608,7 +1608,7 @@

    Container is running without liveness probe

  • Introduced through: - [DocId: 44] + [DocId: 37] spec @@ -1623,7 +1623,7 @@

    Container is running without liveness probe

  • - Line number: 21223 + Line number: 898
  • @@ -1660,7 +1660,7 @@

    Container is running without liveness probe

  • Introduced through: - [DocId: 46] + [DocId: 39] spec @@ -1675,7 +1675,7 @@

    Container is running without liveness probe

  • - Line number: 21410 + Line number: 1109
  • @@ -1712,7 +1712,7 @@

    Container is running without memory limit

  • Introduced through: - [DocId: 43] + [DocId: 36] input @@ -1733,7 +1733,7 @@

    Container is running without memory limit

  • - Line number: 21012 + Line number: 675
  • @@ -1770,7 +1770,7 @@

    Container is running without memory limit

  • Introduced through: - [DocId: 44] + [DocId: 37] input @@ -1791,7 +1791,7 @@

    Container is running without memory limit

  • - Line number: 21223 + Line number: 898
  • @@ -1828,7 +1828,7 @@

    Container is running without memory limit

  • Introduced through: - [DocId: 44] + [DocId: 37] input @@ -1849,7 +1849,7 @@

    Container is running without memory limit

  • - Line number: 21257 + Line number: 944
  • @@ -1886,7 +1886,7 @@

    Container is running without memory limit

  • Introduced through: - [DocId: 45] + [DocId: 38] input @@ -1907,7 +1907,7 @@

    Container is running without memory limit

  • - Line number: 21317 + Line number: 1004
  • @@ -1944,7 +1944,7 @@

    Container is running without memory limit

  • Introduced through: - [DocId: 46] + [DocId: 39] input @@ -1965,7 +1965,7 @@

    Container is running without memory limit

  • - Line number: 21410 + Line number: 1109
  • @@ -2002,7 +2002,7 @@

    Container is running without memory limit

  • Introduced through: - [DocId: 46] + [DocId: 39] input @@ -2023,7 +2023,7 @@

    Container is running without memory limit

  • - Line number: 21434 + Line number: 1133
  • @@ -2060,7 +2060,7 @@

    Container is running without memory limit

  • Introduced through: - [DocId: 47] + [DocId: 40] input @@ -2081,7 +2081,7 @@

    Container is running without memory limit

  • - Line number: 21696 + Line number: 1437
  • @@ -2118,7 +2118,7 @@

    Container is running without memory limit

  • Introduced through: - [DocId: 47] + [DocId: 40] input @@ -2139,7 +2139,7 @@

    Container is running without memory limit

  • - Line number: 21491 + Line number: 1190
  • @@ -2176,7 +2176,7 @@

    Container is running without memory limit

  • Introduced through: - [DocId: 48] + [DocId: 41] input @@ -2197,7 +2197,7 @@

    Container is running without memory limit

  • - Line number: 21781 + Line number: 1522
  • @@ -2234,7 +2234,7 @@

    Container is running without memory limit

  • Introduced through: - [DocId: 49] + [DocId: 42] input @@ -2255,7 +2255,7 @@

    Container is running without memory limit

  • - Line number: 22108 + Line number: 1912
  • @@ -2292,7 +2292,7 @@

    Container's or Pod's UID could clash with hos
  • Introduced through: - [DocId: 43] + [DocId: 36] input @@ -2311,7 +2311,7 @@

    Container's or Pod's UID could clash with hos

  • - Line number: 21147 + Line number: 822
  • @@ -2348,7 +2348,7 @@

    Container's or Pod's UID could clash with hos
  • Introduced through: - [DocId: 44] + [DocId: 37] input @@ -2367,7 +2367,7 @@

    Container's or Pod's UID could clash with hos

  • - Line number: 21265 + Line number: 952
  • @@ -2404,7 +2404,7 @@

    Container's or Pod's UID could clash with hos
  • Introduced through: - [DocId: 44] + [DocId: 37] input @@ -2423,7 +2423,7 @@

    Container's or Pod's UID could clash with hos

  • - Line number: 21240 + Line number: 927
  • @@ -2460,7 +2460,7 @@

    Container's or Pod's UID could clash with hos
  • Introduced through: - [DocId: 45] + [DocId: 38] input @@ -2479,7 +2479,7 @@

    Container's or Pod's UID could clash with hos

  • - Line number: 21344 + Line number: 1043
  • @@ -2516,7 +2516,7 @@

    Container's or Pod's UID could clash with hos
  • Introduced through: - [DocId: 46] + [DocId: 39] input @@ -2535,7 +2535,7 @@

    Container's or Pod's UID could clash with hos

  • - Line number: 21427 + Line number: 1126
  • @@ -2572,7 +2572,7 @@

    Container's or Pod's UID could clash with hos
  • Introduced through: - [DocId: 46] + [DocId: 39] input @@ -2591,7 +2591,7 @@

    Container's or Pod's UID could clash with hos

  • - Line number: 21441 + Line number: 1140
  • @@ -2628,7 +2628,7 @@

    Container's or Pod's UID could clash with hos
  • Introduced through: - [DocId: 47] + [DocId: 40] input @@ -2647,7 +2647,7 @@

    Container's or Pod's UID could clash with hos

  • - Line number: 21703 + Line number: 1444
  • @@ -2684,7 +2684,7 @@

    Container's or Pod's UID could clash with hos
  • Introduced through: - [DocId: 47] + [DocId: 40] input @@ -2703,7 +2703,7 @@

    Container's or Pod's UID could clash with hos

  • - Line number: 21669 + Line number: 1410
  • @@ -2740,7 +2740,7 @@

    Container's or Pod's UID could clash with hos
  • Introduced through: - [DocId: 48] + [DocId: 41] input @@ -2759,7 +2759,7 @@

    Container's or Pod's UID could clash with hos

  • - Line number: 22018 + Line number: 1813
  • @@ -2796,7 +2796,7 @@

    Container's or Pod's UID could clash with hos
  • Introduced through: - [DocId: 49] + [DocId: 42] input @@ -2815,7 +2815,7 @@

    Container's or Pod's UID could clash with hos

  • - Line number: 22267 + Line number: 2113
  • diff --git a/docs/snyk/v2.13.0-rc2/argocd-test.html b/docs/snyk/v2.13.0-rc2/argocd-test.html new file mode 100644 index 0000000000000..339b8e739fba1 --- /dev/null +++ b/docs/snyk/v2.13.0-rc2/argocd-test.html @@ -0,0 +1,745 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    September 22nd 2024, 12:21:26 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • /argo-cd/argoproj/argo-cd/v2/go.mod (gomodules)
    • +
    • /argo-cd/ui/yarn.lock (yarn)
    • +
    +
    + +
    +
    2 known vulnerabilities
    +
    4 vulnerable dependency paths
    +
    2132 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    Regular Expression Denial of Service (ReDoS)

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd ui/yarn.lock +
    • +
    • + Package Manager: npm +
    • +
    • + Vulnerable module: + + path-to-regexp +
    • + +
    • Introduced through: + + + argo-cd-ui@1.0.0, react-router@4.3.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + argo-cd-ui@1.0.0 + + react-router@4.3.1 + + path-to-regexp@1.8.0 + + + +
    • +
    • + Introduced through: + argo-cd-ui@1.0.0 + + react-router-dom@4.3.1 + + react-router@4.3.1 + + path-to-regexp@1.8.0 + + + +
    • +
    • + Introduced through: + argo-cd-ui@1.0.0 + + argo-ui@1.0.0 + + react-router-dom@4.3.1 + + react-router@4.3.1 + + path-to-regexp@1.8.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) when including multiple regular expression parameters in a single segment, which will produce the regular expression /^\/([^\/]+?)-([^\/]+?)\/?$/, if two parameters within a single segment are separated by a character other than a / or .. Poor performance will block the event loop and can lead to a DoS.

    +

    Note: + While the 8.0.0 release has completely eliminated the vulnerable functionality, prior versions that have received the patch to mitigate backtracking may still be vulnerable if custom regular expressions are used. So it is strongly recommended for regular expression input to be controlled to avoid malicious performance degradation in those versions. This behavior is enforced as of version 7.1.0 via the strict option, which returns an error if a dangerous regular expression is detected.

    +

    Workaround

    +

    This vulnerability can be avoided by using a custom regular expression for parameters after the first in a segment, which excludes - and /.

    +

    PoC

    +
    /a${'-a'.repeat(8_000)}/a
    +        
    +

    Details

    +

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.

    +

    The Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.

    +

    Let’s take the following regular expression as an example:

    +
    regex = /A(B|C+)+D/
    +        
    +

    This regular expression accomplishes the following:

    +
      +
    • A The string must start with the letter 'A'
    • +
    • (B|C+)+ The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the + matches one or more times). The + at the end of this section states that we can look for one or more matches of this section.
    • +
    • D Finally, we ensure this section of the string ends with a 'D'
    • +
    +

    The expression would match inputs such as ABBD, ABCCCCD, ABCBCCCD and ACCCCCD

    +

    It most cases, it doesn't take very long for a regex engine to find a match:

    +
    $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD")'
    +        0.04s user 0.01s system 95% cpu 0.052 total
    +        
    +        $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX")'
    +        1.79s user 0.02s system 99% cpu 1.812 total
    +        
    +

    The entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.

    +

    Most Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as catastrophic backtracking.

    +

    Let's look at how our expression runs into this problem, using a shorter string: "ACCCX". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:

    +
      +
    1. CCC
    2. +
    3. CC+C
    4. +
    5. C+CC
    6. +
    7. C+C+C.
    8. +
    +

    The engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use RegEx 101 debugger to see the engine has to take a total of 38 steps before it can determine the string doesn't match.

    +

    From there, the number of steps the engine must use to validate a string just continues to grow.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    StringNumber of C'sNumber of steps
    ACCCX338
    ACCCCX471
    ACCCCCX5136
    ACCCCCCCCCCCCCCX1465,553
    +

    By the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.

    +

    Remediation

    +

    Upgrade path-to-regexp to version 0.1.10, 1.9.0, 3.3.0, 6.3.0, 8.0.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod +
    • +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/Azure/azure-sdk-for-go/sdk/azidentity +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + github.com/Azure/azure-sdk-for-go/sdk/azidentity@1.1.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    github.com/Azure/azure-sdk-for-go/sdk/azidentity is a module that provides Microsoft Entra ID (formerly Azure Active Directory) token authentication support across the Azure SDK. It includes a set of TokenCredential implementations, which can be used with Azure SDK clients supporting token authentication.

    +

    Affected versions of this package are vulnerable to Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') in the authentication process. An attacker can elevate privileges by exploiting race conditions during the token validation steps. This is only exploitable if the application is configured to use multiple threads or processes for handling authentication requests.

    +

    Notes:

    +
      +
    1. An attacker who successfully exploited the vulnerability could elevate privileges and read any file on the file system with SYSTEM access permissions;

      +
    2. +
    3. An attacker who successfully exploits this vulnerability can only obtain read access to the system files by exploiting this vulnerability. The attacker cannot perform write or delete operations on the files;

      +
    4. +
    5. The vulnerability exists in the following credential types: DefaultAzureCredential and ManagedIdentityCredential;

      +
    6. +
    7. The vulnerability exists in the following credential types:

      +
    8. +
    +

    ManagedIdentityApplication (.NET)

    +

    ManagedIdentityApplication (Java)

    +

    ManagedIdentityApplication (Node.js)

    +

    Remediation

    +

    Upgrade github.com/Azure/azure-sdk-for-go/sdk/azidentity to version 1.6.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.9.17/redis_7.0.15-alpine.html b/docs/snyk/v2.13.0-rc2/ghcr.io_dexidp_dex_v2.41.1.html similarity index 61% rename from docs/snyk/v2.9.17/redis_7.0.15-alpine.html rename to docs/snyk/v2.13.0-rc2/ghcr.io_dexidp_dex_v2.41.1.html index 09de90da5f9fc..6a121eec05819 100644 --- a/docs/snyk/v2.9.17/redis_7.0.15-alpine.html +++ b/docs/snyk/v2.13.0-rc2/ghcr.io_dexidp_dex_v2.41.1.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,20 +456,22 @@

    Snyk test report

    -

    June 16th 2024, 12:23:28 am (UTC+00:00)

    +

    September 22nd 2024, 12:21:32 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)
    • +
    • 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)
    -
    3 known vulnerabilities
    -
    19 vulnerable dependency paths
    -
    18 dependencies
    +
    2 known vulnerabilities
    +
    8 vulnerable dependency paths
    +
    969 dependencies

    @@ -478,7 +480,7 @@

    Snyk test report

    -

    Use After Free

    +

    Insertion of Sensitive Information into Log File

    @@ -489,125 +491,20 @@

    Use After Free

    • - Package Manager: alpine:3.20 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|redis@7.0.15-alpine and busybox/busybox@1.36.1-r28 - + Manifest file: ghcr.io/dexidp/dex:v2.41.1/hairyhenderson/gomplate/v4 /usr/local/bin/gomplate
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - alpine-baselayout/alpine-baselayout@3.6.5-r0 - - busybox/busybox-binsh@1.36.1-r28 - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - alpine-baselayout/alpine-baselayout@3.6.5-r0 - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/ssl_client@1.36.1-r28 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.20 relevant fixed versions and status.

    -

    A use-after-free vulnerability in BusyBox v.1.36.1 allows attackers to cause a denial of service via a crafted awk pattern in the awk.c evaluate function.

    -

    Remediation

    -

    Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Use After Free

    -
    - -
    - medium severity -
    - -
    - -
    • - Package Manager: alpine:3.20 + Package Manager: golang
    • Vulnerable module: - busybox/busybox + google.golang.org/grpc/metadata
    • Introduced through: - docker-image|redis@7.0.15-alpine and busybox/busybox@1.36.1-r28 + github.com/hairyhenderson/gomplate/v4@* and google.golang.org/grpc/metadata@v1.64.0
    @@ -620,51 +517,9 @@

    Detailed paths

    • Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - alpine-baselayout/alpine-baselayout@3.6.5-r0 - - busybox/busybox-binsh@1.36.1-r28 - - busybox/busybox@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine - - alpine-baselayout/alpine-baselayout@3.6.5-r0 - - busybox/busybox-binsh@1.36.1-r28 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine + github.com/hairyhenderson/gomplate/v4@* - busybox/ssl_client@1.36.1-r28 + google.golang.org/grpc/metadata@v1.64.0 @@ -675,26 +530,25 @@

      Detailed paths


      -

      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.20 relevant fixed versions and status.

      -

      A use-after-free vulnerability was discovered in BusyBox v.1.36.1 via a crafted awk pattern in the awk.c copyvar function.

      +

      Overview

      +

      google.golang.org/grpc/metadata is a package that defines the structure of the metadata supported by the gRPC library

      +

      Affected versions of this package are vulnerable to Insertion of Sensitive Information into Log File in the form of gRPC metadata. If the metadata contains sensitive information an attacker can expose it.

      Remediation

      -

      Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

      +

      Upgrade google.golang.org/grpc/metadata to version 1.64.1 or higher.

      References


    -

    CVE-2024-4741

    +

    CVE-2024-6119

    @@ -715,7 +569,7 @@

    CVE-2024-4741

  • Introduced through: - docker-image|redis@7.0.15-alpine and openssl/libcrypto3@3.3.0-r2 + docker-image|ghcr.io/dexidp/dex@v2.41.1 and openssl/libcrypto3@3.3.1-r3
  • @@ -728,97 +582,75 @@

    Detailed paths

    • Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 - openssl/libcrypto3@3.3.0-r2 + openssl/libcrypto3@3.3.1-r3
    • Introduced through: - docker-image|redis@7.0.15-alpine - - .redis-rundeps@20240524.005525 - - openssl/libcrypto3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 apk-tools/apk-tools@2.14.4-r0 - openssl/libcrypto3@3.3.0-r2 + openssl/libcrypto3@3.3.1-r3
    • Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 - busybox/ssl_client@1.36.1-r28 + busybox/ssl_client@1.36.1-r29 - openssl/libcrypto3@3.3.0-r2 + openssl/libcrypto3@3.3.1-r3
    • Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 - .redis-rundeps@20240524.005525 + apk-tools/apk-tools@2.14.4-r0 - openssl/libssl3@3.3.0-r2 + openssl/libssl3@3.3.1-r3 - openssl/libcrypto3@3.3.0-r2 + openssl/libcrypto3@3.3.1-r3
    • Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 - openssl/libssl3@3.3.0-r2 + openssl/libssl3@3.3.1-r3
    • Introduced through: - docker-image|redis@7.0.15-alpine - - .redis-rundeps@20240524.005525 - - openssl/libssl3@3.3.0-r2 - - - -
    • -
    • - Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 apk-tools/apk-tools@2.14.4-r0 - openssl/libssl3@3.3.0-r2 + openssl/libssl3@3.3.1-r3
    • Introduced through: - docker-image|redis@7.0.15-alpine + docker-image|ghcr.io/dexidp/dex@v2.41.1 - busybox/ssl_client@1.36.1-r28 + busybox/ssl_client@1.36.1-r29 - openssl/libssl3@3.3.0-r2 + openssl/libssl3@3.3.1-r3 @@ -830,14 +662,42 @@

      Detailed paths


      NVD Description

      -

      This vulnerability has not been analyzed by NVD yet.

      +

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

      +

      Issue summary: Applications performing certificate name checks (e.g., TLS + clients checking server certificates) may attempt to read an invalid memory + address resulting in abnormal termination of the application process.

      +

      Impact summary: Abnormal termination of an application can a cause a denial of + service.

      +

      Applications performing certificate name checks (e.g., TLS clients checking + server certificates) may attempt to read an invalid memory address when + comparing the expected name with an otherName subject alternative name of an + X.509 certificate. This may result in an exception that terminates the + application program.

      +

      Note that basic certificate chain validation (signatures, dates, ...) is not + affected, the denial of service can occur only when the application also + specifies an expected DNS name, Email address or IP address.

      +

      TLS servers rarely solicit client certificates, and even when they do, they + generally don't perform a name check against a reference identifier (expected + identity), but rather extract the presented identity after checking the + certificate chain. So TLS servers are generally not affected and the severity + of the issue is Moderate.

      +

      The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

      Remediation

      -

      Upgrade Alpine:3.20 openssl to version 3.3.0-r3 or higher.

      +

      Upgrade Alpine:3.20 openssl to version 3.3.2-r0 or higher.

      +

      References

      +
    diff --git a/docs/snyk/v2.13.0-rc2/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html b/docs/snyk/v2.13.0-rc2/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html new file mode 100644 index 0000000000000..8197e5ec4909e --- /dev/null +++ b/docs/snyk/v2.13.0-rc2/public.ecr.aws_docker_library_haproxy_2.6.17-alpine.html @@ -0,0 +1,1305 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    September 22nd 2024, 12:21:37 am (UTC+00:00)

    +
    +
    + Scanned the following path: +
      +
    • public.ecr.aws/docker/library/haproxy:2.6.17-alpine/docker/library/haproxy (apk)
    • +
    +
    + +
    +
    5 known vulnerabilities
    +
    42 vulnerable dependency paths
    +
    18 dependencies
    +
    +
    +
    +
    +
    + + + + + + + +
    Project docker-image|public.ecr.aws/docker/library/haproxy
    Path public.ecr.aws/docker/library/haproxy:2.6.17-alpine/docker/library/haproxy
    Package Manager apk
    +
    +
    +
    +
    +

    Use After Free

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and busybox/busybox@1.36.1-r28 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/busybox@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + alpine-baselayout/alpine-baselayout@3.6.5-r0 + + busybox/busybox-binsh@1.36.1-r28 + + busybox/busybox@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + alpine-baselayout/alpine-baselayout@3.6.5-r0 + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    A use-after-free vulnerability in BusyBox v.1.36.1 allows attackers to cause a denial of service via a crafted awk pattern in the awk.c evaluate function.

    +

    Remediation

    +

    Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Use After Free

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and busybox/busybox@1.36.1-r28 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/busybox@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + alpine-baselayout/alpine-baselayout@3.6.5-r0 + + busybox/busybox-binsh@1.36.1-r28 + + busybox/busybox@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + alpine-baselayout/alpine-baselayout@3.6.5-r0 + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + busybox/busybox-binsh@1.36.1-r28 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    A use-after-free vulnerability was discovered in BusyBox v.1.36.1 via a crafted awk pattern in the awk.c copyvar function.

    +

    Remediation

    +

    Upgrade Alpine:3.20 busybox to version 1.36.1-r29 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-4741

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and openssl/libcrypto3@3.3.0-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.0-r3 or higher.

    + +
    + + + +
    +
    +

    CVE-2024-5535

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and openssl/libcrypto3@3.3.0-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Calling the OpenSSL API function SSL_select_next_proto with an + empty supported client protocols buffer may cause a crash or memory contents to + be sent to the peer.

    +

    Impact summary: A buffer overread can have a range of potential consequences + such as unexpected application beahviour or a crash. In particular this issue + could result in up to 255 bytes of arbitrary private data from memory being sent + to the peer leading to a loss of confidentiality. However, only applications + that directly call the SSL_select_next_proto function with a 0 length list of + supported client protocols are affected by this issue. This would normally never + be a valid scenario and is typically not under attacker control but may occur by + accident in the case of a configuration or programming error in the calling + application.

    +

    The OpenSSL API function SSL_select_next_proto is typically used by TLS + applications that support ALPN (Application Layer Protocol Negotiation) or NPN + (Next Protocol Negotiation). NPN is older, was never standardised and + is deprecated in favour of ALPN. We believe that ALPN is significantly more + widely deployed than NPN. The SSL_select_next_proto function accepts a list of + protocols from the server and a list of protocols from the client and returns + the first protocol that appears in the server list that also appears in the + client list. In the case of no overlap between the two lists it returns the + first item in the client list. In either case it will signal whether an overlap + between the two lists was found. In the case where SSL_select_next_proto is + called with a zero length client list it fails to notice this condition and + returns the memory immediately following the client list pointer (and reports + that there was no overlap in the lists).

    +

    This function is typically called from a server side application callback for + ALPN or a client side application callback for NPN. In the case of ALPN the list + of protocols supplied by the client is guaranteed by libssl to never be zero in + length. The list of server protocols comes from the application and should never + normally be expected to be of zero length. In this case if the + SSL_select_next_proto function has been called as expected (with the list + supplied by the client passed in the client/client_len parameters), then the + application will not be vulnerable to this issue. If the application has + accidentally been configured with a zero length server list, and has + accidentally passed that zero length server list in the client/client_len + parameters, and has additionally failed to correctly handle a "no overlap" + response (which would normally result in a handshake failure in ALPN) then it + will be vulnerable to this problem.

    +

    In the case of NPN, the protocol permits the client to opportunistically select + a protocol when there is no overlap. OpenSSL returns the first client protocol + in the no overlap case in support of this. The list of client protocols comes + from the application and should never normally be expected to be of zero length. + However if the SSL_select_next_proto function is accidentally called with a + client_len of 0 then an invalid memory pointer will be returned instead. If the + application uses this output as the opportunistic protocol then the loss of + confidentiality will occur.

    +

    This issue has been assessed as Low severity because applications are most + likely to be vulnerable if they are using NPN instead of ALPN - but NPN is not + widely used. It also requires an application configuration or programming error. + Finally, this issue would not typically be under attacker control making active + exploitation unlikely.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Due to the low severity of this issue we are not issuing new releases of + OpenSSL at this time. The fix will be included in the next releases when they + become available.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.1-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2024-6119

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.20 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine and openssl/libcrypto3@3.3.0-r2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + ca-certificates/ca-certificates@20240226-r0 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + openssl/libcrypto3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + .haproxy-rundeps@20240524.005458 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + apk-tools/apk-tools@2.14.4-r0 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    • + Introduced through: + docker-image|public.ecr.aws/docker/library/haproxy@2.6.17-alpine + + busybox/ssl_client@1.36.1-r28 + + openssl/libssl3@3.3.0-r2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.20 relevant fixed versions and status.

    +

    Issue summary: Applications performing certificate name checks (e.g., TLS + clients checking server certificates) may attempt to read an invalid memory + address resulting in abnormal termination of the application process.

    +

    Impact summary: Abnormal termination of an application can a cause a denial of + service.

    +

    Applications performing certificate name checks (e.g., TLS clients checking + server certificates) may attempt to read an invalid memory address when + comparing the expected name with an otherName subject alternative name of an + X.509 certificate. This may result in an exception that terminates the + application program.

    +

    Note that basic certificate chain validation (signatures, dates, ...) is not + affected, the denial of service can occur only when the application also + specifies an expected DNS name, Email address or IP address.

    +

    TLS servers rarely solicit client certificates, and even when they do, they + generally don't perform a name check against a reference identifier (expected + identity), but rather extract the presented identity after checking the + certificate chain. So TLS servers are generally not affected and the severity + of the issue is Moderate.

    +

    The FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.20 openssl to version 3.3.2-r0 or higher.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.13.0-rc2/public.ecr.aws_docker_library_redis_7.0.15-alpine.html b/docs/snyk/v2.13.0-rc2/public.ecr.aws_docker_library_redis_7.0.15-alpine.html new file mode 100644 index 0000000000000..26e6ff3618a3f --- /dev/null +++ b/docs/snyk/v2.13.0-rc2/public.ecr.aws_docker_library_redis_7.0.15-alpine.html @@ -0,0 +1,484 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    September 22nd 2024, 12:21:40 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)
    • +
    +
    + +
    +
    0 known vulnerabilities
    +
    0 vulnerable dependency paths
    +
    18 dependencies
    +
    +
    +
    +
    + +
    + No known vulnerabilities detected. +
    +
    + + + diff --git a/docs/snyk/v2.10.12/haproxy_2.6.14-alpine.html b/docs/snyk/v2.13.0-rc2/quay.io_argoproj_argocd_v2.13.0-rc2.html similarity index 52% rename from docs/snyk/v2.10.12/haproxy_2.6.14-alpine.html rename to docs/snyk/v2.13.0-rc2/quay.io_argoproj_argocd_v2.13.0-rc2.html index 808120d96d9a7..043d857a863c8 100644 --- a/docs/snyk/v2.10.12/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.13.0-rc2/quay.io_argoproj_argocd_v2.13.0-rc2.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,58 +456,56 @@

    Snyk test report

    -

    June 16th 2024, 12:20:52 am (UTC+00:00)

    +

    September 22nd 2024, 12:21:56 am (UTC+00:00)

    - Scanned the following path: + Scanned the following paths:
      -
    • haproxy:2.6.14-alpine (apk)
    • +
    • quay.io/argoproj/argocd:v2.13.0-rc2/argoproj/argocd/Dockerfile (deb)
    • +
    • quay.io/argoproj/argocd:v2.13.0-rc2/argoproj/argo-cd/v2//usr/local/bin/argocd (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.13.0-rc2//usr/local/bin/kustomize (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.13.0-rc2/helm/v3//usr/local/bin/helm (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.13.0-rc2/git-lfs/git-lfs//usr/bin/git-lfs (gomodules)
    11 known vulnerabilities
    -
    83 vulnerable dependency paths
    -
    18 dependencies
    +
    65 vulnerable dependency paths
    +
    2355 dependencies
    -
    - - - - - - - -
    Project docker-image|haproxy
    Path haproxy:2.6.14-alpine
    Package Manager apk
    -
    +
    -
    -

    CVE-2023-5363

    +
    +

    CVE-2024-41996

    -
    - high severity +
    + medium severity

    • - Package Manager: alpine:3.18 + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc2/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04
    • Vulnerable module: - openssl/libcrypto3 + openssl/libssl3t64
    • Introduced through: - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 and openssl/libssl3t64@3.0.13-0ubuntu3.4
    @@ -520,289 +518,135 @@

    Detailed paths

    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libcrypto3@3.1.2-r0 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - .haproxy-rundeps@20230809.001942 + coreutils@9.4-3ubuntu6 - openssl/libcrypto3@3.1.2-r0 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - apk-tools/apk-tools@2.14.0-r2 + cyrus-sasl2/libsasl2-modules@2.1.28+dfsg1-5ubuntu3.1 - openssl/libcrypto3@3.1.2-r0 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - busybox/ssl_client@1.36.1-r2 + libfido2/libfido2-1@1.14.0-1build3 - openssl/libcrypto3@3.1.2-r0 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - .haproxy-rundeps@20230809.001942 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 - openssl/libssl3@3.1.2-r0 - - openssl/libcrypto3@3.1.2-r0 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine + ca-certificates@20240203 - .haproxy-rundeps@20230809.001942 + openssl@3.0.13-0ubuntu3.4 - openssl/libssl3@3.1.2-r0 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - apk-tools/apk-tools@2.14.0-r2 + git@1:2.43.0-1ubuntu7.1 - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - busybox/ssl_client@1.36.1-r2 + libssh/libssh-4@0.10.6-2build2 - openssl/libssl3@3.1.2-r0 + openssl/libssl3t64@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 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 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine + git@1:2.43.0-1ubuntu7.1 - .haproxy-rundeps@20230809.001942 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - 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 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - busybox/ssl_client@1.36.1-r2 + krb5/libkrb5-3@1.20.1-6ubuntu2.1 - openssl/libcrypto3@3.1.2-r0 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libssl3@3.1.2-r0 + git@1:2.43.0-1ubuntu7.1 - openssl/libcrypto3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine + openldap/libldap2@2.6.7+dfsg-1~exp1ubuntu8 - .haproxy-rundeps@20230809.001942 + cyrus-sasl2/libsasl2-2@2.1.28+dfsg1-5ubuntu3.1 - openssl/libssl3@3.1.2-r0 + openssl/libssl3t64@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libssl3@3.1.2-r0 + openssl@3.0.13-0ubuntu3.4
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - busybox/ssl_client@1.36.1-r2 + ca-certificates@20240203 - openssl/libssl3@3.1.2-r0 + openssl@3.0.13-0ubuntu3.4 @@ -814,55 +658,28 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by 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.

      +

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      +

      Validating the order of the public keys in the Diffie-Hellman Key Agreement Protocol, when an approved safe prime is used, allows remote attackers (from the client side) to trigger unnecessarily expensive server-side DHE modular-exponentiation calculations. The client may cause asymmetric resource consumption. The basic attack scenario is that the client must claim that it can only communicate with DHE, and the server must be configured to allow DHE and validate the order of the public key.

      Remediation

      -

      Upgrade Alpine:3.18 openssl to version 3.1.4-r1 or higher.

      +

      There is no fixed version for Ubuntu:24.04 openssl.

      References


    -

    Out-of-bounds Write

    +

    Information Exposure

    @@ -873,17 +690,20 @@

    Out-of-bounds Write

    • - Package Manager: alpine:3.18 + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc2/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04
    • Vulnerable module: - openssl/libcrypto3 + libgcrypt20
    • Introduced through: - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 and libgcrypt20@1.10.3-2build1
    @@ -896,97 +716,100 @@

    Detailed paths

    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libcrypto3@3.1.2-r0 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - .haproxy-rundeps@20230809.001942 + gnupg2/dirmngr@2.4.4-2ubuntu17 - openssl/libcrypto3@3.1.2-r0 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - apk-tools/apk-tools@2.14.0-r2 + gnupg2/gpg@2.4.4-2ubuntu17 - openssl/libcrypto3@3.1.2-r0 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - busybox/ssl_client@1.36.1-r2 + gnupg2/gpg-agent@2.4.4-2ubuntu17 - openssl/libcrypto3@3.1.2-r0 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - .haproxy-rundeps@20230809.001942 + apt@2.7.14build2 - openssl/libssl3@3.1.2-r0 + apt/libapt-pkg6.0t64@2.7.14build2 - openssl/libcrypto3@3.1.2-r0 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libssl3@3.1.2-r0 - - - -
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine + apt@2.7.14build2 - .haproxy-rundeps@20230809.001942 + gnupg2/gpgv@2.4.4-2ubuntu17 - openssl/libssl3@3.1.2-r0 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + gnupg2/gpg@2.4.4-2ubuntu17 - apk-tools/apk-tools@2.14.0-r2 + gnupg2/gpgconf@2.4.4-2ubuntu17 - openssl/libssl3@3.1.2-r0 + libgcrypt20@1.10.3-2build1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - busybox/ssl_client@1.36.1-r2 + apt@2.7.14build2 - openssl/libssl3@3.1.2-r0 + adduser@3.137ubuntu1 + + shadow/passwd@1:4.13+dfsg1-4ubuntu3 + + pam/libpam-modules@1.5.3-5ubuntu5.1 + + systemd/libsystemd0@255.4-1ubuntu8.4 + + libgcrypt20@1.10.3-2build1 @@ -998,60 +821,28 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by 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.

      +

      Note: Versions mentioned in the description apply only to the upstream libgcrypt20 package and not the libgcrypt20 package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      +

      A timing-based side-channel flaw was found in libgcrypt's RSA implementation. This issue may allow a remote attacker to initiate a Bleichenbacher-style attack, which can lead to the decryption of RSA ciphertexts.

      Remediation

      -

      Upgrade Alpine:3.18 openssl to version 3.1.4-r3 or higher.

      +

      There is no fixed version for Ubuntu:24.04 libgcrypt20.

      References


    -

    CVE-2024-0727

    +

    CVE-2024-26462

    @@ -1062,18 +853,21 @@

    CVE-2024-0727

    • - Package Manager: alpine:3.18 + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc2/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04
    • Vulnerable module: - openssl/libcrypto3 + krb5/libk5crypto3
    • Introduced through: - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1085,97 +879,146 @@

    Detailed paths

    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 - openssl/libcrypto3@3.1.2-r0 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - .haproxy-rundeps@20230809.001942 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - openssl/libcrypto3@3.1.2-r0 + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 - apk-tools/apk-tools@2.14.0-r2 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl/libcrypto3@3.1.2-r0 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 - busybox/ssl_client@1.36.1-r2 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl/libcrypto3@3.1.2-r0 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - .haproxy-rundeps@20230809.001942 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - openssl/libssl3@3.1.2-r0 + krb5/libkrb5-3@1.20.1-6ubuntu2.1 - openssl/libcrypto3@3.1.2-r0 + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl/libssl3@3.1.2-r0 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - .haproxy-rundeps@20230809.001942 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 - openssl/libssl3@3.1.2-r0 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 - apk-tools/apk-tools@2.14.0-r2 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl/libssl3@3.1.2-r0 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - busybox/ssl_client@1.36.1-r2 + libssh/libssh-4@0.10.6-2build2 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libssl3@3.1.2-r0 + krb5/krb5-locales@1.20.1-6ubuntu2.1 @@ -1187,68 +1030,51 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

      -

      Issue summary: 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.

      +

      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

      -

      Upgrade Alpine:3.18 openssl to version 3.1.4-r5 or higher.

      +

      There is no fixed version for Ubuntu:24.04 krb5.

      References


    -
    -

    Out-of-bounds Write

    +
    +

    Release of Invalid Pointer or Reference

    -
    - medium severity +
    + low severity

    • - Package Manager: alpine:3.18 + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc2/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04
    • Vulnerable module: - busybox/busybox + patch
    • Introduced through: - docker-image|haproxy@2.6.14-alpine and busybox/busybox@1.36.1-r2 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 and patch@2.7.6-7build3
    @@ -1261,51 +1087,9 @@

    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 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - 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 + patch@2.7.6-7build3 @@ -1317,46 +1101,50 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

      -

      A heap-buffer-overflow was discovered in BusyBox v.1.36.1 in the next_token function at awk.c:1159.

      +

      Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      +

      An Invalid Pointer vulnerability exists in GNU patch 2.7 via the another_hunk function, which causes a Denial of Service.

      Remediation

      -

      Upgrade Alpine:3.18 busybox to version 1.36.1-r6 or higher.

      +

      There is no fixed version for Ubuntu:24.04 patch.

      References


    -
    -

    Use After Free

    +
    +

    Double Free

    -
    - medium severity +
    + low severity

    • - Package Manager: alpine:3.18 + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc2/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04
    • Vulnerable module: - busybox/busybox + patch
    • Introduced through: - docker-image|haproxy@2.6.14-alpine and busybox/busybox@1.36.1-r2 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 and patch@2.7.6-7build3
    @@ -1369,51 +1157,9 @@

    Detailed paths

    -
    -

    Use After Free

    +
    +

    CVE-2024-26458

    -
    - medium severity +
    + low severity

    • - Package Manager: alpine:3.18 + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc2/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04
    • Vulnerable module: - busybox/busybox + krb5/libk5crypto3
    • Introduced through: - docker-image|haproxy@2.6.14-alpine and busybox/busybox@1.36.1-r2 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1477,159 +1232,146 @@

    Detailed paths

    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - busybox/busybox@1.36.1-r2 + krb5/libk5crypto3@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + git@1:2.43.0-1ubuntu7.1 - busybox/busybox-binsh@1.36.1-r2 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - busybox/busybox@1.36.1-r2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - busybox/busybox-binsh@1.36.1-r2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + krb5/libkrb5-3@1.20.1-6ubuntu2.1 - busybox/busybox-binsh@1.36.1-r2 + krb5/libkrb5support0@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - busybox/ssl_client@1.36.1-r2 + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1
    • -
    - -
    - -
    - -

    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 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - busybox/busybox@1.36.1-r2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine - - alpine-baselayout/alpine-baselayout@3.4.3-r1 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - busybox/busybox-binsh@1.36.1-r2 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 - busybox/busybox@1.36.1-r2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - busybox/busybox-binsh@1.36.1-r2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - alpine-baselayout/alpine-baselayout@3.4.3-r1 + git@1:2.43.0-1ubuntu7.1 - busybox/busybox-binsh@1.36.1-r2 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + libssh/libssh-4@0.10.6-2build2 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - busybox/ssl_client@1.36.1-r2 + krb5/krb5-locales@1.20.1-6ubuntu2.1 @@ -1641,25 +1383,27 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

      -

      A use-after-free vulnerability was discovered in BusyBox v.1.36.1 via a crafted awk pattern in the awk.c copyvar function.

      +

      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

      -

      Upgrade Alpine:3.18 busybox to version 1.36.1-r7 or higher.

      +

      There is no fixed version for Ubuntu:24.04 krb5.

      References


    -

    CVE-2023-6237

    +

    CVE-2024-26461

    @@ -1670,18 +1414,21 @@

    CVE-2023-6237

    • - Package Manager: alpine:3.18 + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc2/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04
    • Vulnerable module: - openssl/libcrypto3 + krb5/libk5crypto3
    • Introduced through: - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2, git@1:2.43.0-1ubuntu7.1 and others
    @@ -1693,97 +1440,146 @@

    Detailed paths

    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - openssl/libcrypto3@3.1.2-r0 + krb5/libk5crypto3@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - .haproxy-rundeps@20230809.001942 + git@1:2.43.0-1ubuntu7.1 - openssl/libcrypto3@3.1.2-r0 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libk5crypto3@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 - apk-tools/apk-tools@2.14.0-r2 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl/libcrypto3@3.1.2-r0 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - busybox/ssl_client@1.36.1-r2 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - openssl/libcrypto3@3.1.2-r0 + krb5/libkrb5-3@1.20.1-6ubuntu2.1 + + krb5/libkrb5support0@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - .haproxy-rundeps@20230809.001942 + krb5/libkrb5-3@1.20.1-6ubuntu2.1 - openssl/libssl3@3.1.2-r0 + krb5/libk5crypto3@1.20.1-6ubuntu2.1 - openssl/libcrypto3@3.1.2-r0 + krb5/libkrb5support0@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 + + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 - openssl/libssl3@3.1.2-r0 + krb5/libkrb5-3@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - .haproxy-rundeps@20230809.001942 + openssh/openssh-client@1:9.6p1-3ubuntu13.5 - openssl/libssl3@3.1.2-r0 + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - apk-tools/apk-tools@2.14.0-r2 + git@1:2.43.0-1ubuntu7.1 - openssl/libssl3@3.1.2-r0 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + git@1:2.43.0-1ubuntu7.1 - busybox/ssl_client@1.36.1-r2 + curl/libcurl3t64-gnutls@8.5.0-2ubuntu10.4 - openssl/libssl3@3.1.2-r0 + libssh/libssh-4@0.10.6-2build2 + + krb5/libgssapi-krb5-2@1.20.1-6ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 + + krb5/krb5-locales@1.20.1-6ubuntu2.1 @@ -1795,49 +1591,27 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by 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.

      +

      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

      -

      Upgrade Alpine:3.18 openssl to version 3.1.4-r4 or higher.

      +

      There is no fixed version for Ubuntu:24.04 krb5.

      References


    -

    CVE-2024-2511

    +

    Out-of-bounds Write

    @@ -1848,17 +1622,20 @@

    CVE-2024-2511

    • - Package Manager: alpine:3.18 + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc2/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04
    • Vulnerable module: - openssl/libcrypto3 + gnupg2/gpgv
    • Introduced through: - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 and gnupg2/gpgv@2.4.4-2ubuntu17
    @@ -1871,97 +1648,80 @@

    Detailed paths

    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libcrypto3@3.1.2-r0 + gnupg2/gpgv@2.4.4-2ubuntu17
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - .haproxy-rundeps@20230809.001942 + apt@2.7.14build2 - openssl/libcrypto3@3.1.2-r0 + gnupg2/gpgv@2.4.4-2ubuntu17
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - apk-tools/apk-tools@2.14.0-r2 + gnupg2/dirmngr@2.4.4-2ubuntu17 - openssl/libcrypto3@3.1.2-r0 + gnupg2/gpgconf@2.4.4-2ubuntu17
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - busybox/ssl_client@1.36.1-r2 + gnupg2/gpg-agent@2.4.4-2ubuntu17 - openssl/libcrypto3@3.1.2-r0 + gnupg2/gpgconf@2.4.4-2ubuntu17
    • Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libssl3@3.1.2-r0 + gnupg2/gpg@2.4.4-2ubuntu17 - openssl/libcrypto3@3.1.2-r0 + gnupg2/gpgconf@2.4.4-2ubuntu17
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libssl3@3.1.2-r0 + gnupg2/dirmngr@2.4.4-2ubuntu17
    • Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libssl3@3.1.2-r0 + gnupg2/gpg@2.4.4-2ubuntu17
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - 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 + gnupg2/gpg-agent@2.4.4-2ubuntu17 @@ -1973,45 +1733,31 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

      -

      Issue summary: 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.

      +

      Note: Versions mentioned in the description apply only to the upstream gnupg2 package and not the gnupg2 package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

      +

      GnuPG can be made to spin on a relatively small input by (for example) crafting a public key with thousands of signatures attached, compressed down to just a few KB.

      Remediation

      -

      Upgrade Alpine:3.18 openssl to version 3.1.4-r6 or higher.

      +

      There is no fixed version for Ubuntu:24.04 gnupg2.

      References


    -

    CVE-2024-4603

    +

    Allocation of Resources Without Limits or Throttling

    @@ -2022,17 +1768,20 @@

    CVE-2024-4603

    • - Package Manager: alpine:3.18 + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc2/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04
    • Vulnerable module: - openssl/libcrypto3 + glibc/libc-bin
    • Introduced through: - docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 and glibc/libc-bin@2.39-0ubuntu8.3
    @@ -2045,97 +1794,183 @@

    Detailed paths

    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libcrypto3@3.1.2-r0 + glibc/libc-bin@2.39-0ubuntu8.3
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - .haproxy-rundeps@20230809.001942 - - openssl/libcrypto3@3.1.2-r0 + glibc/libc6@2.39-0ubuntu8.3
    • -
    • - 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 - - +
  • - +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    sha256crypt and sha512crypt through 0.6 allow attackers to cause a denial of service (CPU consumption) because the algorithm's runtime is proportional to the square of the length of the password.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 glibc.

    +

    References

    + + +
    + + + +
    +
    +

    Improper Input Validation

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc2/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + git/git-man +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2, git@1:2.43.0-1ubuntu7.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
    • Introduced through: - docker-image|haproxy@2.6.14-alpine - - .haproxy-rundeps@20230809.001942 + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libssl3@3.1.2-r0 + git@1:2.43.0-1ubuntu7.1 - openssl/libcrypto3@3.1.2-r0 + git/git-man@1:2.43.0-1ubuntu7.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - openssl/libssl3@3.1.2-r0 + git@1:2.43.0-1ubuntu7.1
    • Introduced through: - docker-image|haproxy@2.6.14-alpine + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 - .haproxy-rundeps@20230809.001942 + git-lfs@3.4.1-1ubuntu0.1 - openssl/libssl3@3.1.2-r0 + git@1:2.43.0-1ubuntu7.1
    • -
    • - Introduced through: - docker-image|haproxy@2.6.14-alpine - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.2-r0 - - +
    - +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream git package and not the git package as distributed by Ubuntu. + See How to fix? for Ubuntu:24.04 relevant fixed versions and status.

    +

    GIT version 2.15.1 and earlier contains a Input Validation Error vulnerability in Client that can result in problems including messing up terminal configuration to RCE. This attack appear to be exploitable via The user must interact with a malicious git server, (or have their traffic modified in a MITM attack).

    +

    Remediation

    +

    There is no fixed version for Ubuntu:24.04 git.

    +

    References

    + + +
    + + + +
    +
    +

    Improper Input Validation

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Manifest file: quay.io/argoproj/argocd:v2.13.0-rc2/argoproj/argocd Dockerfile +
    • +
    • + Package Manager: ubuntu:24.04 +
    • +
    • + Vulnerable module: + + coreutils +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.13.0-rc2 and coreutils@9.4-3ubuntu6 + +
    • +
    + +
    + + +

    Detailed paths

    + +
    diff --git a/docs/snyk/v2.13.0-rc2/redis_7.0.15-alpine.html b/docs/snyk/v2.13.0-rc2/redis_7.0.15-alpine.html new file mode 100644 index 0000000000000..9ce4786034705 --- /dev/null +++ b/docs/snyk/v2.13.0-rc2/redis_7.0.15-alpine.html @@ -0,0 +1,484 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    September 22nd 2024, 12:22:00 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)
    • +
    +
    + +
    +
    0 known vulnerabilities
    +
    0 vulnerable dependency paths
    +
    18 dependencies
    +
    +
    +
    +
    + +
    + No known vulnerabilities detected. +
    +
    + + + diff --git a/docs/snyk/v2.9.17/argocd-test.html b/docs/snyk/v2.9.17/argocd-test.html deleted file mode 100644 index a9fd4cf5773f8..0000000000000 --- a/docs/snyk/v2.9.17/argocd-test.html +++ /dev/null @@ -1,4197 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
    -
    -
    -
    - - - Snyk - Open Source Security - - - - - - - -
    -

    Snyk test report

    - -

    June 16th 2024, 12:22:56 am (UTC+00:00)

    -
    -
    - Scanned the following paths: -
      -
    • /argo-cd/argoproj/argo-cd/v2/go.mod (gomodules)
    • -
    • /argo-cd/ui/yarn.lock (yarn)
    • -
    -
    - -
    -
    11 known vulnerabilities
    -
    176 vulnerable dependency paths
    -
    1919 dependencies
    -
    -
    -
    -
    - -
    -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - google.golang.org/grpc -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and google.golang.org/grpc@1.56.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - 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.56.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/health/grpc_health_v1@1.56.2 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - 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@1.56.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/health@1.56.2 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/reflection@1.56.2 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - 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.56.2 - - - -
    • -
    • - 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.56.2 - - - -
    • -
    • - 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.56.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - 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.56.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.42.0 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/auth@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 - - go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig@1.16.0 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 - - go.opentelemetry.io/proto/otlp/collector/trace/v1@0.19.0 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - 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.56.2 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/reflection@1.56.2 - - google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.56.2 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/health@1.56.2 - - google.golang.org/grpc/health/grpc_health_v1@1.56.2 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/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 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - 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 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/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.56.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 - - go.opentelemetry.io/proto/otlp/collector/trace/v1@0.19.0 - - github.com/grpc-ecosystem/grpc-gateway/v2/runtime@2.11.3 - - google.golang.org/grpc/health/grpc_health_v1@1.56.2 - - google.golang.org/grpc@1.56.2 - - - -
    • -
    • - 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.56.2 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    google.golang.org/grpc is a Go implementation of gRPC

    -

    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.

    -

    Remediation

    -

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.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.24.17 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - golang.org/x/net/http2@0.19.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc@1.56.2 - - google.golang.org/grpc/internal/transport@1.56.2 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/transport@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.56.2 - - google.golang.org/grpc/internal/transport@1.56.2 - - 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.56.2 - - google.golang.org/grpc@1.56.2 - - google.golang.org/grpc/internal/transport@1.56.2 - - 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.56.2 - - google.golang.org/grpc/internal/transport@1.56.2 - - 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.56.2 - - google.golang.org/grpc/internal/transport@1.56.2 - - 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.56.2 - - google.golang.org/grpc/internal/transport@1.56.2 - - 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.16.0 - - google.golang.org/grpc@1.56.2 - - google.golang.org/grpc/internal/transport@1.56.2 - - 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.56.2 - - google.golang.org/grpc/internal/transport@1.56.2 - - 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.42.0 - - google.golang.org/grpc@1.56.2 - - google.golang.org/grpc/internal/transport@1.56.2 - - 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.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/tools/auth@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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@#9dcecdc3eebf - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/testing@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/testing@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.11.0 - - k8s.io/client-go/dynamic@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/transport/spdy@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#b0fffe419a0f - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - k8s.io/client-go/transport@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/transport@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - k8s.io/client-go/transport@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - k8s.io/client-go/transport@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - k8s.io/client-go/transport@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/rest@0.24.17 - - k8s.io/client-go/transport@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.56.2 - - google.golang.org/grpc@1.56.2 - - google.golang.org/grpc/internal/transport@1.56.2 - - 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.56.2 - - google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.56.2 - - google.golang.org/grpc@1.56.2 - - google.golang.org/grpc/internal/transport@1.56.2 - - 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.56.2 - - google.golang.org/grpc/health/grpc_health_v1@1.56.2 - - google.golang.org/grpc@1.56.2 - - google.golang.org/grpc/internal/transport@1.56.2 - - 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@#b0fffe419a0f - - k8s.io/kubectl/pkg/util/openapi@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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@#b0fffe419a0f - - k8s.io/kubectl/pkg/util/openapi@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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@#b0fffe419a0f - - k8s.io/kubectl/pkg/util/openapi@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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@#9dcecdc3eebf - - k8s.io/client-go/listers/core/v1@0.24.17 - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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@#9dcecdc3eebf - - k8s.io/client-go/tools/clientcmd@0.24.17 - - k8s.io/client-go/tools/auth@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/listers/core/v1@0.24.17 - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/cache/internal@0.11.0 - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/tools/remotecommand@0.24.17 - - k8s.io/client-go/transport/spdy@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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/resource@#b0fffe419a0f - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#b0fffe419a0f - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#b0fffe419a0f - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#b0fffe419a0f - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/scheme@0.11.0 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#b0fffe419a0f - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/api/errors@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/tools/pager@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/api/equality@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/testing@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - k8s.io/client-go/transport@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/testing@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - k8s.io/client-go/transport@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/transport/spdy@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - k8s.io/client-go/transport@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#b0fffe419a0f - - github.com/argoproj/gitops-engine/pkg/utils/kube@#b0fffe419a0f - - k8s.io/kubectl/pkg/util/openapi@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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@#b0fffe419a0f - - github.com/argoproj/gitops-engine/pkg/utils/kube@#b0fffe419a0f - - k8s.io/kubectl/pkg/util/openapi@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 - - k8s.io/client-go/restmapper@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.11.0 - - k8s.io/client-go/tools/clientcmd@0.24.17 - - k8s.io/client-go/tools/auth@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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@#b0fffe419a0f - - k8s.io/apimachinery/pkg/util/strategicpatch@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#b0fffe419a0f - - github.com/argoproj/gitops-engine/pkg/sync/resource@#b0fffe419a0f - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/api/storage/v1beta1@0.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/listers/core/v1@0.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/tools/reference@0.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#9dcecdc3eebf - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/tools/pager@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/tools/pager@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/tools/pager@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#9dcecdc3eebf - - k8s.io/client-go/listers/core/v1@0.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.11.0 - - k8s.io/client-go/dynamic@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/tools/remotecommand@0.24.17 - - k8s.io/client-go/transport/spdy@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - k8s.io/client-go/transport@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.56.2 - - google.golang.org/grpc/internal/transport@1.56.2 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/cache/internal@0.11.0 - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.24.17 - - k8s.io/client-go/applyconfigurations/storage/v1beta1@0.24.17 - - k8s.io/client-go/applyconfigurations/meta/v1@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/metrics@0.11.0 - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.24.17 - - k8s.io/client-go/tools/clientcmd/api/latest@0.24.17 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/kubernetes/scheme@0.24.17 - - k8s.io/api/storage/v1beta1@0.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/cache/internal@0.11.0 - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/tools/pager@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#b0fffe419a0f - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b0fffe419a0f - - github.com/argoproj/gitops-engine/pkg/sync/common@#b0fffe419a0f - - github.com/argoproj/gitops-engine/pkg/utils/kube@#b0fffe419a0f - - k8s.io/kubectl/pkg/util/openapi@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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@#b0fffe419a0f - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b0fffe419a0f - - github.com/argoproj/gitops-engine/pkg/sync/common@#b0fffe419a0f - - github.com/argoproj/gitops-engine/pkg/utils/kube@#b0fffe419a0f - - k8s.io/kubectl/pkg/util/openapi@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/manager@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/webhook@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/metrics@0.11.0 - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.11.0 - - k8s.io/apimachinery/pkg/runtime/serializer@0.24.17 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.11.0 - - k8s.io/apimachinery/pkg/runtime/serializer@0.24.17 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#9dcecdc3eebf - - k8s.io/client-go/tools/clientcmd@0.24.17 - - k8s.io/client-go/tools/clientcmd/api/latest@0.24.17 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/kubernetes/scheme@0.24.17 - - k8s.io/api/storage/v1beta1@0.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.24.17 - - k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.24.17 - - k8s.io/client-go/kubernetes/scheme@0.24.17 - - k8s.io/api/storage/v1beta1@0.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#b0fffe419a0f - - k8s.io/kubernetes/pkg/apis/storage/install@1.24.17 - - k8s.io/kubernetes/pkg/apis/storage/v1alpha1@1.24.17 - - k8s.io/api/storage/v1alpha1@0.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#b0fffe419a0f - - github.com/argoproj/gitops-engine/pkg/sync/hook@#b0fffe419a0f - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b0fffe419a0f - - github.com/argoproj/gitops-engine/pkg/sync/common@#b0fffe419a0f - - github.com/argoproj/gitops-engine/pkg/utils/kube@#b0fffe419a0f - - k8s.io/kubectl/pkg/util/openapi@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/source@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.17 - - k8s.io/client-go/rest@0.24.17 - - 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@#b0fffe419a0f - - k8s.io/kubectl/pkg/util/openapi@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/kubernetes/scheme@0.24.17 - - k8s.io/api/storage/v1beta1@0.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#b0fffe419a0f - - k8s.io/kubectl/pkg/util/openapi@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/kubernetes/scheme@0.24.17 - - k8s.io/api/storage/v1beta1@0.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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@#b0fffe419a0f - - k8s.io/kubectl/pkg/util/openapi@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/kubernetes/scheme@0.24.17 - - k8s.io/api/storage/v1beta1@0.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/cache/internal@0.11.0 - - k8s.io/client-go/tools/cache@0.24.17 - - k8s.io/client-go/tools/pager@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 - - k8s.io/client-go/restmapper@0.24.17 - - k8s.io/client-go/discovery@0.24.17 - - k8s.io/client-go/kubernetes/scheme@0.24.17 - - k8s.io/api/storage/v1beta1@0.24.17 - - k8s.io/api/core/v1@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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.11.0 - - sigs.k8s.io/controller-runtime/pkg/source@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.17 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.17 - - k8s.io/apimachinery/pkg/watch@0.24.17 - - k8s.io/apimachinery/pkg/util/net@0.24.17 - - 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

    - -
    - - - -
    -
    -

    Regular Expression Denial of Service (ReDoS)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd/argoproj/argo-cd/v2 go.mod -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/whilp/git-urls -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/whilp/git-urls@1.0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/whilp/git-urls@1.0.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf - - github.com/whilp/git-urls@1.0.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf - - github.com/whilp/git-urls@1.0.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf - - github.com/whilp/git-urls@1.0.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf - - github.com/whilp/git-urls@1.0.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf - - github.com/whilp/git-urls@1.0.2 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    github.com/whilp/git-urls is a Git URLs parser

    -

    Affected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) due to the usage of an insecure regular expression in scpSyntax. Exploiting this vulnerability is possible when a long input is provided inside the directory path of the git URL.

    -

    Note: - This vulnerability has existed since commit 4a18977c6eecbf4ce0ca1e486e9ba77072ba4395.

    -

    PoC

    -
    
    -        var payload = strings.Repeat("////", 19000000) //payload used, the number can be tweaked to cause 7 second delay
    -        malicious_url := "6en6ar@-:0////" + payload + "\"
    -        begin := time.Now()
    -        //u, err := giturls.ParseScp("remote_username@10.10.0.2:/remote/directory")// normal git url
    -        _, err := giturls.ParseScp(malicious_url)
    -        if err != nil {
    -        fmt.Errorf("[ - ] Error ->" + err.Error())
    -        }
    -        //fmt.Println("[ + ] Url --> " + u.Host)
    -        elapse := time.Since(begin)
    -        fmt.Printf("Function took %s", elapse)
    -        
    -

    Details

    -

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.

    -

    The Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.

    -

    Let’s take the following regular expression as an example:

    -
    regex = /A(B|C+)+D/
    -        
    -

    This regular expression accomplishes the following:

    -
      -
    • A The string must start with the letter 'A'
    • -
    • (B|C+)+ The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the + matches one or more times). The + at the end of this section states that we can look for one or more matches of this section.
    • -
    • D Finally, we ensure this section of the string ends with a 'D'
    • -
    -

    The expression would match inputs such as ABBD, ABCCCCD, ABCBCCCD and ACCCCCD

    -

    It most cases, it doesn't take very long for a regex engine to find a match:

    -
    $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD")'
    -        0.04s user 0.01s system 95% cpu 0.052 total
    -        
    -        $ time node -e '/A(B|C+)+D/.test("ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX")'
    -        1.79s user 0.02s system 99% cpu 1.812 total
    -        
    -

    The entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.

    -

    Most Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as catastrophic backtracking.

    -

    Let's look at how our expression runs into this problem, using a shorter string: "ACCCX". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:

    -
      -
    1. CCC
    2. -
    3. CC+C
    4. -
    5. C+CC
    6. -
    7. C+C+C.
    8. -
    -

    The engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use RegEx 101 debugger to see the engine has to take a total of 38 steps before it can determine the string doesn't match.

    -

    From there, the number of steps the engine must use to validate a string just continues to grow.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    StringNumber of C'sNumber of steps
    ACCCX338
    ACCCCX471
    ACCCCCX5136
    ACCCCCCCCCCCCCCX1465,553
    -

    By the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.

    -

    Remediation

    -

    There is no fixed version for github.com/whilp/git-urls.

    -

    References

    - - -
    - - - -
    -
    -

    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

    - -
    - - - -
    -
    -

    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/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/services@#9dcecdc3eebf - - 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/subscriptions@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf - - 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@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf - - 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@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf - - 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@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf - - 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@#9dcecdc3eebf - - 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@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf - - 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@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf - - 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@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf - - 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@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf - - github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf - - 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

    - - -
    - - - -
    -
    -

    Template Injection

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: /argo-cd ui/yarn.lock -
    • -
    • - Package Manager: npm -
    • -
    • - Vulnerable module: - - dompurify -
    • - -
    • Introduced through: - - - argo-cd-ui@1.0.0, redoc@2.0.0-rc.64 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - argo-cd-ui@1.0.0 - - redoc@2.0.0-rc.64 - - dompurify@2.3.6 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    dompurify is a DOM-only XSS sanitizer for HTML, MathML and SVG.

    -

    Affected versions of this package are vulnerable to Template Injection in purify.js, due to inconsistencies in the parsing of XML and HTML tags. Executable code can be injected in HTML inside XML CDATA blocks.

    -

    PoC

    -
    <![CDATA[ ><img src onerror=alert(1)> ]]>
    -        
    -

    Remediation

    -

    Upgrade dompurify to version 2.4.9, 3.0.11 or higher.

    -

    References

    - - -
    - - - -
    -
    -
    -
    - - - diff --git a/docs/snyk/v2.9.17/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.9.17/ghcr.io_dexidp_dex_v2.37.0.html deleted file mode 100644 index 39dd138e3930d..0000000000000 --- a/docs/snyk/v2.9.17/ghcr.io_dexidp_dex_v2.37.0.html +++ /dev/null @@ -1,5205 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
    -
    -
    -
    - - - Snyk - Open Source Security - - - - - - - -
    -

    Snyk test report

    - -

    June 16th 2024, 12:23:03 am (UTC+00:00)

    -
    -
    - Scanned the following paths: -
      -
    • ghcr.io/dexidp/dex:v2.37.0/dexidp/dex (apk)
    • -
    • ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3//usr/local/bin/gomplate (gomodules)
    • -
    • ghcr.io/dexidp/dex:v2.37.0/dexidp/dex//usr/local/bin/docker-entrypoint (gomodules)
    • -
    • ghcr.io/dexidp/dex:v2.37.0/dexidp/dex//usr/local/bin/dex (gomodules)
    • -
    -
    - -
    -
    49 known vulnerabilities
    -
    157 vulnerable dependency paths
    -
    786 dependencies
    -
    -
    -
    -
    - -
    -
    -
    -

    Path Traversal

    -
    - -
    - critical severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-git/go-git/v5 -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/go-git/go-git/v5@v5.4.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/go-git/go-git/v5@v5.4.2 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Path Traversal via malicious server replies. An attacker can create and amend files across the filesystem and potentially achieve remote code execution by sending crafted responses to the client.

    -

    Notes:

    -
      -
    1. This is only exploitable if the client is using ChrootOS, which is the default for certain functions such as PlainClone.

      -
    2. -
    3. Applications using BoundOS or in-memory filesystems are not affected by this issue.

      -
    4. -
    5. Users running versions of go-git from v4 and above are recommended to upgrade to v5.11 in order to mitigate this vulnerability.

      -
    6. -
    -

    Workaround

    -

    This vulnerability can be mitigated by limiting the client's use to trustworthy Git servers.

    -

    Remediation

    -

    Upgrade github.com/go-git/go-git/v5 to version 5.11.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Out-of-bounds Write

    -
    - -
    - critical severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/busybox@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r0 - - busybox/busybox@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/busybox-binsh@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    There is a stack overflow vulnerability in ash.c:6030 in busybox before 1.35. In the environment of Internet of Vehicles, this vulnerability can be executed from command to arbitrary code execution.

    -

    Remediation

    -

    Upgrade Alpine:3.18 busybox to version 1.36.1-r1 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    CVE-2023-5363

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: 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

    - - -
    - - - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - google.golang.org/grpc -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and google.golang.org/grpc@v1.46.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - google.golang.org/grpc@v1.46.2 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - google.golang.org/grpc@v1.56.1 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    google.golang.org/grpc is a Go implementation of gRPC

    -

    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.

    -

    Remediation

    -

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/http2 -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.7.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - golang.org/x/net/http2@v0.7.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - golang.org/x/net/http2@v0.11.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    -

    Affected versions of this package are vulnerable to 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.

    -

    Remediation

    -

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/http2 -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.7.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - golang.org/x/net/http2@v0.7.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - golang.org/x/net/http2@v0.11.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling when reading header data from CONTINUATION frames. As part of the HPACK flow, all incoming HEADERS and CONTINUATION frames are read even if their payloads exceed MaxHeaderBytes and will be discarded. An attacker can send excessive data over a connection to render it unresponsive.

    -

    Remediation

    -

    Upgrade golang.org/x/net/http2 to version 0.23.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Heap-based Buffer Overflow

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/dexidp/dex /usr/local/bin/dex -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/mattn/go-sqlite3 -
    • - -
    • Introduced through: - - github.com/dexidp/dex@* and github.com/mattn/go-sqlite3@v1.14.17 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/mattn/go-sqlite3@v1.14.17 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Heap-based Buffer Overflow via the sessionReadRecord function in the ext/session/sqlite3session.c file. An attacker can cause a program crash or execute arbitrary code by manipulating the input to trigger a heap-based buffer overflow.

    -

    Remediation

    -

    Upgrade github.com/mattn/go-sqlite3 to version 1.14.18 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/dexidp/dex /usr/local/bin/dex -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-jose/go-jose/v3 -
    • - -
    • Introduced through: - - github.com/dexidp/dex@* and github.com/go-jose/go-jose/v3@v3.0.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/go-jose/go-jose/v3@v3.0.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Denial of Service (DoS) when decrypting JWE inputs. An attacker can cause a denial-of-service by providing a PBES2 encrypted JWE blob with a very large p2c value.

    -

    Details

    -

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.

    -

    Unlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.

    -

    One popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.

    -

    When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

    -

    Two common types of DoS vulnerabilities:

    -
      -
    • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

      -
    • -
    • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

      -
    • -
    -

    Remediation

    -

    Upgrade github.com/go-jose/go-jose/v3 to version 3.0.1 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Improper Authentication

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: The AES-SIV cipher implementation contains a bug that causes - it to ignore empty associated data entries which are unauthenticated as - a consequence.

    -

    Impact summary: Applications that use the AES-SIV algorithm and want to - authenticate empty data entries as associated data can be mislead by removing - adding or reordering such empty entries as these are ignored by the OpenSSL - implementation. We are currently unaware of any such applications.

    -

    The AES-SIV algorithm allows for authentication of multiple associated - data entries along with the encryption. To authenticate empty data the - application has to call EVP_EncryptUpdate() (or EVP_CipherUpdate()) with - NULL pointer as the output buffer and 0 as the input buffer length. - The AES-SIV implementation in OpenSSL just returns success for such a call - instead of performing the associated data authentication operation. - The empty data thus will not be authenticated.

    -

    As this issue does not affect non-empty associated data authentication and - we expect it to be rare for an application to use empty associated data - entries this is qualified as Low severity issue.

    -

    Remediation

    -

    Upgrade Alpine:3.18 openssl to version 3.1.1-r2 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Inefficient Regular Expression Complexity

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    -

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() - or EVP_PKEY_param_check() to check a DH key or 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.

    -

    The function DH_check() performs various checks on DH parameters. One of those - checks confirms that the modulus ('p' parameter) is not too large. Trying to use - a very large modulus is slow and OpenSSL will not normally use a modulus which - is over 10,000 bits in length.

    -

    However the DH_check() function checks numerous aspects of the key or parameters - that have been supplied. Some of those checks use the supplied modulus value - even if it has already been found to be too large.

    -

    An application that calls DH_check() and supplies a key or parameters obtained - from an untrusted source could be vulernable to a Denial of Service attack.

    -

    The function DH_check() is itself 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_ex() and - EVP_PKEY_param_check().

    -

    Also vulnerable are the OpenSSL dhparam 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 not affected by this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.18 openssl to version 3.1.1-r3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Excessive Iteration

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - openssl/libcrypto3 -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    -

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() - or EVP_PKEY_param_check() to check a DH key or 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.

    -

    The function DH_check() performs various checks on DH parameters. After fixing - CVE-2023-3446 it was discovered that a large q parameter value can also trigger - an overly long computation during some of these checks. A correct q value, - if present, cannot be larger than the modulus p parameter, thus it is - unnecessary to perform these checks if q is larger than p.

    -

    An application that calls DH_check() and supplies a key or parameters obtained - from an untrusted source could be vulnerable to a Denial of Service attack.

    -

    The function DH_check() is itself 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_ex() and - EVP_PKEY_param_check().

    -

    Also vulnerable are the OpenSSL dhparam 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 not affected by this issue.

    -

    Remediation

    -

    Upgrade Alpine:3.18 openssl to version 3.1.2-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|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: 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|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: 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|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: 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

    - - -
    - - - -
    -
    -

    Infinite loop

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.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.28.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - google.golang.org/protobuf/internal/encoding/json@v1.28.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - google.golang.org/protobuf/internal/encoding/json@v1.31.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Infinite loop via the protojson.Unmarshal function. An attacker can cause a denial of service condition by unmarshaling certain forms of invalid JSON.

    -

    Note:

    -

    This condition can occur when unmarshaling into a message which contains a google.protobuf.Any value, or when the UnmarshalOptions.DiscardUnknown option is set.

    -

    Remediation

    -

    Upgrade google.golang.org/protobuf/internal/encoding/json to version 1.33.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Stack-based Buffer Overflow

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.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.28.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - google.golang.org/protobuf/encoding/protojson@v1.28.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - google.golang.org/protobuf/encoding/protojson@v1.31.0 - - - -
    • -
    - -
    - -
    - -

    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.37.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.28.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - google.golang.org/protobuf/encoding/protojson@v1.28.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - google.golang.org/protobuf/encoding/protojson@v1.31.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Infinite loop via the protojson.Unmarshal function. An attacker can cause a denial of service condition by unmarshaling certain forms of invalid JSON.

    -

    Note:

    -

    This condition can occur when unmarshaling into a message which contains a google.protobuf.Any value, or when the UnmarshalOptions.DiscardUnknown option is set.

    -

    Remediation

    -

    Upgrade google.golang.org/protobuf/encoding/protojson to version 1.33.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Allocation of Resources Without Limits or Throttling

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/http2 -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.7.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - golang.org/x/net/http2@v0.7.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - golang.org/x/net/http2@v0.11.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    -

    Affected versions of this package are vulnerable to Allocation of Resources Without Limits or Throttling when MaxConcurrentStreams handler goroutines running. A a handler is started until one of the existing handlers exits.

    -

    Note:

    -

    This issue is related to CVE-2023-44487

    -

    Remediation

    -

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Cross-site Scripting (XSS)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.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.11.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - - golang.org/x/net/html@v0.11.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 Cross-site Scripting (XSS) in the render1() function in render.go. Text nodes not in the HTML namespace are incorrectly literally rendered, causing text which should be escaped to not be.

    -

    Details

    -

    A cross-site scripting attack occurs when the attacker tricks a legitimate web-based application or site to accept a request as originating from a trusted source.

    -

    This is done by escaping the context of the web application; the web application then delivers that data to its users along with other trusted dynamic content, without validating it. The browser unknowingly executes malicious script on the client side (through client-side languages; usually JavaScript or HTML) in order to perform actions that are otherwise typically blocked by the browser’s Same Origin Policy.

    -

    Injecting malicious code is the most prevalent manner by which XSS is exploited; for this reason, escaping characters in order to prevent this manipulation is the top method for securing code against this vulnerability.

    -

    Escaping means that the application is coded to mark key characters, and particularly key characters included in user input, to prevent those characters from being interpreted in a dangerous context. For example, in HTML, < can be coded as &lt; and > can be coded as &gt; in order to be interpreted and displayed as themselves in text, while within the code itself, they are used for HTML tags. If malicious content is injected into an application that escapes special characters and that malicious content uses < and > as HTML tags, those characters are nonetheless not interpreted as HTML tags by the browser if they’ve been correctly escaped in the application code and in this way the attempted attack is diverted.

    -

    The most prominent use of XSS is to steal cookies (source: OWASP HttpOnly) and hijack user sessions, but XSS exploits have been used to expose sensitive information, enable access to privileged services and functionality and deliver malware.

    -

    Types of attacks

    -

    There are a few methods by which XSS can be manipulated:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeOriginDescription
    StoredServerThe malicious code is inserted in the application (usually as a link) by the attacker. The code is activated every time a user clicks the link.
    ReflectedServerThe attacker delivers a malicious link externally from the vulnerable web site application to a user. When clicked, malicious code is sent to the vulnerable web site, which reflects the attack back to the user’s browser.
    DOM-basedClientThe attacker forces the user’s browser to render a malicious page. The data in the page itself delivers the cross-site scripting data.
    MutatedThe attacker injects code that appears safe, but is then rewritten and modified by the browser, while parsing the markup. An example is rebalancing unclosed quotation marks or even adding quotation marks to unquoted parameters.
    -

    Affected environments

    -

    The following environments are susceptible to an XSS attack:

    -
      -
    • Web servers
    • -
    • Application servers
    • -
    • Web application environments
    • -
    -

    How to prevent

    -

    This section describes the top best practices designed to specifically protect your code:

    -
      -
    • Sanitize data input in an HTTP request before reflecting it back, ensuring all data is validated, filtered or escaped before echoing anything back to the user, such as the values of query parameters during searches.
    • -
    • Convert special characters such as ?, &, /, <, > and spaces to their respective HTML or URL encoded equivalents.
    • -
    • Give users the option to disable client-side scripts.
    • -
    • Redirect invalid requests.
    • -
    • Detect simultaneous logins, including those from two separate IP addresses, and invalidate those sessions.
    • -
    • Use and enforce a Content Security Policy (source: Wikipedia) to disable any features that might be manipulated for an XSS attack.
    • -
    • Read the documentation for any of the libraries referenced in your code to understand which elements allow for embedded HTML.
    • -
    -

    Remediation

    -

    Upgrade golang.org/x/net/html to version 0.13.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Authentication Bypass by Capture-replay

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/crypto/ssh -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and golang.org/x/crypto/ssh@v0.0.0-20220525230936-793ad666bf5e - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - golang.org/x/crypto/ssh@v0.0.0-20220525230936-793ad666bf5e - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/crypto/ssh is a SSH client and server

    -

    Affected versions of this package are vulnerable to Authentication Bypass by Capture-replay during the establishment of the secure channel. An attacker can manipulate handshake sequence numbers to delete messages sent immediately after the channel is established.

    -

    Note:

    -
      -
    1. Sequence numbers are only validated once the channel is established and arbitrary messages are allowed during the handshake, allowing them to manipulate the sequence numbers.

      -
    2. -
    3. The potential consequences of the general Terrapin attack are dependent on the messages exchanged after the handshake concludes. If you are using a custom SSH service and do not resort to the authentication protocol, you should check that dropping the first few messages of a connection does not yield security risks.

      -
    4. -
    -

    Impact:

    -

    While cryptographically novel, there is no discernable impact on the integrity of SSH traffic beyond giving the attacker the ability to delete the message that enables some features related to keystroke timing obfuscation. To successfully carry out the exploitation, the connection needs to be protected using either the ChaCha20-Poly1305 or CBC with Encrypt-then-MAC encryption methods. The attacker must also be able to intercept and modify the connection's traffic.

    -

    Workaround

    -

    Temporarily disable the affected chacha20-poly1305@openssh.com encryption and *-etm@openssh.com MAC algorithms in the affected configuration, and use unaffected algorithms like AES-GCM instead.

    -

    Remediation

    -

    Upgrade golang.org/x/crypto/ssh to version 0.17.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/vault/sdk/helper/certutil -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/compressutil@v0.5.0 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/consts@v0.5.0 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/jsonutil@v0.5.0 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/pluginutil@v0.5.0 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/helper/strutil@v0.5.0 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/logical@v0.5.0 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/physical@v0.5.0 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/sdk/physical/inmem@v0.5.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/vault/api -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/api@v1.6.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/vault/api@v1.6.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/serf/coordinate -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/serf/coordinate@v0.9.7 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/serf/coordinate@v0.9.7 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/dexidp/dex /usr/local/bin/dex -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/hcl/v2 -
    • - -
    • Introduced through: - - github.com/dexidp/dex@* and github.com/hashicorp/hcl/v2@v2.13.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/hashicorp/hcl/v2@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/hashicorp/hcl/v2/ext/customdecode@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/hashicorp/hcl/v2/ext/tryfunc@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/hashicorp/hcl/v2/gohcl@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/hashicorp/hcl/v2/hclparse@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/hashicorp/hcl/v2/hclsyntax@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/hashicorp/hcl/v2/hclwrite@v2.13.0 - - - -
    • -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/hashicorp/hcl/v2/json@v2.13.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/hcl -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/hcl@v1.0.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/hcl@v1.0.0 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/hcl/hcl/parser@v1.0.0 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/hcl/hcl/strconv@v1.0.0 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/hcl/hcl/token@v1.0.0 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/hcl/json/parser@v1.0.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/golang-lru/simplelru -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/golang-lru/simplelru@v0.5.4 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/golang-lru/simplelru@v0.5.4 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-version -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-version@v1.5.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-version@v1.5.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-sockaddr -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-sockaddr@v1.0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-sockaddr@v1.0.2 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-sockaddr/template@v1.0.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-secure-stdlib/strutil -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-secure-stdlib/parseutil -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-secure-stdlib/mlock -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-rootcerts -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-rootcerts@v1.0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-rootcerts@v1.0.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-retryablehttp -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-retryablehttp@v0.7.1 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-plugin -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-plugin@v1.4.4 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-plugin@v1.4.4 - - - -
    • -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-plugin/internal/plugin@v1.4.4 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-immutable-radix -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-immutable-radix@v1.3.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-immutable-radix@v1.3.1 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-cleanhttp -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-cleanhttp@v0.5.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/go-cleanhttp@v0.5.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/errwrap -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/errwrap@v1.1.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/errwrap@v1.1.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/consul/api -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/consul/api@v1.13.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/hashicorp/consul/api@v1.13.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/gosimple/slug -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/gosimple/slug@v1.12.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/gosimple/slug@v1.12.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/dexidp/dex /usr/local/bin/dex -
    • -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/go-sql-driver/mysql -
    • - -
    • Introduced through: - - github.com/dexidp/dex@* and github.com/go-sql-driver/mysql@v1.7.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/go-sql-driver/mysql@v1.7.1 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    Improper Handling of Highly Compressed Data (Data Amplification)

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/dexidp/dex /usr/local/bin/dex -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-jose/go-jose/v3 -
    • - -
    • Introduced through: - - github.com/dexidp/dex@* and github.com/go-jose/go-jose/v3@v3.0.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/dexidp/dex@* - - github.com/go-jose/go-jose/v3@v3.0.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    Affected versions of this package are vulnerable to Improper Handling of Highly Compressed Data (Data Amplification). An attacker could send a JWE containing compressed data that, when decompressed by Decrypt or DecryptMulti, would use large amounts of memory and CPU.

    -

    Remediation

    -

    Upgrade github.com/go-jose/go-jose/v3 to version 3.0.3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Uncontrolled Resource Consumption ('Resource Exhaustion')

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Manifest file: ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 /usr/local/bin/gomplate -
    • -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - github.com/go-git/go-git/v5/plumbing -
    • - -
    • Introduced through: - - github.com/hairyhenderson/gomplate/v3@* and github.com/go-git/go-git/v5/plumbing@v5.4.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/hairyhenderson/gomplate/v3@* - - github.com/go-git/go-git/v5/plumbing@v5.4.2 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    github.com/go-git/go-git/v5/plumbing is a highly extensible git implementation library written in pure Go.

    -

    Affected versions of this package are vulnerable to Uncontrolled Resource Consumption ('Resource Exhaustion') via specially crafted responses from a Git server, which triggers resource exhaustion in clients.

    -

    Note - This is only exploitable if the client is not using the in-memory filesystem supported by the library.

    -

    Workaround

    -

    In cases where a bump to the latest version of go-git is not possible, we recommend limiting its use to only trust-worthy Git servers.

    -

    Details

    -

    Denial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.

    -

    Unlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.

    -

    One popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.

    -

    When it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.

    -

    Two common types of DoS vulnerabilities:

    -
      -
    • High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, commons-fileupload:commons-fileupload.

      -
    • -
    • Crash - An attacker sending crafted requests that could cause the system to crash. For Example, npm ws package

      -
    • -
    -

    Remediation

    -

    Upgrade github.com/go-git/go-git/v5/plumbing to version 5.11.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Out-of-bounds Write

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: alpine:3.18 -
    • -
    • - Vulnerable module: - - busybox/busybox -
    • - -
    • Introduced through: - - docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/busybox@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r0 - - busybox/busybox@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/busybox-binsh@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - - -
    • -
    - -
    - -
    - -

    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|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/busybox@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r0 - - busybox/busybox@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/busybox-binsh@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - - -
    • -
    - -
    - -
    - -

    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|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/busybox@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r0 - - busybox/busybox@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/busybox-binsh@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - - -
    • -
    - -
    - -
    - -

    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|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/busybox@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r0 - - busybox/busybox@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/busybox-binsh@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - alpine-baselayout/alpine-baselayout@3.4.3-r1 - - busybox/busybox-binsh@1.36.1-r0 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - - -
    • -
    - -
    - -
    - -

    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|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: 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|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: 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|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - openssl/libcrypto3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - apk-tools/apk-tools@2.14.0-r2 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    • - Introduced through: - docker-image|ghcr.io/dexidp/dex@v2.37.0 - - busybox/ssl_client@1.36.1-r0 - - openssl/libssl3@3.1.1-r1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. - See How to fix? for Alpine:3.18 relevant fixed versions and status.

    -

    Issue summary: 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

    - - -
    - - - -
    -
    -
    -
    - - - diff --git a/docs/user-guide/annotations-and-labels.md b/docs/user-guide/annotations-and-labels.md index 032824c8708f3..2b4e9968dcfb4 100644 --- a/docs/user-guide/annotations-and-labels.md +++ b/docs/user-guide/annotations-and-labels.md @@ -14,6 +14,7 @@ | argocd.argoproj.io/sync-options | any | [see sync options docs](sync-options.md) | Provides a variety of settings to determine how an Application's resources are synced. | | argocd.argoproj.io/sync-wave | any | [see sync waves docs](sync-waves.md) | | | argocd.argoproj.io/tracking-id | any | any | Used by Argo CD to track resources it manages. See [resource tracking docs](resource_tracking.md) for details. | +| argocd.argoproj.io/ignore-resource-updates | any | `"true"`, `false` | Used by Argo CD to ignore resource updates. See [reconcile docs](..%2Foperator-manual%2Freconcile.md)reconcile_docs for details. | | link.argocd.argoproj.io/{some link name} | any | An http(s) URL | Adds a link to the Argo CD UI for the resource. See [external URL docs](external-url.md) for details. | | pref.argocd.argoproj.io/default-pod-sort | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default grouping mechanism. | | pref.argocd.argoproj.io/default-view | Application | [see UI customization docs](../operator-manual/ui-customization.md) | Sets the Application's default view mode (e.g. "tree" or "list") | diff --git a/docs/user-guide/build-environment.md b/docs/user-guide/build-environment.md index 8e2448f4f9e7f..52fc8b1d03a5a 100644 --- a/docs/user-guide/build-environment.md +++ b/docs/user-guide/build-environment.md @@ -8,6 +8,7 @@ | `ARGOCD_APP_NAMESPACE` | The destination namespace of the application. | | `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`. | | `ARGOCD_APP_SOURCE_PATH` | The path of the app within the source repo. | | `ARGOCD_APP_SOURCE_REPO_URL` | The source repo URL. | | `ARGOCD_APP_SOURCE_TARGET_REVISION` | The target revision from the spec, e.g. `master`. | diff --git a/docs/user-guide/commands/argocd.md b/docs/user-guide/commands/argocd.md index dc5cd36297760..0514eb9447103 100644 --- a/docs/user-guide/commands/argocd.md +++ b/docs/user-guide/commands/argocd.md @@ -11,7 +11,8 @@ argocd [flags] ### Options ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_account.md b/docs/user-guide/commands/argocd_account.md index 88d483ffac68e..25eaa7d214542 100644 --- a/docs/user-guide/commands/argocd_account.md +++ b/docs/user-guide/commands/argocd_account.md @@ -52,7 +52,8 @@ argocd account [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_account_bcrypt.md b/docs/user-guide/commands/argocd_account_bcrypt.md index 6bc282cfaab1e..d4bde8b933424 100644 --- a/docs/user-guide/commands/argocd_account_bcrypt.md +++ b/docs/user-guide/commands/argocd_account_bcrypt.md @@ -25,7 +25,8 @@ argocd account bcrypt --password YOUR_PASSWORD ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_account_can-i.md b/docs/user-guide/commands/argocd_account_can-i.md index 6e6cb2bea524b..f6fd5a01880a8 100644 --- a/docs/user-guide/commands/argocd_account_can-i.md +++ b/docs/user-guide/commands/argocd_account_can-i.md @@ -35,7 +35,8 @@ Resources: [clusters projects applications applicationsets repositories certific ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_account_delete-token.md b/docs/user-guide/commands/argocd_account_delete-token.md index 6ef4cf11499fe..25d5b9a37d17a 100644 --- a/docs/user-guide/commands/argocd_account_delete-token.md +++ b/docs/user-guide/commands/argocd_account_delete-token.md @@ -28,7 +28,8 @@ argocd account delete-token --account ID ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_account_generate-token.md b/docs/user-guide/commands/argocd_account_generate-token.md index 0d21d36ad32ff..e149548374894 100644 --- a/docs/user-guide/commands/argocd_account_generate-token.md +++ b/docs/user-guide/commands/argocd_account_generate-token.md @@ -30,7 +30,8 @@ argocd account generate-token --account ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 66603a52b2628..577f103b48c0d 100644 --- a/docs/user-guide/commands/argocd_account_get-user-info.md +++ b/docs/user-guide/commands/argocd_account_get-user-info.md @@ -28,7 +28,8 @@ argocd account get-user-info [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_account_get.md b/docs/user-guide/commands/argocd_account_get.md index fbe0ef6027141..70d181e702a17 100644 --- a/docs/user-guide/commands/argocd_account_get.md +++ b/docs/user-guide/commands/argocd_account_get.md @@ -29,7 +29,8 @@ argocd account get --account ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_account_list.md b/docs/user-guide/commands/argocd_account_list.md index 0082c0260496c..6af9d8a6d0ee0 100644 --- a/docs/user-guide/commands/argocd_account_list.md +++ b/docs/user-guide/commands/argocd_account_list.md @@ -24,7 +24,8 @@ argocd account list ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_account_update-password.md b/docs/user-guide/commands/argocd_account_update-password.md index ed84a7da00617..3a31b6ee06274 100644 --- a/docs/user-guide/commands/argocd_account_update-password.md +++ b/docs/user-guide/commands/argocd_account_update-password.md @@ -40,7 +40,8 @@ argocd account update-password [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin.md b/docs/user-guide/commands/argocd_admin.md index 0aa338f1570e2..ec1de309c135b 100644 --- a/docs/user-guide/commands/argocd_admin.md +++ b/docs/user-guide/commands/argocd_admin.md @@ -30,7 +30,8 @@ $ argocd admin initial-password reset ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_app.md b/docs/user-guide/commands/argocd_admin_app.md index 58e0f50f25846..12fa400c8c94d 100644 --- a/docs/user-guide/commands/argocd_admin_app.md +++ b/docs/user-guide/commands/argocd_admin_app.md @@ -32,7 +32,8 @@ argocd admin app get-reconcile-results APPNAME ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 39190e23349fc..c77a3d3db57e0 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 @@ -17,7 +17,8 @@ argocd admin app diff-reconcile-results PATH1 PATH2 [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 ed9f36a4268c0..2826917d4765c 100644 --- a/docs/user-guide/commands/argocd_admin_app_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_app_generate-spec.md @@ -47,7 +47,10 @@ argocd admin app generate-spec APPNAME [flags] --directory-recurse Recurse directory --env string Application environment to monitor -f, --file string Filename or URL to Kubernetes manifests for the app + --helm-api-versions stringArray Helm api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster --helm-chart string Helm Chart name + --helm-kube-version string Helm kube-version to use when running helm template. If not set, use the kube version from the destination cluster + --helm-namespace string Helm namespace to use when running helm template. If not set, use app.spec.destination.namespace --helm-pass-credentials Pass credentials to all domain --helm-set stringArray Helm set values on the command line (can be repeated to set several values: --helm-set key1=val1 --helm-set key2=val2) --helm-set-file stringArray Helm set values from respective files specified via the command line (can be repeated to set several values: --helm-set-file key1=path1 --helm-set-file key2=path2) @@ -62,11 +65,13 @@ argocd admin app generate-spec APPNAME [flags] --jsonnet-libs stringArray Additional jsonnet libs (prefixed by repoRoot) --jsonnet-tla-code stringArray Jsonnet top level code arguments --jsonnet-tla-str stringArray Jsonnet top level string arguments + --kustomize-api-versions stringArray api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster. Only applicable when Helm is enabled for Kustomize builds --kustomize-common-annotation stringArray Set common labels in Kustomize --kustomize-common-label stringArray Set common labels in Kustomize --kustomize-force-common-annotation Force common annotations in Kustomize --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-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) @@ -86,6 +91,7 @@ argocd admin app generate-spec APPNAME [flags] --revision string The tracking source branch, tag, commit or Helm chart version the application will sync to --revision-history-limit int How many items to keep in revision history (default 10) --self-heal Set self healing when sync is automated + --set-finalizer Sets deletion finalizer on the application, application resources will be cascaded on deletion --sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false` --sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic)) --sync-retry-backoff-duration duration Sync retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s) @@ -100,7 +106,8 @@ argocd admin app generate-spec APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 4e696bd994903..a985a7d0e8484 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 @@ -43,7 +43,8 @@ argocd admin app get-reconcile-results PATH [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_cluster.md b/docs/user-guide/commands/argocd_admin_cluster.md index 544c0de08959c..7abe6fd1a42f8 100644 --- a/docs/user-guide/commands/argocd_admin_cluster.md +++ b/docs/user-guide/commands/argocd_admin_cluster.md @@ -31,7 +31,8 @@ argocd admin cluster namespaces my-cluster ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 79f88233fab32..01a0fe6ff3a07 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_cluster_generate-spec.md @@ -40,7 +40,8 @@ argocd admin cluster generate-spec CONTEXT [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md index 38f61ce5cd8a2..37092a4ef303a 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md +++ b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md @@ -54,7 +54,8 @@ argocd admin cluster kubeconfig https://cluster-api-url:6443 /path/to/output/kub ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_cluster_namespaces.md b/docs/user-guide/commands/argocd_admin_cluster_namespaces.md index fee5c7679e159..791f61ec1c1f0 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_namespaces.md +++ b/docs/user-guide/commands/argocd_admin_cluster_namespaces.md @@ -37,7 +37,8 @@ argocd admin cluster namespaces [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 fcbebd7612337..57b776ff1cc3d 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 @@ -38,7 +38,8 @@ argocd admin cluster namespaces disable-namespaced-mode PATTERN [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 762a652d7ab12..cfbfd2fb891ab 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 @@ -40,7 +40,8 @@ argocd admin cluster namespaces enable-namespaced-mode PATTERN [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_cluster_shards.md b/docs/user-guide/commands/argocd_admin_cluster_shards.md index 44efa4392b9ac..b624c8dbe6c49 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_shards.md +++ b/docs/user-guide/commands/argocd_admin_cluster_shards.md @@ -53,7 +53,8 @@ argocd admin cluster shards [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_cluster_stats.md b/docs/user-guide/commands/argocd_admin_cluster_stats.md index 18aa583f01305..b894959c1c0c3 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_stats.md +++ b/docs/user-guide/commands/argocd_admin_cluster_stats.md @@ -67,7 +67,8 @@ argocd admin cluster stats target-cluster ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_dashboard.md b/docs/user-guide/commands/argocd_admin_dashboard.md index 71e11a173906a..ecfee6be3a242 100644 --- a/docs/user-guide/commands/argocd_admin_dashboard.md +++ b/docs/user-guide/commands/argocd_admin_dashboard.md @@ -54,7 +54,8 @@ $ argocd admin dashboard --redis-compress gzip ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_export.md b/docs/user-guide/commands/argocd_admin_export.md index d168fe5450a74..f4fe070f2d1f5 100644 --- a/docs/user-guide/commands/argocd_admin_export.md +++ b/docs/user-guide/commands/argocd_admin_export.md @@ -11,34 +11,37 @@ argocd admin export [flags] ### Options ``` - --as string Username to impersonate for the operation - --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. - --as-uid string UID to impersonate for the operation - --certificate-authority string Path to a cert file for the certificate authority - --client-certificate string Path to a client certificate file for TLS - --client-key string Path to a client key file for TLS - --cluster string The name of the kubeconfig cluster to use - --context string The name of the kubeconfig context to use - --disable-compression If true, opt-out of response compression for all requests to the server - -h, --help help for export - --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 - -o, --out string Output to the specified file instead of stdout (default "-") - --password string Password for basic authentication to the API server - --proxy-url string If provided, this URL will be used to connect via proxy - --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") - --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 - --user string The name of the kubeconfig user to use - --username string Username for basic authentication to the API server + --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 + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server + -h, --help help for export + --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 + -o, --out string Output to the specified file instead of stdout (default "-") + --password string Password for basic authentication to the API server + --proxy-url string If provided, this URL will be used to connect via proxy + --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --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 + --user string The name of the kubeconfig user to use + --username string Username for basic authentication to the API server ``` ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_import.md b/docs/user-guide/commands/argocd_admin_import.md index dc8a4b2dbf947..b373184a3796d 100644 --- a/docs/user-guide/commands/argocd_admin_import.md +++ b/docs/user-guide/commands/argocd_admin_import.md @@ -11,37 +11,41 @@ argocd admin import SOURCE [flags] ### Options ``` - --as string Username to impersonate for the operation - --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. - --as-uid string UID to impersonate for the operation - --certificate-authority string Path to a cert file for the certificate authority - --client-certificate string Path to a client certificate file for TLS - --client-key string Path to a client key file for TLS - --cluster string The name of the kubeconfig cluster to use - --context string The name of the kubeconfig context to use - --disable-compression If true, opt-out of response compression for all requests to the server - --dry-run Print what will be performed - -h, --help help for import - --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure - --kubeconfig string Path to a kube config. Only required if out-of-cluster - -n, --namespace string If present, the namespace scope for this CLI request - --password string Password for basic authentication to the API server - --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 - --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 - --user string The name of the kubeconfig user to use - --username string Username for basic authentication to the API server - --verbose Verbose output (versus only changed output) + --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 + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server + --dry-run Print what will be performed + -h, --help help for import + --ignore-tracking Do not update the tracking annotation if the resource is already tracked + --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kubeconfig string Path to a kube config. Only required if out-of-cluster + -n, --namespace string If present, the namespace scope for this CLI request + --password string Password for basic authentication to the API server + --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 + --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 + --user string The name of the kubeconfig user to use + --username string Username for basic authentication to the API server + --verbose Verbose output (versus only changed output) ``` ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_initial-password.md b/docs/user-guide/commands/argocd_admin_initial-password.md index dbc44561debdc..92feb9e8ad9f5 100644 --- a/docs/user-guide/commands/argocd_admin_initial-password.md +++ b/docs/user-guide/commands/argocd_admin_initial-password.md @@ -37,7 +37,8 @@ argocd admin initial-password [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_notifications.md b/docs/user-guide/commands/argocd_admin_notifications.md index 87429217f99e9..58f2b832bebbb 100644 --- a/docs/user-guide/commands/argocd_admin_notifications.md +++ b/docs/user-guide/commands/argocd_admin_notifications.md @@ -42,7 +42,8 @@ argocd admin notifications [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_notifications_template.md b/docs/user-guide/commands/argocd_admin_notifications_template.md index 75d5700aaac04..2a93df1a9a9f1 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template.md @@ -17,13 +17,14 @@ argocd admin notifications template [flags] ### Options inherited from parent commands ``` + --argocd-context string The name of the Argo-CD server context to use --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") --argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server --argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file 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 214a8e5cd442b..e48bb8271d4db 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template_get.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template_get.md @@ -29,13 +29,14 @@ argocd admin notifications template get app-sync-succeeded -o=yaml ### Options inherited from parent commands ``` + --argocd-context string The name of the Argo-CD server context to use --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") --argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server --argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file 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 4f94a9d960476..cfcb6bc08db89 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template_notify.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template_notify.md @@ -30,13 +30,14 @@ argocd admin notifications template notify app-sync-succeeded guestbook ### Options inherited from parent commands ``` + --argocd-context string The name of the Argo-CD server context to use --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") --argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server --argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file diff --git a/docs/user-guide/commands/argocd_admin_notifications_trigger.md b/docs/user-guide/commands/argocd_admin_notifications_trigger.md index d6ff9e53ab235..74b8460151e2e 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger.md @@ -17,13 +17,14 @@ argocd admin notifications trigger [flags] ### Options inherited from parent commands ``` + --argocd-context string The name of the Argo-CD server context to use --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") --argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server --argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file 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 acd2ab5af9553..6d3f7aa9b3200 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md @@ -29,13 +29,14 @@ argocd admin notifications trigger get on-sync-failed -o=yaml ### Options inherited from parent commands ``` + --argocd-context string The name of the Argo-CD server context to use --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") --argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server --argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file 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 f8bebb2937937..6b27a7a54d27f 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md @@ -29,13 +29,14 @@ argocd admin notifications trigger run on-sync-status-unknown ./sample-app.yaml ### Options inherited from parent commands ``` + --argocd-context string The name of the Argo-CD server context to use --argocd-repo-server string Argo CD repo server address (default "argocd-repo-server:8081") --argocd-repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server --argocd-repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file diff --git a/docs/user-guide/commands/argocd_admin_proj.md b/docs/user-guide/commands/argocd_admin_proj.md index b22a2513b7e4d..e4f11de54cab1 100644 --- a/docs/user-guide/commands/argocd_admin_proj.md +++ b/docs/user-guide/commands/argocd_admin_proj.md @@ -17,7 +17,8 @@ argocd admin proj [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 83dc00a6096b4..753d0fa68a704 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 @@ -45,7 +45,8 @@ argocd admin proj generate-allow-list /path/to/clusterrole.yaml my-project ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 b4f544367813d..c94eba4365ef8 100644 --- a/docs/user-guide/commands/argocd_admin_proj_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_proj_generate-spec.md @@ -44,7 +44,8 @@ argocd admin proj generate-spec PROJECT [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 c1c4823077e01..09dc8994d2a7f 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 @@ -53,7 +53,8 @@ argocd admin proj update-role-policy PROJECT_GLOB MODIFICATION ACTION [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 85e56195758dd..de2653e962f5e 100644 --- a/docs/user-guide/commands/argocd_admin_redis-initial-password.md +++ b/docs/user-guide/commands/argocd_admin_redis-initial-password.md @@ -37,7 +37,8 @@ argocd admin redis-initial-password [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_repo.md b/docs/user-guide/commands/argocd_admin_repo.md index 411cf558bac5b..33944fda2d87c 100644 --- a/docs/user-guide/commands/argocd_admin_repo.md +++ b/docs/user-guide/commands/argocd_admin_repo.md @@ -17,7 +17,8 @@ argocd admin repo [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 10c722913258b..3616e057c53c7 100644 --- a/docs/user-guide/commands/argocd_admin_repo_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_repo_generate-spec.md @@ -50,6 +50,7 @@ argocd admin repo generate-spec REPOURL [flags] --insecure-ignore-host-key disables SSH strict host key checking (deprecated, use --insecure-skip-server-verification instead) --insecure-skip-server-verification disables server certificate and host key checks --name string name of the repository, mandatory for repositories of type helm + --no-proxy string don't access these targets via proxy -o, --output string Output format. One of: json|yaml (default "yaml") --password string password to the repository --project string project of the repository @@ -64,7 +65,8 @@ argocd admin repo generate-spec REPOURL [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_settings.md b/docs/user-guide/commands/argocd_admin_settings.md index 3c631cf8f123b..d2726048afc42 100644 --- a/docs/user-guide/commands/argocd_admin_settings.md +++ b/docs/user-guide/commands/argocd_admin_settings.md @@ -40,7 +40,8 @@ argocd admin settings [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_admin_settings_rbac.md b/docs/user-guide/commands/argocd_admin_settings_rbac.md index 043c39979a98a..5cb18ba1a0580 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac.md @@ -18,11 +18,12 @@ argocd admin settings rbac [flags] ``` --argocd-cm-path string Path to local argocd-cm.yaml file + --argocd-context string The name of the Argo-CD server context to use --argocd-secret-path string Path to local argocd-secret.yaml file --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file 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 f14092785facf..5697d68530c4d 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac_can.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac_can.md @@ -73,8 +73,9 @@ argocd admin settings rbac can someuser create application 'default/app' --defau ``` --argocd-cm-path string Path to local argocd-cm.yaml file + --argocd-context string The name of the Argo-CD server context to use --argocd-secret-path string Path to local argocd-secret.yaml file - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 4be305e40a33c..6e5721e705fb1 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md @@ -65,8 +65,9 @@ argocd admin settings rbac validate --namespace argocd ``` --argocd-cm-path string Path to local argocd-cm.yaml file + --argocd-context string The name of the Argo-CD server context to use --argocd-secret-path string Path to local argocd-secret.yaml file - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 eeec6bcf5f63a..095ae66f6fb39 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md @@ -18,11 +18,12 @@ argocd admin settings resource-overrides [flags] ``` --argocd-cm-path string Path to local argocd-cm.yaml file + --argocd-context string The name of the Argo-CD server context to use --argocd-secret-path string Path to local argocd-secret.yaml file --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file 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 1e5cc49335cc5..8d1afb6e81b42 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 @@ -29,11 +29,12 @@ argocd admin settings resource-overrides health ./deploy.yaml --argocd-cm-path . ``` --argocd-cm-path string Path to local argocd-cm.yaml file + --argocd-context string The name of the Argo-CD server context to use --argocd-secret-path string Path to local argocd-secret.yaml file --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file 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 752b3a64c59c7..c10989511069e 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 @@ -29,11 +29,12 @@ argocd admin settings resource-overrides ignore-differences ./deploy.yaml --argo ``` --argocd-cm-path string Path to local argocd-cm.yaml file + --argocd-context string The name of the Argo-CD server context to use --argocd-secret-path string Path to local argocd-secret.yaml file --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file 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 0eeefab2713ea..f562e3557ccfd 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 @@ -30,11 +30,12 @@ argocd admin settings resource-overrides ignore-resource-updates ./deploy.yaml - ``` --argocd-cm-path string Path to local argocd-cm.yaml file + --argocd-context string The name of the Argo-CD server context to use --argocd-secret-path string Path to local argocd-secret.yaml file --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file 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 57f60f3d726f5..144a7d0b9d92b 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 @@ -29,11 +29,12 @@ argocd admin settings resource-overrides action list /tmp/deploy.yaml --argocd-c ``` --argocd-cm-path string Path to local argocd-cm.yaml file + --argocd-context string The name of the Argo-CD server context to use --argocd-secret-path string Path to local argocd-secret.yaml file --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file 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 f7ce62d4559fe..99f5c903d11c2 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 @@ -29,11 +29,12 @@ argocd admin settings resource-overrides action run /tmp/deploy.yaml restart --a ``` --argocd-cm-path string Path to local argocd-cm.yaml file + --argocd-context string The name of the Argo-CD server context to use --argocd-secret-path string Path to local argocd-secret.yaml file --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file diff --git a/docs/user-guide/commands/argocd_admin_settings_validate.md b/docs/user-guide/commands/argocd_admin_settings_validate.md index 8e40a403441b5..1565397fb5117 100644 --- a/docs/user-guide/commands/argocd_admin_settings_validate.md +++ b/docs/user-guide/commands/argocd_admin_settings_validate.md @@ -34,11 +34,12 @@ argocd admin settings validate --group accounts --group plugins --load-cluster-s ``` --argocd-cm-path string Path to local argocd-cm.yaml file + --argocd-context string The name of the Argo-CD server context to use --argocd-secret-path string Path to local argocd-secret.yaml file --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 - --auth-token string Authentication token + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file diff --git a/docs/user-guide/commands/argocd_app.md b/docs/user-guide/commands/argocd_app.md index a3840231aff7a..ea5bf74d6a56a 100644 --- a/docs/user-guide/commands/argocd_app.md +++ b/docs/user-guide/commands/argocd_app.md @@ -49,7 +49,8 @@ argocd app [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_actions.md b/docs/user-guide/commands/argocd_app_actions.md index af336f1767b23..21df6d1f1564e 100644 --- a/docs/user-guide/commands/argocd_app_actions.md +++ b/docs/user-guide/commands/argocd_app_actions.md @@ -27,7 +27,8 @@ argocd app actions [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_actions_list.md b/docs/user-guide/commands/argocd_app_actions_list.md index 2d1f78524df50..513042b746278 100644 --- a/docs/user-guide/commands/argocd_app_actions_list.md +++ b/docs/user-guide/commands/argocd_app_actions_list.md @@ -29,7 +29,8 @@ argocd app actions list APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_actions_run.md b/docs/user-guide/commands/argocd_app_actions_run.md index db8e29fc197b9..8dc105243793b 100644 --- a/docs/user-guide/commands/argocd_app_actions_run.md +++ b/docs/user-guide/commands/argocd_app_actions_run.md @@ -29,7 +29,8 @@ argocd app actions run APPNAME ACTION [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_add-source.md b/docs/user-guide/commands/argocd_app_add-source.md index ced4bc7b577ca..b6bc3ae3de6c2 100644 --- a/docs/user-guide/commands/argocd_app_add-source.md +++ b/docs/user-guide/commands/argocd_app_add-source.md @@ -29,7 +29,10 @@ argocd app add-source APPNAME [flags] --directory-include string Set glob expression used to include files from application source path --directory-recurse Recurse directory --env string Application environment to monitor + --helm-api-versions stringArray Helm api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster --helm-chart string Helm Chart name + --helm-kube-version string Helm kube-version to use when running helm template. If not set, use the kube version from the destination cluster + --helm-namespace string Helm namespace to use when running helm template. If not set, use app.spec.destination.namespace --helm-pass-credentials Pass credentials to all domain --helm-set stringArray Helm set values on the command line (can be repeated to set several values: --helm-set key1=val1 --helm-set key2=val2) --helm-set-file stringArray Helm set values from respective files specified via the command line (can be repeated to set several values: --helm-set-file key1=path1 --helm-set-file key2=path2) @@ -43,11 +46,13 @@ argocd app add-source APPNAME [flags] --jsonnet-libs stringArray Additional jsonnet libs (prefixed by repoRoot) --jsonnet-tla-code stringArray Jsonnet top level code arguments --jsonnet-tla-str stringArray Jsonnet top level string arguments + --kustomize-api-versions stringArray api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster. Only applicable when Helm is enabled for Kustomize builds --kustomize-common-annotation stringArray Set common labels in Kustomize --kustomize-common-label stringArray Set common labels in Kustomize --kustomize-force-common-annotation Force common annotations in Kustomize --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-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) @@ -78,7 +83,8 @@ argocd app add-source APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_create.md b/docs/user-guide/commands/argocd_app_create.md index fb147b8e4aa9f..662ee0b92644a 100644 --- a/docs/user-guide/commands/argocd_app_create.md +++ b/docs/user-guide/commands/argocd_app_create.md @@ -49,7 +49,10 @@ argocd app create APPNAME [flags] --directory-recurse Recurse directory --env string Application environment to monitor -f, --file string Filename or URL to Kubernetes manifests for the app + --helm-api-versions stringArray Helm api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster --helm-chart string Helm Chart name + --helm-kube-version string Helm kube-version to use when running helm template. If not set, use the kube version from the destination cluster + --helm-namespace string Helm namespace to use when running helm template. If not set, use app.spec.destination.namespace --helm-pass-credentials Pass credentials to all domain --helm-set stringArray Helm set values on the command line (can be repeated to set several values: --helm-set key1=val1 --helm-set key2=val2) --helm-set-file stringArray Helm set values from respective files specified via the command line (can be repeated to set several values: --helm-set-file key1=path1 --helm-set-file key2=path2) @@ -63,11 +66,13 @@ argocd app create APPNAME [flags] --jsonnet-libs stringArray Additional jsonnet libs (prefixed by repoRoot) --jsonnet-tla-code stringArray Jsonnet top level code arguments --jsonnet-tla-str stringArray Jsonnet top level string arguments + --kustomize-api-versions stringArray api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster. Only applicable when Helm is enabled for Kustomize builds --kustomize-common-annotation stringArray Set common labels in Kustomize --kustomize-common-label stringArray Set common labels in Kustomize --kustomize-force-common-annotation Force common annotations in Kustomize --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-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) @@ -102,7 +107,8 @@ argocd app create APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_delete-resource.md b/docs/user-guide/commands/argocd_app_delete-resource.md index e397c0c019fa8..892de087ec811 100644 --- a/docs/user-guide/commands/argocd_app_delete-resource.md +++ b/docs/user-guide/commands/argocd_app_delete-resource.md @@ -25,7 +25,8 @@ argocd app delete-resource APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_delete.md b/docs/user-guide/commands/argocd_app_delete.md index 827eeaab4ce7a..15ccb486220ad 100644 --- a/docs/user-guide/commands/argocd_app_delete.md +++ b/docs/user-guide/commands/argocd_app_delete.md @@ -40,7 +40,8 @@ argocd app delete APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_diff.md b/docs/user-guide/commands/argocd_app_diff.md index f8c5a15589340..07efe70af6b40 100644 --- a/docs/user-guide/commands/argocd_app_diff.md +++ b/docs/user-guide/commands/argocd_app_diff.md @@ -36,7 +36,8 @@ argocd app diff APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_edit.md b/docs/user-guide/commands/argocd_app_edit.md index e581677b79c12..684e77e12ce5a 100644 --- a/docs/user-guide/commands/argocd_app_edit.md +++ b/docs/user-guide/commands/argocd_app_edit.md @@ -18,7 +18,8 @@ argocd app edit APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_get.md b/docs/user-guide/commands/argocd_app_get.md index d0bf744054c38..8785e5b52637b 100644 --- a/docs/user-guide/commands/argocd_app_get.md +++ b/docs/user-guide/commands/argocd_app_get.md @@ -26,6 +26,9 @@ argocd app get APPNAME [flags] # Show application parameters and overrides argocd app get my-app --show-params + # Show application parameters and overrides for a source at position 1 under spec.sources of app my-app + argocd app get my-app --show-params --source-position 1 + # Refresh application data when retrieving argocd app get my-app --refresh @@ -49,12 +52,14 @@ argocd app get APPNAME [flags] --refresh Refresh application data when retrieving --show-operation Show application operation --show-params Show application parameters and overrides + --source-position int Position of the source from the list of sources of the app. Counting starts at 1. (default -1) ``` ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_history.md b/docs/user-guide/commands/argocd_app_history.md index eefadef01f417..81c2127ab8d6c 100644 --- a/docs/user-guide/commands/argocd_app_history.md +++ b/docs/user-guide/commands/argocd_app_history.md @@ -19,7 +19,8 @@ argocd app history APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_list.md b/docs/user-guide/commands/argocd_app_list.md index 17e00fcac9df3..843716f549771 100644 --- a/docs/user-guide/commands/argocd_app_list.md +++ b/docs/user-guide/commands/argocd_app_list.md @@ -37,7 +37,8 @@ argocd app list [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_logs.md b/docs/user-guide/commands/argocd_app_logs.md index 8dc1f6a9f1aae..decb6b05fd808 100644 --- a/docs/user-guide/commands/argocd_app_logs.md +++ b/docs/user-guide/commands/argocd_app_logs.md @@ -68,7 +68,8 @@ argocd app logs APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_manifests.md b/docs/user-guide/commands/argocd_app_manifests.md index 86d1aea1b1831..3238a7cfcf2d3 100644 --- a/docs/user-guide/commands/argocd_app_manifests.md +++ b/docs/user-guide/commands/argocd_app_manifests.md @@ -36,7 +36,8 @@ argocd app manifests APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_patch-resource.md b/docs/user-guide/commands/argocd_app_patch-resource.md index c849395cb3ea8..392c3c87e7014 100644 --- a/docs/user-guide/commands/argocd_app_patch-resource.md +++ b/docs/user-guide/commands/argocd_app_patch-resource.md @@ -25,7 +25,8 @@ argocd app patch-resource APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_patch.md b/docs/user-guide/commands/argocd_app_patch.md index 0c453ea159e64..90375448ce3af 100644 --- a/docs/user-guide/commands/argocd_app_patch.md +++ b/docs/user-guide/commands/argocd_app_patch.md @@ -30,7 +30,8 @@ argocd app patch APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_remove-source.md b/docs/user-guide/commands/argocd_app_remove-source.md index 9f96989e5d482..d9741e108ce86 100644 --- a/docs/user-guide/commands/argocd_app_remove-source.md +++ b/docs/user-guide/commands/argocd_app_remove-source.md @@ -26,7 +26,8 @@ argocd app remove-source APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_resources.md b/docs/user-guide/commands/argocd_app_resources.md index 22027f74ba3d7..9e3b43c5e1bfa 100644 --- a/docs/user-guide/commands/argocd_app_resources.md +++ b/docs/user-guide/commands/argocd_app_resources.md @@ -20,7 +20,8 @@ argocd app resources APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_rollback.md b/docs/user-guide/commands/argocd_app_rollback.md index 923023e35a2e8..47adea4a19a3a 100644 --- a/docs/user-guide/commands/argocd_app_rollback.md +++ b/docs/user-guide/commands/argocd_app_rollback.md @@ -21,7 +21,8 @@ argocd app rollback APPNAME [ID] [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_set.md b/docs/user-guide/commands/argocd_app_set.md index 077f9ed175c70..878d6e098e3ca 100644 --- a/docs/user-guide/commands/argocd_app_set.md +++ b/docs/user-guide/commands/argocd_app_set.md @@ -38,7 +38,10 @@ argocd app set APPNAME [flags] --directory-include string Set glob expression used to include files from application source path --directory-recurse Recurse directory --env string Application environment to monitor + --helm-api-versions stringArray Helm api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster --helm-chart string Helm Chart name + --helm-kube-version string Helm kube-version to use when running helm template. If not set, use the kube version from the destination cluster + --helm-namespace string Helm namespace to use when running helm template. If not set, use app.spec.destination.namespace --helm-pass-credentials Pass credentials to all domain --helm-set stringArray Helm set values on the command line (can be repeated to set several values: --helm-set key1=val1 --helm-set key2=val2) --helm-set-file stringArray Helm set values from respective files specified via the command line (can be repeated to set several values: --helm-set-file key1=path1 --helm-set-file key2=path2) @@ -52,11 +55,13 @@ argocd app set APPNAME [flags] --jsonnet-libs stringArray Additional jsonnet libs (prefixed by repoRoot) --jsonnet-tla-code stringArray Jsonnet top level code arguments --jsonnet-tla-str stringArray Jsonnet top level string arguments + --kustomize-api-versions stringArray api-versions (in format [group/]version/kind) to use when running helm template (Can be repeated to set several values: --helm-api-versions traefik.io/v1alpha1/TLSOption --helm-api-versions v1/Service). If not set, use the api-versions from the destination cluster. Only applicable when Helm is enabled for Kustomize builds --kustomize-common-annotation stringArray Set common labels in Kustomize --kustomize-common-label stringArray Set common labels in Kustomize --kustomize-force-common-annotation Force common annotations in Kustomize --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-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) @@ -88,7 +93,8 @@ argocd app set APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_sync.md b/docs/user-guide/commands/argocd_app_sync.md index 1dc6f48bd16ba..00d37d33747ff 100644 --- a/docs/user-guide/commands/argocd_app_sync.md +++ b/docs/user-guide/commands/argocd_app_sync.md @@ -75,7 +75,8 @@ argocd app sync [APPNAME... | -l selector | --project project-name] [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_terminate-op.md b/docs/user-guide/commands/argocd_app_terminate-op.md index a6d04299ca313..37cf70b9ea058 100644 --- a/docs/user-guide/commands/argocd_app_terminate-op.md +++ b/docs/user-guide/commands/argocd_app_terminate-op.md @@ -17,7 +17,8 @@ argocd app terminate-op APPNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_unset.md b/docs/user-guide/commands/argocd_app_unset.md index 10795166c4477..177f1b095dd69 100644 --- a/docs/user-guide/commands/argocd_app_unset.md +++ b/docs/user-guide/commands/argocd_app_unset.md @@ -48,7 +48,8 @@ argocd app unset APPNAME parameters [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_app_wait.md b/docs/user-guide/commands/argocd_app_wait.md index e2d3886f4d3ab..867484e3432b1 100644 --- a/docs/user-guide/commands/argocd_app_wait.md +++ b/docs/user-guide/commands/argocd_app_wait.md @@ -55,7 +55,8 @@ argocd app wait [APPNAME.. | -l selector] [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_appset.md b/docs/user-guide/commands/argocd_appset.md index 7b543ae318831..39c25dcca8fa7 100644 --- a/docs/user-guide/commands/argocd_appset.md +++ b/docs/user-guide/commands/argocd_appset.md @@ -52,7 +52,8 @@ argocd appset [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") @@ -82,6 +83,7 @@ argocd appset [flags] * [argocd](argocd.md) - argocd controls a Argo CD server * [argocd appset create](argocd_appset_create.md) - Create one or more ApplicationSets * [argocd appset delete](argocd_appset_delete.md) - Delete one or more ApplicationSets +* [argocd appset generate](argocd_appset_generate.md) - Generate apps of ApplicationSet rendered templates * [argocd appset get](argocd_appset_get.md) - Get ApplicationSet details * [argocd appset list](argocd_appset_list.md) - List ApplicationSets diff --git a/docs/user-guide/commands/argocd_appset_create.md b/docs/user-guide/commands/argocd_appset_create.md index fccc03fcc971c..ac0b1427dd7af 100644 --- a/docs/user-guide/commands/argocd_appset_create.md +++ b/docs/user-guide/commands/argocd_appset_create.md @@ -13,19 +13,25 @@ argocd appset create [flags] ``` # Create ApplicationSets argocd appset create (...) + + # Dry-run AppSet creation to see what applications would be managed + argocd appset create --dry-run -o json | jq -r '.status.resources[].name' ``` ### Options ``` - -h, --help help for create - --upsert Allows to override ApplicationSet with the same name even if supplied ApplicationSet spec is different from existing spec + --dry-run Allows to evaluate the ApplicationSet template on the server to get a preview of the applications that would be created + -h, --help help for create + -o, --output string Output format. One of: json|yaml|wide (default "wide") + --upsert Allows to override ApplicationSet with the same name even if supplied ApplicationSet spec is different from existing spec ``` ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_appset_delete.md b/docs/user-guide/commands/argocd_appset_delete.md index d97ca51b604e8..90510a42073c0 100644 --- a/docs/user-guide/commands/argocd_appset_delete.md +++ b/docs/user-guide/commands/argocd_appset_delete.md @@ -25,7 +25,8 @@ argocd appset delete [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_appset_generate.md b/docs/user-guide/commands/argocd_appset_generate.md new file mode 100644 index 0000000000000..8c7db6e8ac9c0 --- /dev/null +++ b/docs/user-guide/commands/argocd_appset_generate.md @@ -0,0 +1,57 @@ +# `argocd appset generate` Command Reference + +## argocd appset generate + +Generate apps of ApplicationSet rendered templates + +``` +argocd appset generate [flags] +``` + +### Examples + +``` + # Generate apps of ApplicationSet rendered templates + argocd appset generate (...) +``` + +### Options + +``` + -h, --help help for generate + -o, --output string Output format. One of: json|yaml|wide (default "wide") +``` + +### Options inherited from parent commands + +``` + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable + --client-crt string Client certificate file + --client-crt-key string Client certificate key file + --config string Path to Argo CD config (default "/home/user/.config/argocd/config") + --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") + --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. + --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. + -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) + --http-retry-max int Maximum number of retries to establish http connection to Argo CD server + --insecure Skip server certificate and domain verification + --kube-context string Directs the command to the given kube-context + --logformat string Set the logging format. One of: text|json (default "text") + --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") + --plaintext Disable TLS + --port-forward Connect to a random argocd-server port using port forwarding + --port-forward-namespace string Namespace name which should be used for port forwarding + --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") + --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") + --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") + --server string Argo CD server address + --server-crt string Server certificate file + --server-name string Name of the Argo CD API server; set this or the ARGOCD_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-server") +``` + +### SEE ALSO + +* [argocd appset](argocd_appset.md) - Manage ApplicationSets + diff --git a/docs/user-guide/commands/argocd_appset_get.md b/docs/user-guide/commands/argocd_appset_get.md index 8024d8ebf0a06..76b3e3946988b 100644 --- a/docs/user-guide/commands/argocd_appset_get.md +++ b/docs/user-guide/commands/argocd_appset_get.md @@ -26,7 +26,8 @@ argocd appset get APPSETNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_appset_list.md b/docs/user-guide/commands/argocd_appset_list.md index 92e0b21cb749b..fad42ce7e240c 100644 --- a/docs/user-guide/commands/argocd_appset_list.md +++ b/docs/user-guide/commands/argocd_appset_list.md @@ -28,7 +28,8 @@ argocd appset list [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_cert.md b/docs/user-guide/commands/argocd_cert.md index b126328a4372f..1e0db72b0452b 100644 --- a/docs/user-guide/commands/argocd_cert.md +++ b/docs/user-guide/commands/argocd_cert.md @@ -59,7 +59,8 @@ argocd cert [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_cert_add-ssh.md b/docs/user-guide/commands/argocd_cert_add-ssh.md index 94daf24bf376e..a32d12e18ea32 100644 --- a/docs/user-guide/commands/argocd_cert_add-ssh.md +++ b/docs/user-guide/commands/argocd_cert_add-ssh.md @@ -20,7 +20,8 @@ argocd cert add-ssh --batch [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_cert_add-tls.md b/docs/user-guide/commands/argocd_cert_add-tls.md index e8d3d733697e7..0208a502836ac 100644 --- a/docs/user-guide/commands/argocd_cert_add-tls.md +++ b/docs/user-guide/commands/argocd_cert_add-tls.md @@ -19,7 +19,8 @@ argocd cert add-tls SERVERNAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_cert_list.md b/docs/user-guide/commands/argocd_cert_list.md index 43a4af5bea783..d3b80dfeac97f 100644 --- a/docs/user-guide/commands/argocd_cert_list.md +++ b/docs/user-guide/commands/argocd_cert_list.md @@ -21,7 +21,8 @@ argocd cert list [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_cert_rm.md b/docs/user-guide/commands/argocd_cert_rm.md index 602a84aa6b85c..f76fb6a9a38c9 100644 --- a/docs/user-guide/commands/argocd_cert_rm.md +++ b/docs/user-guide/commands/argocd_cert_rm.md @@ -19,7 +19,8 @@ argocd cert rm REPOSERVER [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_cluster.md b/docs/user-guide/commands/argocd_cluster.md index a30c357d54d71..6f30e5a9308e4 100644 --- a/docs/user-guide/commands/argocd_cluster.md +++ b/docs/user-guide/commands/argocd_cluster.md @@ -56,7 +56,8 @@ argocd cluster [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_cluster_add.md b/docs/user-guide/commands/argocd_cluster_add.md index 8a80a12f5a4d5..cf1d9ba2d588e 100644 --- a/docs/user-guide/commands/argocd_cluster_add.md +++ b/docs/user-guide/commands/argocd_cluster_add.md @@ -39,7 +39,8 @@ argocd cluster add CONTEXT [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_cluster_get.md b/docs/user-guide/commands/argocd_cluster_get.md index a020a94557e99..8b3fd5e410a04 100644 --- a/docs/user-guide/commands/argocd_cluster_get.md +++ b/docs/user-guide/commands/argocd_cluster_get.md @@ -25,7 +25,8 @@ argocd cluster get in-cluster ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_cluster_list.md b/docs/user-guide/commands/argocd_cluster_list.md index 3e03f1581648f..d7ffbeb7baa9f 100644 --- a/docs/user-guide/commands/argocd_cluster_list.md +++ b/docs/user-guide/commands/argocd_cluster_list.md @@ -40,7 +40,8 @@ argocd cluster list -o server ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_cluster_rm.md b/docs/user-guide/commands/argocd_cluster_rm.md index 80057bb5a7082..667e5f9143cd4 100644 --- a/docs/user-guide/commands/argocd_cluster_rm.md +++ b/docs/user-guide/commands/argocd_cluster_rm.md @@ -25,7 +25,8 @@ argocd cluster rm cluster-name ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_cluster_rotate-auth.md b/docs/user-guide/commands/argocd_cluster_rotate-auth.md index 8dc3a5bf745d3..f91c10f3ea6e2 100644 --- a/docs/user-guide/commands/argocd_cluster_rotate-auth.md +++ b/docs/user-guide/commands/argocd_cluster_rotate-auth.md @@ -24,7 +24,8 @@ argocd cluster rotate-auth cluster-name ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_cluster_set.md b/docs/user-guide/commands/argocd_cluster_set.md index 2dba9c2ad16e8..3d26a6ec29702 100644 --- a/docs/user-guide/commands/argocd_cluster_set.md +++ b/docs/user-guide/commands/argocd_cluster_set.md @@ -19,15 +19,18 @@ argocd cluster set NAME [flags] ### Options ``` - -h, --help help for set - --name string Overwrite the cluster name - --namespace stringArray List of namespaces which are allowed to manage. Specify '*' to manage all namespaces + --annotation stringArray Set metadata annotations (e.g. --annotation key=value) + -h, --help help for set + --label stringArray Set metadata labels (e.g. --label key=value) + --name string Overwrite the cluster name + --namespace stringArray List of namespaces which are allowed to manage. Specify '*' to manage all namespaces ``` ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_completion.md b/docs/user-guide/commands/argocd_completion.md index 09d2bf264f1e8..32c91ccbc2707 100644 --- a/docs/user-guide/commands/argocd_completion.md +++ b/docs/user-guide/commands/argocd_completion.md @@ -52,7 +52,8 @@ $ source ~/.config/fish/completions/argocd.fish ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_context.md b/docs/user-guide/commands/argocd_context.md index f02944cf4f775..1805bb7e0a1e0 100644 --- a/docs/user-guide/commands/argocd_context.md +++ b/docs/user-guide/commands/argocd_context.md @@ -31,7 +31,8 @@ argocd context cd.argoproj.io --delete ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_gpg.md b/docs/user-guide/commands/argocd_gpg.md index bca15e98b7c87..41941b1f2739c 100644 --- a/docs/user-guide/commands/argocd_gpg.md +++ b/docs/user-guide/commands/argocd_gpg.md @@ -36,7 +36,8 @@ argocd gpg [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_gpg_add.md b/docs/user-guide/commands/argocd_gpg_add.md index 3ef5d4e6c72d5..e0fd7ac55116f 100644 --- a/docs/user-guide/commands/argocd_gpg_add.md +++ b/docs/user-guide/commands/argocd_gpg_add.md @@ -25,7 +25,8 @@ argocd gpg add [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_gpg_get.md b/docs/user-guide/commands/argocd_gpg_get.md index e0ad3d9ee25d6..5e738b60d8906 100644 --- a/docs/user-guide/commands/argocd_gpg_get.md +++ b/docs/user-guide/commands/argocd_gpg_get.md @@ -31,7 +31,8 @@ argocd gpg get KEYID [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_gpg_list.md b/docs/user-guide/commands/argocd_gpg_list.md index 50f0e72e83c0d..2d193caf677a6 100644 --- a/docs/user-guide/commands/argocd_gpg_list.md +++ b/docs/user-guide/commands/argocd_gpg_list.md @@ -31,7 +31,8 @@ argocd gpg list [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_gpg_rm.md b/docs/user-guide/commands/argocd_gpg_rm.md index ecf744988d0fd..125f193bb473c 100644 --- a/docs/user-guide/commands/argocd_gpg_rm.md +++ b/docs/user-guide/commands/argocd_gpg_rm.md @@ -17,7 +17,8 @@ argocd gpg rm KEYID [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_login.md b/docs/user-guide/commands/argocd_login.md index adf02fefbc454..c20247b01b283 100644 --- a/docs/user-guide/commands/argocd_login.md +++ b/docs/user-guide/commands/argocd_login.md @@ -28,19 +28,21 @@ argocd login cd.argoproj.io --core ### Options ``` - -h, --help help for login - --name string Name to use for the context - --password string The password of an account to authenticate - --skip-test-tls Skip testing whether the server is configured with TLS (this can help when the command hangs for no apparent reason) - --sso Perform SSO login - --sso-port int Port to run local OAuth2 login application (default 8085) - --username string The username of an account to authenticate + -h, --help help for login + --name string Name to use for the context + --password string The password of an account to authenticate + --skip-test-tls Skip testing whether the server is configured with TLS (this can help when the command hangs for no apparent reason) + --sso Perform SSO login + --sso-launch-browser Automatically launch the system default browser when performing SSO login (default true) + --sso-port int Port to run local OAuth2 login application (default 8085) + --username string The username of an account to authenticate ``` ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_logout.md b/docs/user-guide/commands/argocd_logout.md index 3e18c70a063a0..132e73fa5033f 100644 --- a/docs/user-guide/commands/argocd_logout.md +++ b/docs/user-guide/commands/argocd_logout.md @@ -30,7 +30,8 @@ $ argocd logout ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj.md b/docs/user-guide/commands/argocd_proj.md index 5586463adee6e..8f35188d33634 100644 --- a/docs/user-guide/commands/argocd_proj.md +++ b/docs/user-guide/commands/argocd_proj.md @@ -52,7 +52,8 @@ argocd proj [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") @@ -81,6 +82,7 @@ argocd proj [flags] * [argocd](argocd.md) - argocd controls a Argo CD server * [argocd proj add-destination](argocd_proj_add-destination.md) - Add project destination +* [argocd proj add-destination-service-account](argocd_proj_add-destination-service-account.md) - Add project destination's default service account * [argocd proj add-orphaned-ignore](argocd_proj_add-orphaned-ignore.md) - Add a resource to orphaned ignore list * [argocd proj add-signature-key](argocd_proj_add-signature-key.md) - Add GnuPG signature key to project * [argocd proj add-source](argocd_proj_add-source.md) - Add project source repository @@ -95,6 +97,7 @@ argocd proj [flags] * [argocd proj get](argocd_proj_get.md) - Get project details * [argocd proj list](argocd_proj_list.md) - List projects * [argocd proj remove-destination](argocd_proj_remove-destination.md) - Remove project destination +* [argocd proj remove-destination-service-account](argocd_proj_remove-destination-service-account.md) - Remove default destination service account from the project * [argocd proj remove-orphaned-ignore](argocd_proj_remove-orphaned-ignore.md) - Remove a resource from orphaned ignore list * [argocd proj remove-signature-key](argocd_proj_remove-signature-key.md) - Remove GnuPG signature key from project * [argocd proj remove-source](argocd_proj_remove-source.md) - Remove project source repository 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 new file mode 100644 index 0000000000000..b1c0be6de7c85 --- /dev/null +++ b/docs/user-guide/commands/argocd_proj_add-destination-service-account.md @@ -0,0 +1,60 @@ +# `argocd proj add-destination-service-account` Command Reference + +## argocd proj add-destination-service-account + +Add project destination's default service account + +``` +argocd proj add-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ACCOUNT [flags] +``` + +### Examples + +``` + # Add project destination service account (SERVICE_ACCOUNT) for a server URL (SERVER) in the specified namespace (NAMESPACE) on the project with name PROJECT + argocd proj add-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ACCOUNT + + # Add project destination service account (SERVICE_ACCOUNT) from a different namespace + argocd proj add-destination PROJECT SERVER NAMESPACE SERVICE_ACCOUNT --service-account-namespace +``` + +### Options + +``` + -h, --help help for add-destination-service-account + --service-account-namespace string Use service-account-namespace as namespace where the service account is present +``` + +### Options inherited from parent commands + +``` + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable + --client-crt string Client certificate file + --client-crt-key string Client certificate key file + --config string Path to Argo CD config (default "/home/user/.config/argocd/config") + --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") + --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. + --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. + -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) + --http-retry-max int Maximum number of retries to establish http connection to Argo CD server + --insecure Skip server certificate and domain verification + --kube-context string Directs the command to the given kube-context + --logformat string Set the logging format. One of: text|json (default "text") + --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") + --plaintext Disable TLS + --port-forward Connect to a random argocd-server port using port forwarding + --port-forward-namespace string Namespace name which should be used for port forwarding + --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") + --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") + --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") + --server string Argo CD server address + --server-crt string Server certificate file + --server-name string Name of the Argo CD API server; set this or the ARGOCD_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-server") +``` + +### SEE ALSO + +* [argocd proj](argocd_proj.md) - Manage projects + diff --git a/docs/user-guide/commands/argocd_proj_add-destination.md b/docs/user-guide/commands/argocd_proj_add-destination.md index 688aebf84156e..d13f1a5234f7b 100644 --- a/docs/user-guide/commands/argocd_proj_add-destination.md +++ b/docs/user-guide/commands/argocd_proj_add-destination.md @@ -28,7 +28,8 @@ argocd proj add-destination PROJECT SERVER/NAME NAMESPACE [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 1b36d8a5ff0f1..c32ba8c010300 100644 --- a/docs/user-guide/commands/argocd_proj_add-orphaned-ignore.md +++ b/docs/user-guide/commands/argocd_proj_add-orphaned-ignore.md @@ -28,7 +28,8 @@ argocd proj add-orphaned-ignore PROJECT GROUP KIND [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 404660510700b..406f554b61195 100644 --- a/docs/user-guide/commands/argocd_proj_add-signature-key.md +++ b/docs/user-guide/commands/argocd_proj_add-signature-key.md @@ -24,7 +24,8 @@ argocd proj add-signature-key PROJECT KEY-ID [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 ced1f6fa3c67d..45c4b0cba6781 100644 --- a/docs/user-guide/commands/argocd_proj_add-source-namespace.md +++ b/docs/user-guide/commands/argocd_proj_add-source-namespace.md @@ -24,7 +24,8 @@ argocd proj add-source-namespace PROJECT NAMESPACE [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_add-source.md b/docs/user-guide/commands/argocd_proj_add-source.md index f0c2f18fd9792..0e64e29d0a3f4 100644 --- a/docs/user-guide/commands/argocd_proj_add-source.md +++ b/docs/user-guide/commands/argocd_proj_add-source.md @@ -24,7 +24,8 @@ argocd proj add-source PROJECT URL [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 338027e724bc2..11a8cfc158ff0 100644 --- a/docs/user-guide/commands/argocd_proj_allow-cluster-resource.md +++ b/docs/user-guide/commands/argocd_proj_allow-cluster-resource.md @@ -25,7 +25,8 @@ argocd proj allow-cluster-resource PROJECT GROUP KIND [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 3e4a410f32a47..89bb7197cf2bc 100644 --- a/docs/user-guide/commands/argocd_proj_allow-namespace-resource.md +++ b/docs/user-guide/commands/argocd_proj_allow-namespace-resource.md @@ -25,7 +25,8 @@ argocd proj allow-namespace-resource PROJECT GROUP KIND [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_create.md b/docs/user-guide/commands/argocd_proj_create.md index fd8687c1b2982..c8b27e35bb762 100644 --- a/docs/user-guide/commands/argocd_proj_create.md +++ b/docs/user-guide/commands/argocd_proj_create.md @@ -40,7 +40,8 @@ argocd proj create PROJECT [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_delete.md b/docs/user-guide/commands/argocd_proj_delete.md index 4d6c4a94f609c..b955732eb6067 100644 --- a/docs/user-guide/commands/argocd_proj_delete.md +++ b/docs/user-guide/commands/argocd_proj_delete.md @@ -24,7 +24,8 @@ argocd proj delete PROJECT [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 4621b18c3efe1..bc9bfcfae0d5a 100644 --- a/docs/user-guide/commands/argocd_proj_deny-cluster-resource.md +++ b/docs/user-guide/commands/argocd_proj_deny-cluster-resource.md @@ -25,7 +25,8 @@ argocd proj deny-cluster-resource PROJECT GROUP KIND [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 e8b55a7b0adb6..97367b23cb9c7 100644 --- a/docs/user-guide/commands/argocd_proj_deny-namespace-resource.md +++ b/docs/user-guide/commands/argocd_proj_deny-namespace-resource.md @@ -25,7 +25,8 @@ argocd proj deny-namespace-resource PROJECT GROUP KIND [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_edit.md b/docs/user-guide/commands/argocd_proj_edit.md index 63a584accfad8..1955aa11ba2c4 100644 --- a/docs/user-guide/commands/argocd_proj_edit.md +++ b/docs/user-guide/commands/argocd_proj_edit.md @@ -24,7 +24,8 @@ argocd proj edit PROJECT [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_get.md b/docs/user-guide/commands/argocd_proj_get.md index 2d2e437b79779..930972018db05 100644 --- a/docs/user-guide/commands/argocd_proj_get.md +++ b/docs/user-guide/commands/argocd_proj_get.md @@ -28,7 +28,8 @@ argocd proj get PROJECT [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_list.md b/docs/user-guide/commands/argocd_proj_list.md index d96c0c4bb13b8..2a71f43d68c3a 100644 --- a/docs/user-guide/commands/argocd_proj_list.md +++ b/docs/user-guide/commands/argocd_proj_list.md @@ -28,7 +28,8 @@ argocd proj list [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 new file mode 100644 index 0000000000000..bcb2a2bc3605e --- /dev/null +++ b/docs/user-guide/commands/argocd_proj_remove-destination-service-account.md @@ -0,0 +1,56 @@ +# `argocd proj remove-destination-service-account` Command Reference + +## argocd proj remove-destination-service-account + +Remove default destination service account from the project + +``` +argocd proj remove-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ACCOUNT [flags] +``` + +### Examples + +``` + # Remove the destination service account (SERVICE_ACCOUNT) from the specified destination (SERVER and NAMESPACE combination) on the project with name PROJECT + argocd proj remove-destination-service-account PROJECT SERVER NAMESPACE SERVICE_ACCOUNT +``` + +### Options + +``` + -h, --help help for remove-destination-service-account +``` + +### Options inherited from parent commands + +``` + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable + --client-crt string Client certificate file + --client-crt-key string Client certificate key file + --config string Path to Argo CD config (default "/home/user/.config/argocd/config") + --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") + --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. + --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. + -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) + --http-retry-max int Maximum number of retries to establish http connection to Argo CD server + --insecure Skip server certificate and domain verification + --kube-context string Directs the command to the given kube-context + --logformat string Set the logging format. One of: text|json (default "text") + --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") + --plaintext Disable TLS + --port-forward Connect to a random argocd-server port using port forwarding + --port-forward-namespace string Namespace name which should be used for port forwarding + --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") + --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") + --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") + --server string Argo CD server address + --server-crt string Server certificate file + --server-name string Name of the Argo CD API server; set this or the ARGOCD_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-server") +``` + +### SEE ALSO + +* [argocd proj](argocd_proj.md) - Manage projects + diff --git a/docs/user-guide/commands/argocd_proj_remove-destination.md b/docs/user-guide/commands/argocd_proj_remove-destination.md index 612e1db68356a..88a702b2ed2b5 100644 --- a/docs/user-guide/commands/argocd_proj_remove-destination.md +++ b/docs/user-guide/commands/argocd_proj_remove-destination.md @@ -24,7 +24,8 @@ argocd proj remove-destination PROJECT SERVER NAMESPACE [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 857cf3c595177..79ff167f1c394 100644 --- a/docs/user-guide/commands/argocd_proj_remove-orphaned-ignore.md +++ b/docs/user-guide/commands/argocd_proj_remove-orphaned-ignore.md @@ -28,7 +28,8 @@ argocd proj remove-orphaned-ignore PROJECT GROUP KIND [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 61d6085022662..0f81b6ec52270 100644 --- a/docs/user-guide/commands/argocd_proj_remove-signature-key.md +++ b/docs/user-guide/commands/argocd_proj_remove-signature-key.md @@ -24,7 +24,8 @@ argocd proj remove-signature-key PROJECT KEY-ID [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 6a0ee319c7b9b..a26bebcee38bb 100644 --- a/docs/user-guide/commands/argocd_proj_remove-source-namespace.md +++ b/docs/user-guide/commands/argocd_proj_remove-source-namespace.md @@ -24,7 +24,8 @@ argocd proj remove-source-namespace PROJECT NAMESPACE [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_remove-source.md b/docs/user-guide/commands/argocd_proj_remove-source.md index d6a1c353059f3..66c016fadd7e5 100644 --- a/docs/user-guide/commands/argocd_proj_remove-source.md +++ b/docs/user-guide/commands/argocd_proj_remove-source.md @@ -24,7 +24,8 @@ argocd proj remove-source PROJECT URL [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_role.md b/docs/user-guide/commands/argocd_proj_role.md index 9546cc4b7ab27..89d7abe87de4d 100644 --- a/docs/user-guide/commands/argocd_proj_role.md +++ b/docs/user-guide/commands/argocd_proj_role.md @@ -17,7 +17,8 @@ argocd proj role [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 4a3aa2f1e8be1..9d818665cd487 100644 --- a/docs/user-guide/commands/argocd_proj_role_add-group.md +++ b/docs/user-guide/commands/argocd_proj_role_add-group.md @@ -17,7 +17,8 @@ argocd proj role add-group PROJECT ROLE-NAME GROUP-CLAIM [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 d4804d31d66a1..d37469d1f8d36 100644 --- a/docs/user-guide/commands/argocd_proj_role_add-policy.md +++ b/docs/user-guide/commands/argocd_proj_role_add-policy.md @@ -49,7 +49,8 @@ ID ISSUED-AT EXPIRES-AT ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 fc7eaf93c2307..faacc8a01b72d 100644 --- a/docs/user-guide/commands/argocd_proj_role_create-token.md +++ b/docs/user-guide/commands/argocd_proj_role_create-token.md @@ -32,7 +32,8 @@ Create token succeeded for proj:test-project:test-role. ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_role_create.md b/docs/user-guide/commands/argocd_proj_role_create.md index 60974c9e1b4e6..885c79f1672b3 100644 --- a/docs/user-guide/commands/argocd_proj_role_create.md +++ b/docs/user-guide/commands/argocd_proj_role_create.md @@ -25,7 +25,8 @@ argocd proj role create PROJECT ROLE-NAME [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 006746f8faeeb..c9c5a7fc17eca 100644 --- a/docs/user-guide/commands/argocd_proj_role_delete-token.md +++ b/docs/user-guide/commands/argocd_proj_role_delete-token.md @@ -49,7 +49,8 @@ $ argocd proj role delete-token test-project test-role 1696769937 ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_role_delete.md b/docs/user-guide/commands/argocd_proj_role_delete.md index fe94a2231db60..97e01627e371a 100644 --- a/docs/user-guide/commands/argocd_proj_role_delete.md +++ b/docs/user-guide/commands/argocd_proj_role_delete.md @@ -23,7 +23,8 @@ $ argocd proj role delete test-project test-role ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_role_get.md b/docs/user-guide/commands/argocd_proj_role_get.md index e21276ce85116..d35b8768b47b2 100644 --- a/docs/user-guide/commands/argocd_proj_role_get.md +++ b/docs/user-guide/commands/argocd_proj_role_get.md @@ -32,7 +32,8 @@ ID ISSUED-AT EXPIRES-AT ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 8d1fe93163dfc..7df6b0c64e0aa 100644 --- a/docs/user-guide/commands/argocd_proj_role_list-tokens.md +++ b/docs/user-guide/commands/argocd_proj_role_list-tokens.md @@ -28,7 +28,8 @@ fa9d3517-c52d-434c-9bff-215b38508842 2023-10-08T11:08:18+01:00 Never ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_role_list.md b/docs/user-guide/commands/argocd_proj_role_list.md index 3cfd630ddc988..34b62a3cf4beb 100644 --- a/docs/user-guide/commands/argocd_proj_role_list.md +++ b/docs/user-guide/commands/argocd_proj_role_list.md @@ -28,7 +28,8 @@ argocd proj role list PROJECT [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 a89e0bcfae315..b4db5dee8b882 100644 --- a/docs/user-guide/commands/argocd_proj_role_remove-group.md +++ b/docs/user-guide/commands/argocd_proj_role_remove-group.md @@ -17,7 +17,8 @@ argocd proj role remove-group PROJECT ROLE-NAME GROUP-CLAIM [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 96aee05da86eb..df0fd403542af 100644 --- a/docs/user-guide/commands/argocd_proj_role_remove-policy.md +++ b/docs/user-guide/commands/argocd_proj_role_remove-policy.md @@ -49,7 +49,8 @@ ID ISSUED-AT EXPIRES-AT ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_set.md b/docs/user-guide/commands/argocd_proj_set.md index 3dc0cc06ec787..7b4d79ff13588 100644 --- a/docs/user-guide/commands/argocd_proj_set.md +++ b/docs/user-guide/commands/argocd_proj_set.md @@ -38,7 +38,8 @@ argocd proj set PROJECT [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_windows.md b/docs/user-guide/commands/argocd_proj_windows.md index 0b22c2098dc82..b02a6772a8582 100644 --- a/docs/user-guide/commands/argocd_proj_windows.md +++ b/docs/user-guide/commands/argocd_proj_windows.md @@ -34,7 +34,8 @@ argocd proj windows list ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_windows_add.md b/docs/user-guide/commands/argocd_proj_windows_add.md index 52fd3a8354ee3..beb158b9c6243 100644 --- a/docs/user-guide/commands/argocd_proj_windows_add.md +++ b/docs/user-guide/commands/argocd_proj_windows_add.md @@ -48,7 +48,8 @@ argocd proj windows add PROJECT \ ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_windows_delete.md b/docs/user-guide/commands/argocd_proj_windows_delete.md index 6faf7dbeedc19..2fc4ef2c43390 100644 --- a/docs/user-guide/commands/argocd_proj_windows_delete.md +++ b/docs/user-guide/commands/argocd_proj_windows_delete.md @@ -28,7 +28,8 @@ argocd proj windows delete new-project 1 ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 3f01015395f1b..011a394b8848a 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 @@ -32,7 +32,8 @@ argocd proj windows disable-manual-sync default 0 ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") 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 7ecbb50e6ac1b..1f51fe038e3b8 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 @@ -35,7 +35,8 @@ argocd proj windows enable-manual-sync my-app-project --message "Manual sync ini ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_windows_list.md b/docs/user-guide/commands/argocd_proj_windows_list.md index 3c361f90d2a68..5f15f34dfe948 100644 --- a/docs/user-guide/commands/argocd_proj_windows_list.md +++ b/docs/user-guide/commands/argocd_proj_windows_list.md @@ -32,7 +32,8 @@ argocd proj windows list test-project ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_proj_windows_update.md b/docs/user-guide/commands/argocd_proj_windows_update.md index e01e3787d51a2..a3405c0650be8 100644 --- a/docs/user-guide/commands/argocd_proj_windows_update.md +++ b/docs/user-guide/commands/argocd_proj_windows_update.md @@ -36,7 +36,8 @@ argocd proj windows update PROJECT ID \ ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_relogin.md b/docs/user-guide/commands/argocd_relogin.md index 430ab4a9222c9..8891d35b896dd 100644 --- a/docs/user-guide/commands/argocd_relogin.md +++ b/docs/user-guide/commands/argocd_relogin.md @@ -32,15 +32,17 @@ argocd login cd.argoproj.io --core ### Options ``` - -h, --help help for relogin - --password string The password of an account to authenticate - --sso-port int Port to run local OAuth2 login application (default 8085) + -h, --help help for relogin + --password string The password of an account to authenticate + --sso-launch-browser Automatically launch the default browser when performing SSO login (default true) + --sso-port int Port to run local OAuth2 login application (default 8085) ``` ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_repo.md b/docs/user-guide/commands/argocd_repo.md index 4df85f7b00d3d..3e6548df9a5a7 100644 --- a/docs/user-guide/commands/argocd_repo.md +++ b/docs/user-guide/commands/argocd_repo.md @@ -54,7 +54,8 @@ argocd repo rm https://github.com/yourusername/your-repo.git ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_repo_add.md b/docs/user-guide/commands/argocd_repo_add.md index 8399d48302509..4abb437cf7bdc 100644 --- a/docs/user-guide/commands/argocd_repo_add.md +++ b/docs/user-guide/commands/argocd_repo_add.md @@ -64,6 +64,7 @@ argocd repo add REPOURL [flags] --insecure-ignore-host-key disables SSH strict host key checking (deprecated, use --insecure-skip-server-verification instead) --insecure-skip-server-verification disables server certificate and host key checks --name string name of the repository, mandatory for repositories of type helm + --no-proxy string don't access these targets via proxy --password string password to the repository --project string project of the repository --proxy string use proxy to access repository @@ -78,7 +79,8 @@ argocd repo add REPOURL [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_repo_get.md b/docs/user-guide/commands/argocd_repo_get.md index e1d445d1068f6..b28d30e1e0037 100644 --- a/docs/user-guide/commands/argocd_repo_get.md +++ b/docs/user-guide/commands/argocd_repo_get.md @@ -20,7 +20,8 @@ argocd repo get [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_repo_list.md b/docs/user-guide/commands/argocd_repo_list.md index 06f1f788cb7c2..5a13cff85c5fc 100644 --- a/docs/user-guide/commands/argocd_repo_list.md +++ b/docs/user-guide/commands/argocd_repo_list.md @@ -19,7 +19,8 @@ argocd repo list [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_repo_rm.md b/docs/user-guide/commands/argocd_repo_rm.md index 4e44bf0acf90b..4b784e0a6d1c1 100644 --- a/docs/user-guide/commands/argocd_repo_rm.md +++ b/docs/user-guide/commands/argocd_repo_rm.md @@ -18,7 +18,8 @@ argocd repo rm REPO [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_repocreds.md b/docs/user-guide/commands/argocd_repocreds.md index f073b2bbb6161..cac91d9700bf5 100644 --- a/docs/user-guide/commands/argocd_repocreds.md +++ b/docs/user-guide/commands/argocd_repocreds.md @@ -49,7 +49,8 @@ argocd repocreds [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_repocreds_add.md b/docs/user-guide/commands/argocd_repocreds_add.md index ce66dc49cfe8c..39405519def40 100644 --- a/docs/user-guide/commands/argocd_repocreds_add.md +++ b/docs/user-guide/commands/argocd_repocreds_add.md @@ -43,6 +43,7 @@ argocd repocreds add REPOURL [flags] --github-app-private-key-path string private key of the GitHub Application -h, --help help for add --password string password to the repository + --proxy-url string If provided, this URL will be used to connect via proxy --ssh-private-key-path string path to the private ssh key (e.g. ~/.ssh/id_rsa) --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) @@ -54,7 +55,8 @@ argocd repocreds add REPOURL [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_repocreds_list.md b/docs/user-guide/commands/argocd_repocreds_list.md index ae358afab2056..ebcf308bdc766 100644 --- a/docs/user-guide/commands/argocd_repocreds_list.md +++ b/docs/user-guide/commands/argocd_repocreds_list.md @@ -34,7 +34,8 @@ argocd repocreds list [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_repocreds_rm.md b/docs/user-guide/commands/argocd_repocreds_rm.md index 3bfee30eb40a3..6893bd3dc3db9 100644 --- a/docs/user-guide/commands/argocd_repocreds_rm.md +++ b/docs/user-guide/commands/argocd_repocreds_rm.md @@ -24,7 +24,8 @@ argocd repocreds rm CREDSURL [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/commands/argocd_version.md b/docs/user-guide/commands/argocd_version.md index 6a7fa7baf5ecb..bd6505cc1c622 100644 --- a/docs/user-guide/commands/argocd_version.md +++ b/docs/user-guide/commands/argocd_version.md @@ -56,7 +56,8 @@ argocd version [flags] ### Options inherited from parent commands ``` - --auth-token string Authentication token + --argocd-context string The name of the Argo-CD server context to use + --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") diff --git a/docs/user-guide/diffing.md b/docs/user-guide/diffing.md index 95fe7f0ace3ac..7e5b72d97959c 100644 --- a/docs/user-guide/diffing.md +++ b/docs/user-guide/diffing.md @@ -74,7 +74,8 @@ If you have a slash `/` in your pointer path, you need to replace it with the `~ spec: ignoreDifferences: - kind: Node - jsonPointers: /metadata/labels/node-role.kubernetes.io~1worker + jsonPointers: + - /metadata/labels/node-role.kubernetes.io~1worker ``` ## System-Level Configuration diff --git a/docs/user-guide/gpg-verification.md b/docs/user-guide/gpg-verification.md index bf632cabdfbc5..f0881df0f0846 100644 --- a/docs/user-guide/gpg-verification.md +++ b/docs/user-guide/gpg-verification.md @@ -29,6 +29,11 @@ not possible using Helm repositories. trust models, and it is not necessary (nor possible) to sign the public keys you are going to import into ArgoCD. + +!!!note Limitations + Signature verification is not supported for the templated `project` field when + using the Git generator. + ## Signature verification targets If signature verification is enforced, ArgoCD will verify the signature using diff --git a/docs/user-guide/helm.md b/docs/user-guide/helm.md index 3b5a5de0dc262..c768b50835a24 100644 --- a/docs/user-guide/helm.md +++ b/docs/user-guide/helm.md @@ -233,12 +233,9 @@ source: helm: fileParameters: - name: some.key - value: path/to/file.ext + path: path/to/file.ext ``` -!!! warning "Reference in multiple sources not supported" - Please note that using a multiple sources application will not let you load the file by reference. See [argoproj/argo-cd#13220](https://github.com/argoproj/argo-cd/issues/13220) - ## Helm Release Name By default, the Helm release name is equal to the Application name to which it belongs. Sometimes, especially on a centralised Argo CD, diff --git a/docs/user-guide/kustomize.md b/docs/user-guide/kustomize.md index 28dfaebd28f25..100622cf03ea8 100644 --- a/docs/user-guide/kustomize.md +++ b/docs/user-guide/kustomize.md @@ -18,6 +18,7 @@ spec: destination: namespace: default server: 'https://kubernetes.default.svc' +``` If the `kustomization.yaml` file exists at the location pointed to by `repoURL` and `path`, Argo CD will render the manifests using Kustomize. diff --git a/docs/user-guide/multiple_sources.md b/docs/user-guide/multiple_sources.md index 462bfa13475f3..f9be46d76f8fa 100644 --- a/docs/user-guide/multiple_sources.md +++ b/docs/user-guide/multiple_sources.md @@ -1,8 +1,5 @@ # Multiple Sources for an Application -!!! warning "Beta Feature" - Specifying multiple sources for an application is a beta feature. This feature is subject to change in backwards incompatible ways until it is marked stable. - By default an Argo CD application is a link between a single source and a cluster. Sometimes however, you want to combine files from multiple locations to form a single Application. diff --git a/docs/user-guide/projects.md b/docs/user-guide/projects.md index f5979cf3c47b3..d027193421d49 100644 --- a/docs/user-guide/projects.md +++ b/docs/user-guide/projects.md @@ -1,7 +1,6 @@ ## Projects -Projects provide a logical grouping of applications, which is useful when Argo CD is used by multiple -teams. Projects provide the following features: +Projects provide a logical grouping of applications, which is useful when Argo CD is used by multiple teams. Projects provide the following features: * restrict what may be deployed (trusted Git source repositories) * restrict where apps may be deployed to (destination clusters and namespaces) @@ -10,10 +9,7 @@ teams. Projects provide the following features: ### 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. The default project can be modified, but not -deleted. 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: @@ -29,10 +25,7 @@ spec: ### 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. +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. ```bash argocd proj create myproject -d https://kubernetes.default.svc,mynamespace -s https://github.com/argoproj/argocd-example-apps.git @@ -109,11 +102,9 @@ As with sources, a destination is considered valid if the following conditions h 1. _Any_ allow destination rule (i.e. a rule which isn't prefixed with `!`) permits the destination 2. AND *no* deny destination (i.e. a rule which is prefixed with `!`) rejects the destination -Keep in mind that `!*` is an invalid rule, since it doesn't make any sense to disallow everything. +Keep in mind that `!*` is an invalid rule, since it doesn't make any sense to disallow everything. -Permitted destination K8s resource kinds are managed with the commands. Note that namespaced-scoped -resources are restricted via a deny list, whereas cluster-scoped resources are restricted via -allow list. +Permitted destination K8s resource kinds are managed with the commands. Note that namespaced-scoped resources are restricted via a deny list, whereas cluster-scoped resources are restricted via allow list. ```bash argocd proj allow-cluster-resource @@ -124,8 +115,7 @@ argocd proj deny-namespace-resource ### Assign Application To A Project -The application project can be changed using `app set` command. In order to change the project of -an app, the user must have permissions to access the new project. +The application project can be changed using `app set` command. In order to change the project of an app, the user must have permissions to access the new project. ``` argocd app set guestbook-default --project myproject @@ -133,18 +123,39 @@ argocd app set guestbook-default --project myproject ## Project Roles -Projects include a feature called roles that enable automated access to a project's applications. -These can be used to give a CI pipeline a restricted set of permissions. For example, a CI system -may only be able to sync 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: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: sample-test-project +spec: + ... + roles: + - description: some-role + groups: + - some-user + name: admin + policies: + - 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: -Projects can have multiple roles, and those roles can have different access granted to them. These -permissions are called policies, and they are stored within the role as a list of policy strings. -A role's policy can only grant access to that role and are limited to applications within the role's -project. However, the policies have an option for granting wildcard access to any application -within a project. +``` + 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. -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. +_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. ```bash argocd proj role list @@ -155,10 +166,7 @@ argocd proj role add-policy argocd proj role remove-policy ``` -Project roles in itself are not useful without generating a token to associate to that role. Argo CD -supports JWT tokens as the means to authenticate to a role. Since the JWT token is -associated with a role's policies, any changes to the role's policies will immediately take effect -for that JWT token. +Project roles in itself are not useful without generating a token to associate to that role. Argo CD supports JWT tokens as the means to authenticate to a role. Since the JWT token is associated with a role's policies, any changes to the role's policies will immediately take effect for that JWT token. The following commands are used to manage the JWT tokens. @@ -167,16 +175,9 @@ 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 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. +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. +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. ```bash PROJ=myproject @@ -211,8 +212,7 @@ argocd app get $APP --auth-token $JWT ## Configuring RBAC With Projects -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. +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:* @@ -234,12 +234,11 @@ spec: ``` You can use `argocd proj role` CLI commands or project details page in the user interface to configure the policy. -Note that each project role policy rule must be scoped to that project only. Use the `argocd-rbac-cm` ConfigMap described in -[RBAC](../operator-manual/rbac.md) documentation if you want to configure cross project RBAC rules. +Note that each project role policy rule must be scoped to that project only. Use the `argocd-rbac-cm` ConfigMap described in [RBAC](../operator-manual/rbac.md) documentation if you want to configure cross project RBAC rules. ## Configuring Global Projects (v1.8) -Global projects can be configured to provide configurations that other projects can inherit from. +Global projects can be configured to provide configurations that other projects can inherit from. Projects, which match `matchExpressions` specified in `argocd-cm` ConfigMap, inherit the following fields from the global project: @@ -271,17 +270,14 @@ projectName: `proj-global-test` should be replaced with your own global project ## Project scoped Repositories and Clusters -Normally, an Argo CD admin creates a project and decides in advance which clusters and Git repositories -it defines. However, this creates a problem in scenarios where a developer wants to add a repository or cluster -after the initial creation of the project. This forces the developer to contact their Argo CD admin again to update the project definition. +Normally, an Argo CD admin creates a project and decides in advance which clusters and Git repositories it defines. However, this creates a problem in scenarios where a developer wants to add a repository or cluster after the initial creation of the project. This forces the developer to contact their Argo CD admin again to update the project definition. It is possible to offer a self-service process for developers so that they can add a repository and/or cluster in a project on their own even after the initial creation of the project. 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 and 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 @@ -295,8 +291,7 @@ This provides extra flexibility so that admins can have stricter rules. e.g.: p, proj:my-project:admin, repositories, update, my-project/https://github.example.com/*, allow ``` -Once the appropriate RBAC rules are in place, developers can create their own Git repositories and (assuming -they have the correct credentials) can add them in an existing project either from the UI or the CLI. +Once the appropriate RBAC rules are in place, developers can create their own Git repositories and (assuming they have the correct credentials) can add them in an existing project either from the UI or the CLI. Both the User interface and the CLI have the ability to optionally specify a project. If a project is specified then the respective cluster/repository is considered project scoped: ```argocd repo add --name stable https://charts.helm.sh/stable --type helm --project my-project``` @@ -319,6 +314,11 @@ stringData: password: **** ``` +!!! warning +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 talk about Git repositories, but the same principles apply to clusters as well. ```yaml @@ -343,9 +343,7 @@ stringData: } ``` -With project-scoped clusters we can also restrict projects to only allow applications whose destinations belong to the -same project. The default behavior allows for applications to be installed onto clusters which are not a part of the same -project, as the example below demonstrates: +With project-scoped clusters we can also restrict projects to only allow applications whose destinations belong to the same project. The default behavior allows for applications to be installed onto clusters which are not a part of the same project, as the example below demonstrates: ```yaml apiVersion: argoproj.io/v1alpha1 @@ -360,12 +358,11 @@ spec: project: foo-project ``` -To prevent this behavior, we can set the attribute `permitOnlyProjectScopedClusters` on a project. +To prevent this behavior, we can set the attribute `permitOnlyProjectScopedClusters` on a project. ```yaml spec: permitOnlyProjectScopedClusters: true ``` -With this set, the application above would no longer be allowed to be synced to any cluster other than the ones which -are a part of the same project. +With this set, the application above would no longer be allowed to be synced to any cluster other than the ones which are a part of the same project. diff --git a/docs/user-guide/sync-waves.md b/docs/user-guide/sync-waves.md index 8b17237c87571..f888ac42be3f9 100644 --- a/docs/user-guide/sync-waves.md +++ b/docs/user-guide/sync-waves.md @@ -51,7 +51,5 @@ Because an application can have resources that are unhealthy in the first wave, 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 that there's currently a delay between each sync wave in order give other controllers a chance to react to the spec change -that we just applied. This also prevent Argo CD from assessing resource health too quickly (against the stale object), causing -hooks to fire prematurely. The current delay between each sync wave is 2 seconds and can be configured via environment -variable `ARGOCD_SYNC_WAVE_DELAY`. +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/examples/dashboard.json b/examples/dashboard.json index 108ac81918ba3..b21a008456e1a 100644 --- a/examples/dashboard.json +++ b/examples/dashboard.json @@ -4014,7 +4014,7 @@ "collapsed": true, "datasource": { "type": "prometheus", - "uid": "prometheus" + "uid": "$datasource" }, "gridPos": { "h": 1, @@ -4031,7 +4031,7 @@ "dashes": false, "datasource": { "type": "prometheus", - "uid": "prometheus" + "uid": "$datasource" }, "fieldConfig": { "defaults": { @@ -4078,7 +4078,7 @@ { "datasource": { "type": "prometheus", - "uid": "prometheus" + "uid": "$datasource" }, "expr": "sum(increase(argocd_redis_request_total{namespace=~\"$namespace\"}[$interval])) by (failed)", "refId": "A" @@ -4119,7 +4119,7 @@ { "datasource": { "type": "prometheus", - "uid": "prometheus" + "uid": "$datasource" }, "refId": "A" } @@ -4426,4 +4426,4 @@ "uid": "LCAgc9rWz", "version": 2, "weekStart": "" -} \ No newline at end of file +} diff --git a/go.mod b/go.mod index 667d476eabd9f..2d020f68e928a 100644 --- a/go.mod +++ b/go.mod @@ -1,118 +1,119 @@ module github.com/argoproj/argo-cd/v2 -go 1.21.0 +go 1.22.0 require ( - code.gitea.io/sdk/gitea v0.18.0 + code.gitea.io/sdk/gitea v0.19.0 github.com/Azure/kubelogin v0.0.20 - github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible - github.com/Masterminds/semver/v3 v3.2.1 - github.com/Masterminds/sprig/v3 v3.2.3 + github.com/Masterminds/semver/v3 v3.3.0 + github.com/Masterminds/sprig/v3 v3.3.0 github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d - github.com/alicebob/miniredis/v2 v2.30.4 - github.com/antonmedv/expr v1.15.2 - github.com/argoproj/gitops-engine v0.7.1-0.20240615185936-83ce6ca8cedc + github.com/alicebob/miniredis/v2 v2.33.0 + github.com/antonmedv/expr v1.15.1 + github.com/argoproj/gitops-engine v0.7.1-0.20240917171920-72bcdda3f0a5 github.com/argoproj/notifications-engine v0.4.1-0.20240606074338-0802cd427621 github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 - github.com/aws/aws-sdk-go v1.50.8 - github.com/bmatcuk/doublestar/v4 v4.6.0 + github.com/aws/aws-sdk-go v1.55.5 + github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/bombsimon/logrusr/v2 v2.0.1 - github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 - github.com/casbin/casbin/v2 v2.77.2 - github.com/cespare/xxhash/v2 v2.2.0 + github.com/bradleyfalzon/ghinstallation/v2 v2.11.0 + github.com/casbin/casbin/v2 v2.100.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.6.0 - github.com/cyphar/filepath-securejoin v0.2.4 + github.com/coreos/go-oidc/v3 v3.11.0 + github.com/cyphar/filepath-securejoin v0.3.2 github.com/dustin/go-humanize v1.0.1 github.com/evanphx/json-patch v5.9.0+incompatible - github.com/felixge/httpsnoop v1.0.3 + github.com/expr-lang/expr v1.16.9 + github.com/felixge/httpsnoop v1.0.4 github.com/fsnotify/fsnotify v1.7.0 github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e github.com/go-git/go-git/v5 v5.12.0 github.com/go-jose/go-jose/v3 v3.0.3 - github.com/go-logr/logr v1.4.1 - github.com/go-openapi/loads v0.21.2 - github.com/go-openapi/runtime v0.26.0 - github.com/go-playground/webhooks/v6 v6.3.0 + 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-20200905025246-8bb8a50cb355 github.com/gogo/protobuf v1.3.2 github.com/golang-jwt/jwt/v4 v4.5.0 github.com/golang/protobuf v1.5.4 - github.com/google/btree v1.1.2 + github.com/google/btree v1.1.3 github.com/google/go-cmp v0.6.0 - github.com/google/go-github/v35 v35.3.0 + github.com/google/go-github/v63 v63.0.0 github.com/google/go-jsonnet v0.20.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 - github.com/google/uuid v1.3.1 - github.com/gorilla/handlers v1.5.1 - github.com/gorilla/websocket v1.5.0 - github.com/gosimple/slug v1.13.1 + 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.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.4 + github.com/hashicorp/go-retryablehttp v0.7.7 github.com/imdario/mergo v0.3.16 github.com/improbable-eng/grpc-web v0.15.0 - github.com/itchyny/gojq v0.12.13 + github.com/itchyny/gojq v0.12.16 github.com/jeremywohl/flatten v1.0.1 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 - github.com/ktrysmt/go-bitbucket v0.9.67 - github.com/mattn/go-isatty v0.0.19 - github.com/mattn/go-zglob v0.0.4 + github.com/ktrysmt/go-bitbucket v0.9.80 + github.com/mattn/go-isatty v0.0.20 + github.com/mattn/go-zglob v0.0.6 github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5 github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 github.com/olekukonko/tablewriter v0.0.5 github.com/patrickmn/go-cache v2.1.0+incompatible - github.com/prometheus/client_golang v1.18.0 + github.com/prometheus/client_golang v1.20.4 github.com/r3labs/diff v1.1.0 - github.com/redis/go-redis/v9 v9.0.5 + github.com/redis/go-redis/v9 v9.6.1 github.com/robfig/cron/v3 v3.0.1 github.com/sirupsen/logrus v1.9.3 github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c github.com/soheilhy/cmux v0.1.5 - github.com/spf13/cobra v1.7.0 + github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 github.com/valyala/fasttemplate v1.2.2 - github.com/xanzy/go-gitlab v0.91.1 - github.com/yuin/gopher-lua v1.1.0 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 - go.opentelemetry.io/otel v1.21.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 - go.opentelemetry.io/otel/sdk v1.21.0 - golang.org/x/crypto v0.23.0 + github.com/xanzy/go-gitlab v0.109.0 + github.com/yuin/gopher-lua v1.1.1 + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 + go.opentelemetry.io/otel v1.30.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 + go.opentelemetry.io/otel/sdk v1.30.0 + golang.org/x/crypto v0.27.0 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 - golang.org/x/net v0.25.0 - golang.org/x/oauth2 v0.12.0 - golang.org/x/sync v0.5.0 - golang.org/x/term v0.20.0 - golang.org/x/time v0.5.0 - google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d - google.golang.org/grpc v1.59.0 - google.golang.org/protobuf v1.33.0 + golang.org/x/net v0.29.0 + golang.org/x/oauth2 v0.23.0 + golang.org/x/sync v0.8.0 + golang.org/x/term v0.24.0 + golang.org/x/time v0.6.0 + google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 + google.golang.org/grpc v1.67.0 + google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.29.6 - k8s.io/apiextensions-apiserver v0.29.6 - k8s.io/apimachinery v0.29.6 - k8s.io/apiserver v0.29.6 - k8s.io/client-go v0.29.6 - k8s.io/code-generator v0.29.6 - k8s.io/klog/v2 v2.110.1 - k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 - k8s.io/kubectl v0.29.6 - k8s.io/utils v0.0.0-20230726121419-3b25d923346b + 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-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.3.0 - sigs.k8s.io/controller-runtime v0.17.2 + oras.land/oras-go/v2 v2.5.0 + sigs.k8s.io/controller-runtime v0.19.0 sigs.k8s.io/structured-merge-diff/v4 v4.4.1 sigs.k8s.io/yaml v1.4.0 ) require ( - dario.cat/mergo v1.0.0 // indirect + dario.cat/mergo v1.0.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 // indirect @@ -133,36 +134,37 @@ require ( 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 v3.2.2+incompatible // indirect github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-github/v62 v62.0.0 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect - github.com/tidwall/gjson v1.14.4 // indirect - github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect + github.com/x448/float16 v0.8.4 // indirect go.opencensus.io v0.24.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect - golang.org/x/tools v0.16.1 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/api v0.132.0 // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/retry.v1 v1.0.3 // indirect + k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect k8s.io/klog v1.0.0 // indirect nhooyr.io/websocket v1.8.7 // indirect ) require ( - cloud.google.com/go/compute v1.23.0 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/compute/metadata v0.5.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.29 // indirect @@ -180,88 +182,87 @@ require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect github.com/cloudflare/circl v1.3.7 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect - github.com/davecgh/go-spew v1.1.1 // 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/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // 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.8.0 // 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/fvbommel/sortorder v1.1.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/analysis v0.21.4 // indirect - github.com/go-openapi/errors v0.20.3 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/spec v0.20.8 // indirect - github.com/go-openapi/strfmt v0.21.7 // indirect - github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-openapi/validate v0.22.1 // indirect + github.com/go-openapi/analysis v0.23.0 // indirect + github.com/go-openapi/errors v0.22.0 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/spec v0.21.0 // indirect + 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/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 // indirect - github.com/golang/glog v1.1.2 // 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-github/v53 v53.2.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/gosimple/unidecode v1.0.1 // indirect github.com/gregdel/pushover v1.2.1 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/huandu/xstrings v1.3.3 // indirect + github.com/huandu/xstrings v1.5.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/itchyny/timefmt-go v0.1.5 // 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.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/klauspost/compress v1.16.5 // 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/malexdev/utfutil v0.0.0-20180510171754-00c8d4a8e7a8 // indirect - github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/mitchellh/copystructure v1.0.0 // 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.0 // indirect - github.com/moby/spdystream v0.2.0 // indirect - github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // 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/oklog/ulid v1.3.1 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc4 // 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.0 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.5.0 - github.com/prometheus/common v0.45.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect - github.com/rivo/uniseg v0.4.4 // indirect - github.com/rs/cors v1.9.0 // indirect + github.com/pkg/errors v0.9.1 + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // 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.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.2.0 // indirect + github.com/shopspring/decimal v1.4.0 // indirect github.com/skeema/knownhosts v1.2.2 // indirect github.com/slack-go/slack v0.12.2 // indirect - github.com/spf13/cast v1.6.0 // 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 @@ -269,34 +270,31 @@ require ( github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xlab/treeprint v1.2.0 // indirect - go.mongodb.org/mongo-driver v1.11.3 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.21.0 // indirect - go.opentelemetry.io/otel/trace v1.21.0 // indirect - go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.mongodb.org/mongo-driver v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 // indirect + go.opentelemetry.io/otel/metric v1.30.0 // indirect + go.opentelemetry.io/otel/trace v1.30.0 // indirect + go.opentelemetry.io/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/appengine v1.6.7 // indirect + google.golang.org/appengine v1.6.8 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect - k8s.io/cli-runtime v0.29.6 // indirect - k8s.io/component-base v0.29.6 // indirect - k8s.io/component-helpers v0.29.6 // indirect - k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 // indirect - k8s.io/kube-aggregator v0.29.6 // indirect - k8s.io/kubernetes v1.29.6 // 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.13.5-0.20230601165947-6ce0bf390ce3 // indirect - sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/api v0.17.2 // indirect + sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect ) replace ( - // https://github.com/golang/go/issues/33546#issuecomment-519656923 - github.com/go-check/check => github.com/go-check/check v0.0.0-20180628173108-788fd7840127 - 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 @@ -308,34 +306,35 @@ replace ( // Avoid CVE-2022-28948 gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1 - k8s.io/api => k8s.io/api v0.29.6 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.29.6 - k8s.io/apimachinery => k8s.io/apimachinery v0.29.6 - k8s.io/apiserver => k8s.io/apiserver v0.29.6 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.29.6 - k8s.io/client-go => k8s.io/client-go v0.29.6 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.29.6 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.29.6 - k8s.io/code-generator => k8s.io/code-generator v0.29.6 - k8s.io/component-base => k8s.io/component-base v0.29.6 - k8s.io/component-helpers => k8s.io/component-helpers v0.29.6 - k8s.io/controller-manager => k8s.io/controller-manager v0.29.6 - k8s.io/cri-api => k8s.io/cri-api v0.29.6 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.29.6 - k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.29.6 - k8s.io/endpointslice => k8s.io/endpointslice v0.29.6 - k8s.io/kms => k8s.io/kms v0.29.6 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.29.6 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.29.6 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.29.6 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.29.6 - k8s.io/kubectl => k8s.io/kubectl v0.29.6 - k8s.io/kubelet => k8s.io/kubelet v0.29.6 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.29.6 - k8s.io/metrics => k8s.io/metrics v0.29.6 - k8s.io/mount-utils => k8s.io/mount-utils v0.29.6 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.29.6 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.29.6 - k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.29.6 - k8s.io/sample-controller => k8s.io/sample-controller v0.29.6 + k8s.io/api => k8s.io/api v0.31.0 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.31.0 + k8s.io/apimachinery => k8s.io/apimachinery v0.31.0 + k8s.io/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 58bf8a9315598..74da7903bd3dd 100644 --- a/go.sum +++ b/go.sum @@ -1,609 +1,13 @@ 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.44.3/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 v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= -cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= -cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= -cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= -cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= -cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= -cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= -cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw= -cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= -cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= -cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= -cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= -cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= -cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= -cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= -cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= -cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= -cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= -cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= -cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= -cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= -cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= -cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= -cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= -cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= -cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= -cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= -cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= -cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= -cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= -cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= -cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= -cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= -cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= -cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= -cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= -cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= -cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= -cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= -cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= -cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= -cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= -cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= -cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= -cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= -cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= -cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= -cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= -cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= -cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= -cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= -cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI= -cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= -cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= -cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= -cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= -cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= -cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= -cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= -cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= -cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= -cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= -cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= -cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= -cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= -cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= -cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= -cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= -cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= -cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= -cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= -cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= -cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= -cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= -cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= -cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= -cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= -cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= -cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= -cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= -cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= -cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= -cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= -cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= -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/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= -cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= -cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= -cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E= -cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= -cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= -cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= -cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= -cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= -cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= -cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= -cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= -cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= -cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= -cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= -cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= -cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= -cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= -cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= -cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= -cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= -cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= -cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= -cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= -cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= -cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= -cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= -cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= -cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= -cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= -cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= -cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= -cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= -cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= -cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= -cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= -cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= -cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= -cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= -cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= -cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= -cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= -cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= -cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= -cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= -cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= -cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= -cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= -cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= -cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= -cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= -cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= -cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= -cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= -cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= -cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= -cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= -cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= -cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= -cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= -cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= -cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= -cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= -cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= -cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= -cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= -cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= -cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= -cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= -cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= -cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= -cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= -cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= -cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= -cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= -cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= -cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= -cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= -cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= -cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= -cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= -cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= -cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= -cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= -cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= -cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= -cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= -cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= -cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= -cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= -cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= -cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= -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/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= -cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= -cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= -cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= -cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= -cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= -cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= -cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= -cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= -cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= -cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= -cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= -cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= -cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= -cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= -cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= -cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= -cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= -cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= -cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= -cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= -cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= -cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= -cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= -cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= -cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= -cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= -cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= -cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= -cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= -cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= -cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= -cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= -cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= -cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= -cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= -cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= -cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= -cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= -cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= -cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= -cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= -cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= -cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= -cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= -cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= -cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= -cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= -cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= -cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= -cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= -cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= -cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= -cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= -cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= -cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= -cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= -cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= -cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= -cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= -cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= -cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= -cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= -cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= -cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= -cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= -cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= -cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= -cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= -cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= -cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= -cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= -cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= -cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= -cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= -cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= -cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= -cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= -cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= -cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= -cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= -cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= -cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= -cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= -cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= -cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= -cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= -cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= -cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= -cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= -cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= -cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= -cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= -cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= -cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= -cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= -cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= -cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= -cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= -cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= -cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= -cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg= -cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= -cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= -cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= -cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= -cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= -cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= -cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= -cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= -cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= -cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= -cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= -cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= -cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= -cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= -cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= -cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= -cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= -cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= -cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= -cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= -cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= -cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= -cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= -cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= -cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= -cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= -cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= -cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= -cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= -cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= -cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= -cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= -cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= -cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= -cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= -cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= -cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= -cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= -cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= -cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= -cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= -cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= -cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= -cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= -cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= -cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= -cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= -cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= -cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= -cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= -cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= -cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= -cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= -cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= -cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= -cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= -cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= -cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= -cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= -cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= -cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= -cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= -cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= -cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= -cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= -cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= -cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= -cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= -cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= -cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= -cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= -cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= -cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= -cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= -cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= -cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= -cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= -cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= -cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= -cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= -cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= -cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= -cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= -cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= -cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= -cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= -cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= -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/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= -cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= -cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= -cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= -cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= -cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= -cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= -cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= -cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= -cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= -cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= -cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= -cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= -cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= -cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= -cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= -cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= -cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= -cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= -cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= -cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= -cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= -cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= -cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= -cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= -cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= -cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= -cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= -cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= -cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= -cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= -cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= -cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= -cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= -cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= -cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= -cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= -cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= -cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= -cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= -cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= -cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= -cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= -cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= -cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= -cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= -cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= -cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= -cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= -cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= -cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= -cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= -cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= -cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= -cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= -cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= -cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= -cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= -cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= -cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= -cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= -cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= -cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= -cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= -cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= -cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= -cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= -cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= -cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= -cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= -cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= -cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= -cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= -cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= -cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= -cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= -cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= -cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= -cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= -cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= -cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= -cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= -cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= -cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= -cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= -cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= -cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= -cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= -cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= -cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= -cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= -cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= -cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= -cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= -cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= -cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= -cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= -cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= -cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= -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= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= -cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= -cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= -cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= -cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= -cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= -cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= -cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= -cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= -cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= -cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= -cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= -cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= -cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= -cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= -cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= -cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= -cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= -cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= -cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= -cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= -cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= -cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= -cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= -cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= -cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= -cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= -cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= -cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= -cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= -cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= -cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= -cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= -cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= -cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= -cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= -cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= -cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= -cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= -cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= -cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= -cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= -cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= -cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= -cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= -cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= -cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= -cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= -cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= -cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= -cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= -cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= -cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= -cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= -cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= -cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= -cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= -cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= -cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= -cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= -cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= -cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= -cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= -cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= -cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= -cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= -cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= -cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= -cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= -code.gitea.io/sdk/gitea v0.18.0 h1:+zZrwVmujIrgobt6wVBWCqITz6bn1aBjnCUHmpZrerI= -code.gitea.io/sdk/gitea v0.18.0/go.mod h1:IG9xZJoltDNeDSW0qiF2Vqx5orMWa7OhVWrjvrd5NpI= -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +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= -gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= -git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.1 h1:tz19qLF65vuu2ibfTqGVJxG/zZAI27NEIIbvAOQwYbw= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.1/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 h1:QkAcEIAKbNL4KoFr4SathZPhDhF4mVwpBMFlYjyAqy8= @@ -636,32 +40,25 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 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/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= 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= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= -github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= -github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/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.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/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= 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 v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= 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= @@ -670,10 +67,6 @@ github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d h1:WtAMR0fPCOfK7 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/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= -github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= 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= @@ -681,22 +74,18 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= 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.30.4 h1:8S4/o1/KoUArAGbGwPxcwf0krlzceva2XVOSchFS7Eo= -github.com/alicebob/miniredis/v2 v2.30.4/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6uH3VlUfb/HS5zKg= -github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +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.2 h1:afFXpDWIC2n3bF+kTZE1JvFo+c34uaM3sTqh8z0xfdU= -github.com/antonmedv/expr v1.15.2/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4JUv1ihsE= -github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= -github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= +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/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE= -github.com/argoproj/gitops-engine v0.7.1-0.20240615185936-83ce6ca8cedc h1:J7LJp2Gh9A9/eQN7Lg74JW+YOVO5NEjq5/cudGAiOwk= -github.com/argoproj/gitops-engine v0.7.1-0.20240615185936-83ce6ca8cedc/go.mod h1:ByLmH5B1Gs361tgI5x5f8oSFuBEXDYENYpG3zFDWtHU= +github.com/argoproj/gitops-engine v0.7.1-0.20240917171920-72bcdda3f0a5 h1:K/e+NsNmE4BccRu21QpqUxkTHxU9YWjU3M775Ck+V/E= +github.com/argoproj/gitops-engine v0.7.1-0.20240917171920-72bcdda3f0a5/go.mod h1:b1vuwkyMUszyUK+USUJqC8vJijnQsEPNDpC+sDdDLtM= github.com/argoproj/notifications-engine v0.4.1-0.20240606074338-0802cd427621 h1:Yg1nt+D2uDK1SL2jSlfukA4yc7db184TTN7iWy3voRE= github.com/argoproj/notifications-engine v0.4.1-0.20240606074338-0802cd427621/go.mod h1:N0A4sEws2soZjEpY4hgZpQS8mRIEw6otzwfkgc3g9uQ= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= @@ -708,14 +97,13 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd 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-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= 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-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.50.8 h1:gY0WoOW+/Wz6XmYSgDH9ge3wnAevYDSQWPxxJvqAkP4= -github.com/aws/aws-sdk-go v1.50.8/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +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= @@ -754,85 +142,75 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvzIZhEXc= -github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= +github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM= github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio= -github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 h1:IRY7Xy588KylkoycsUhFpW7cdGpy5Y5BPsz4IfuJtGk= -github.com/bradleyfalzon/ghinstallation/v2 v2.6.0/go.mod h1:oQ3etOwN3TRH4EwgW5/7MxSVMGlMlzG/O8TU7eYdoSk= -github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= -github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= -github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= -github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/bradleyfalzon/ghinstallation/v2 v2.11.0 h1:R9d0v+iobRHSaE4wKUnXFiZp53AL4ED5MzgEMwGTZag= +github.com/bradleyfalzon/ghinstallation/v2 v2.11.0/go.mod h1:0LWKQwOHewXO/1acI6TtyE0Xc4ObDb2rFN7eHBAG71M= +github.com/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/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwmarrin/discordgo v0.19.0/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/casbin/casbin/v2 v2.77.2 h1:yQinn/w9x8AswiwqwtrXz93VU48R1aYTXdHEx4RI3jM= -github.com/casbin/casbin/v2 v2.77.2/go.mod h1:mzGx0hYW9/ksOSpw3wNjk3NRAroq5VMFYUQ6G43iGPk= +github.com/casbin/casbin/v2 v2.100.0 h1:aeugSNjjHfCrgA22nHkVvw2xsscboHv5r0a13ljQKGQ= +github.com/casbin/casbin/v2 v2.100.0/go.mod h1:LO7YPez4dX3LgoTCqSQAleQDo0S0BeZBDxYnPUl95Ng= +github.com/casbin/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.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +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/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= 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= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= 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.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= 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/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 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.6.0 h1:AKVxfYw1Gmkn/w96z0DbT/B/xFnzTd3MkZvWLjF4n/o= -github.com/coreos/go-oidc/v3 v3.6.0/go.mod h1:ZpHUsHBucTUj6WOkrP4E20UPynbLZzhTQ1XKCXkxyPc= +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 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= 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.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.3.2 h1:QhZu5AxQ+o1XZH0Ye05YzvJ0kAdK6VQc0z9NNMek7gc= +github.com/cyphar/filepath-securejoin v0.3.2/go.mod h1:F7i41x/9cBF7lzCrVsYs9fuzwRZm4NQsGTBdpp6mETc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= @@ -843,11 +221,11 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= 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/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0/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/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= @@ -865,38 +243,26 @@ github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4s 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/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= -github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= -github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= -github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= -github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= -github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= 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.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= -github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +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.16.9 h1:WUAzmR0JNI9JCiF0/ewwHB1gmcGw5wW7nWt8gc6PpCI= +github.com/expr-lang/expr v1.16.9/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/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +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/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +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= @@ -906,8 +272,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= -github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e h1:C3DkNr9pxqXqCrmRHO7s3XgZS3zpi9GEA01GuWZODfo= 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= @@ -922,11 +288,6 @@ github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxI github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI= github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= -github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= -github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= -github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= -github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= -github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= @@ -935,17 +296,15 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMj 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.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= -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-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 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-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= -github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= 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= @@ -957,53 +316,38 @@ github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV 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.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= 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= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= -github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= -github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= -github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= -github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU= +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/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +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 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= -github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= -github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= -github.com/go-openapi/runtime v0.26.0 h1:HYOFtG00FM1UvqrcxbEJg/SwvDRvYLQKGhw2zaQjTcc= -github.com/go-openapi/runtime v0.26.0/go.mod h1:QgRGeZwrUcSHdeh4Ka9Glvo0ug1LC5WyE+EV88plZrQ= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU= -github.com/go-openapi/spec v0.20.8/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= -github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= -github.com/go-openapi/strfmt v0.21.7 h1:rspiXgNWgeUzhjo1YU01do6qsahtJNByjLVbPLNHb8k= -github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +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= +github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs= +github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ= +github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc= +github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= +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/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= -github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= -github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +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= +github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -1011,8 +355,8 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/webhooks/v6 v6.3.0 h1:zBLUxK1Scxwi97TmZt5j/B/rLlard2zY7P77FHg58FE= -github.com/go-playground/webhooks/v6 v6.3.0/go.mod h1:GCocmfMtpJdkEOM1uG9p2nXzg1kY5X/LtvQgtPHUaaA= +github.com/go-playground/webhooks/v6 v6.4.0 h1:KLa6y7bD19N48rxJDHM0DpE3T4grV7GxMy1b/aHMWPY= +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= @@ -1020,41 +364,22 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me 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= github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +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-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= @@ -1069,41 +394,27 @@ github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzq github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= -github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= -github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +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-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.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= 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/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4/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.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +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.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= @@ -1111,12 +422,10 @@ github.com/google/go-cmp v0.2.1-0.20190312032427-6f77996f0c42/go.mod h1:8QqcDgzr 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.3/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.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= @@ -1124,12 +433,12 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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/v35 v35.3.0 h1:fU+WBzuukn0VssbayTT+Zo3/ESKX9JYWjbZTLOTEyho= -github.com/google/go-github/v35 v35.3.0/go.mod h1:yWB7uCcVWaUbUP74Aq3whuMySRMatyRmq5U9FTNlbio= 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/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/XUvTtI= -github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao= +github.com/google/go-github/v62 v62.0.0 h1:/6mGCaRywZz9MuHyw9gD1CwsbmBX8GWsbFkwMmHdhl4= +github.com/google/go-github/v62 v62.0.0/go.mod h1:EMxeUqGJq2xRu9DYBMwel/mr7kZrzUOfQmmpYrZn2a4= +github.com/google/go-github/v63 v63.0.0 h1:13xwK/wk9alSokujB9lJkuzdmQuVn2QCPeck76wR3nE= +github.com/google/go-github/v63 v63.0.0/go.mod h1:IqbcrgUmIcEaioWrGYei/09o+ge5vhffGOcxrO0AfmA= github.com/google/go-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= @@ -1139,32 +448,11 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ 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/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -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-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= -github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= -github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= 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= @@ -1173,49 +461,29 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ 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.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= -github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= -github.com/googleapis/gax-go/v2 v2.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.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= -github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= -github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= -github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= -github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= -github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= 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.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +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.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 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gosimple/slug v1.13.1 h1:bQ+kpX9Qa6tHRaK+fZR0A0M2Kd7Pa5eHPPsb1JpHD+Q= -github.com/gosimple/slug v1.13.1/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= +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.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.2.1 h1:IPPJCdzXz60gMqnlzS0ZAW5z5aS1gI4nU+YM0Pe+ssA= @@ -1231,10 +499,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/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= @@ -1242,14 +508,14 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng 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 v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +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.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA= -github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +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-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= @@ -1267,14 +533,12 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p 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.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= -github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +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/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +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.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= 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= @@ -1283,10 +547,10 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/itchyny/gojq v0.12.13 h1:IxyYlHYIlspQHHTE0f3cJF0NKDMfajxViuhBLnHd/QU= -github.com/itchyny/gojq v0.12.13/go.mod h1:JzwzAqenfhrPUuwbmEz3nu3JQmFLlQTQMUcOdnu/Sf4= -github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE= -github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8= +github.com/itchyny/gojq v0.12.16 h1:yLfgLxhIr/6sJNVmYfQjTIv0jGctu6/DgDoivmxTr7g= +github.com/itchyny/gojq v0.12.16/go.mod h1:6abHbdC2uB9ogMS38XsErnfqJ94UlngIJGlRAIj4jTM= +github.com/itchyny/timefmt-go v0.1.6 h1:ia3s54iciXDdzWzwaVKXZPbiXzxxnv1SPGFfM/myJ5Q= +github.com/itchyny/timefmt-go v0.1.6/go.mod h1:RRDZYC5s9ErkjQvTvvU7keJjxUYzIISJGxm9/mAERQg= github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= 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= @@ -1311,17 +575,11 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.10/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/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= 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/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= 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= @@ -1329,24 +587,19 @@ github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF 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/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= 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.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= 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.0.9/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.2/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/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 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.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 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= @@ -1355,65 +608,57 @@ 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.67 h1:pFQs95TTgrwd3I9gKnas8zTYMVUOId0ZI4N0yqqMEVQ= -github.com/ktrysmt/go-bitbucket v0.9.67/go.mod h1:g4i0XvhrK5dQ+RIZAJmF0XfBvhBEn3Ibt/6YbEyXkXw= +github.com/ktrysmt/go-bitbucket v0.9.80 h1:S+vZTXKx/VG5yCaX4I3Bmwo8lxWr4ifvuHdTboHTMMc= +github.com/ktrysmt/go-bitbucket v0.9.80/go.mod h1:b8ogWEGxQMWoeFnT1ZE4aHIPGindI+9z/zAW/OVFjk0= github.com/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-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= -github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= -github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= 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.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 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/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= 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.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +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.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-zglob v0.0.4 h1:LQi2iOm0/fGgu80AioIJ/1j9w9Oh+9DZ39J4VAGzHQM= -github.com/mattn/go-zglob v0.0.4/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= +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/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= 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/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= 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/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= 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.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +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= @@ -1422,16 +667,14 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 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.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 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.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= -github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +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.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= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1441,7 +684,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= @@ -1460,7 +702,6 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE 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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= 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= @@ -1497,8 +738,10 @@ github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3Ro 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.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY= -github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw= +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= @@ -1520,14 +763,15 @@ github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+q 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.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= 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 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= 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.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= -github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +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= @@ -1538,21 +782,17 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh 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/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= 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/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= -github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= -github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= 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/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= @@ -1564,85 +804,78 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE 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/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/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.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= +github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_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.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +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.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +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.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +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 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.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o= -github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= -github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= +github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +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.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.2.2/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.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= -github.com/rs/cors v1.9.0/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/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= -github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= 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.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +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.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= 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= @@ -1665,17 +898,12 @@ github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE 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/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/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.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= 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= @@ -1703,13 +931,6 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= -github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= 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= @@ -1727,73 +948,54 @@ github.com/vmihailenco/msgpack/v5 v5.3.4 h1:qMKAwOV+meBw2Y8k9cVwAy7qErtYCwBzZ2el github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= 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/xanzy/go-gitlab v0.91.1 h1:gnV57IPGYywWer32oXKBcdmc8dVxeKl3AauV8Bu17rw= -github.com/xanzy/go-gitlab v0.91.1/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xanzy/go-gitlab v0.109.0 h1:RcRme5w8VpLXTSTTMZdVoQWY37qTJWg+gwdQl4aAttE= +github.com/xanzy/go-gitlab v0.109.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= 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/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -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.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 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.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE= -github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= -github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= +github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= -go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= -go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= -go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= -go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= +go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= go.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.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 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.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= -go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= -go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= -go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= -go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= -go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 h1:hCq2hNMwsegUvPzI7sPOvtO9cqyy5GbWt/Ybp2xrx8Q= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0/go.mod h1:LqaApwGx/oUmzsbqxkzuBvyoPpkxk3JQWnqfVrJ3wCA= +go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= +go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4= +go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= +go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= +go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= +go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= +go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= +go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= +go.opentelemetry.io/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= @@ -1812,25 +1014,17 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf 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-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= 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-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= 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-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 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.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= @@ -1841,66 +1035,32 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y 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.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +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/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/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-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= -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-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= -golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 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/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/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= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= @@ -1909,8 +1069,10 @@ 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 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/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= @@ -1922,70 +1084,35 @@ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73r 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-20190813141303-74dc4d7220e7/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-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-20201031054903-ff519b6c9102/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-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-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-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= 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.4.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.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= 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= @@ -1993,65 +1120,39 @@ 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.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/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-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= -golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= -golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= -golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= -golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= -golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= -golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/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-20190412183630-56d357773e84/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-20220601150217-0de741cfad7f/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.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/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= @@ -2060,19 +1161,12 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h 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-20190204203706-41f3e6584952/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-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/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-20190531175056-4c3a928424d2/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= @@ -2082,89 +1176,40 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w 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-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/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-20200905004654-be1d3432aa8f/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-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/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-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/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-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-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-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/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-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/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-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/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-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/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-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220624220833-87e55d714810/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-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.7.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= @@ -2172,10 +1217,16 @@ 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.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/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= @@ -2185,7 +1236,6 @@ 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.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= 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= @@ -2193,17 +1243,17 @@ 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.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +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/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/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.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= @@ -2218,93 +1268,38 @@ 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.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -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/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/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-20190206041539-40960b6deb8e/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-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/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-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -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-20190927191325-030b2cf1153e/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-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-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-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-20200103221440-774c71fcf114/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-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-20200505023115-26f46d2f7ef8/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-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= 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.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= 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= @@ -2312,15 +1307,17 @@ 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 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= 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 h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= 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-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= 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= @@ -2329,315 +1326,68 @@ 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= -gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= -gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= -gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -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.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= -google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= -google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= -google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= -google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= -google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= -google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= -google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= -google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= -google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= -google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= -google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjYK+5E= -google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= -google.golang.org/api v0.124.0/go.mod h1:xu2HQurE5gi/3t1aFCvhPD781p0a3p11sdunTJ2BlP4= -google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= google.golang.org/api v0.132.0 h1:8t2/+qZ26kAOGSmOiHwVycqVaDg7q3JDILrNi/Z6rvc= google.golang.org/api v0.132.0/go.mod h1:AeTBC6GpJnJSRJjktDcPX0QwtS8pGYZOV6MSuSCusw0= google.golang.org/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 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-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-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 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-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/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-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= -google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= -google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= -google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= -google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= -google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= -google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= -google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= -google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= -google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= -google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= -google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q= -google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/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.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/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.31.1/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.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= -google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= +google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 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.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= 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= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/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/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= 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= @@ -2657,111 +1407,67 @@ 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= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.29.6 h1:eDxIl8+PeEpwbe2YyS5RXJ9vdn4hnKWMBf4WUJP9DQM= -k8s.io/api v0.29.6/go.mod h1:ZuUPMhJV74DJXapldbg6upaHfiOjrBb+0ffUbBi1jaw= -k8s.io/apiextensions-apiserver v0.29.6 h1:tUu1N6Zt9GT8KVcPF5aGDqfISz1mveM4yFh7eL5bxmE= -k8s.io/apiextensions-apiserver v0.29.6/go.mod h1:iw1EbwZat08I219qrQKoFMHGo7J9KxPqMpVKxCbNbCs= -k8s.io/apimachinery v0.29.6 h1:CLjJ5b0hWW7531n/njRE3rnusw3rhVGCFftPfnG54CI= -k8s.io/apimachinery v0.29.6/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y= -k8s.io/apiserver v0.29.6 h1:JxgDbpgahOgqoDOf+zVl2mI+rQcHcLQnK6YhhtsjbNs= -k8s.io/apiserver v0.29.6/go.mod h1:HrQwfPWxhwEa+n8/+5YwSF5yT2WXbeyFjqq6KEXHTX8= -k8s.io/cli-runtime v0.29.6 h1:nPbmS6ICW223S0BWTV+sK5xClWe89QB/n16/c5cJwT8= -k8s.io/cli-runtime v0.29.6/go.mod h1:5BzzwnVhtqVJvatDZmSZ6OtiSGqbdn0hKzpRbV3uf5o= -k8s.io/client-go v0.29.6 h1:5E2ebuB/p0F0THuQatyvhDvPL2SIeqwTPrtnrwKob/8= -k8s.io/client-go v0.29.6/go.mod h1:jHZcrQqDplyv20v7eu+iFM4gTpglZSZoMVcKrh8sRGg= -k8s.io/code-generator v0.29.6 h1:Z8T9VMR0mr7V5GG66c6GVAZrIiEy2uFoQwbeVeWLqPA= -k8s.io/code-generator v0.29.6/go.mod h1:7TYnI0dYItL2cKuhhgPSuF3WED9uMdELgbVXFfn/joE= -k8s.io/component-base v0.29.6 h1:XkVJI67FvBgNb/3kKqvaGKokxUrIR0RrksCPNI+JYCs= -k8s.io/component-base v0.29.6/go.mod h1:kIahZm8aw9lV8Vw17LF89REmeBrv5+QEl3v7HsrmITY= -k8s.io/component-helpers v0.29.6 h1:kG/tK0gXPXj6n3Oxn5Eul8nYzer3SejZI3ClwiWkreQ= -k8s.io/component-helpers v0.29.6/go.mod h1:Ltb44cbXci9fy9rytWwYsu8vHfi4fjyQdSwk6UlCR4E= -k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks= -k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= +k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= +k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= +k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= +k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc= +k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/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 v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.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.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-aggregator v0.29.6 h1:jZJjYF58F6kVuGC/kqLfuu7qGHqc2hoVKsDnRj26QRs= -k8s.io/kube-aggregator v0.29.6/go.mod h1:a6z0yORlXVXtGfsVB5PCjh2Soq1S7Wc6fApU6/T2eCE= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/kubectl v0.29.6 h1:hmkOMyH2uSUV16gIB3Qp2dv09fM2+PGEXz5SH1gwp7Y= -k8s.io/kubectl v0.29.6/go.mod h1:IUpyXy2OCbIMuBMAisDHM9shh5/Nseij4w+HIt0aq6A= -k8s.io/kubernetes v1.29.6 h1:jn8kA/oVOAWZOeoorx6xZ4d+KgGp+Evgi90x9bEI/DE= -k8s.io/kubernetes v1.29.6/go.mod h1:28sDhcb87LX5z3GWAKYmLrhrifxi4W9bEWua4DRTIvk= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= +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.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= -lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= -modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= -modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= -modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= -modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= -modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= -modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= -modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= -modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= -modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= -modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= -modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= -modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= -modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= -modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= -modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= -modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= -modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= -modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= -modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= -modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= -modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= -modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= -modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= -modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= -modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= 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.3.0 h1:lqX1aXdN+DAmDTKjiDyvq85cIaI4RkIKp/PghWlAGIU= -oras.land/oras-go/v2 v2.3.0/go.mod h1:GeAwLuC4G/JpNwkd+bSZ6SkDMGaaYglt6YK2WvZP7uQ= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= -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.17.2 h1:FwHwD1CTUemg0pW2otk7/U5/i5m2ymzvOXdbeGOUvw0= -sigs.k8s.io/controller-runtime v0.17.2/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= +oras.land/oras-go/v2 v2.5.0 h1:o8Me9kLY74Vp5uw07QXPiitjsw7qNXi8Twd+19Zf02c= +oras.land/oras-go/v2 v2.5.0/go.mod h1:z4eisnLP530vwIOUOJeBIj0aGI0L1C3d53atvCBqZHg= +sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= +sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/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.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= -sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= -sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= +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 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/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.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= 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/gen-catalog/main.go b/hack/gen-catalog/main.go index ff3da21d6791d..c7963dbf83ab4 100644 --- a/hack/gen-catalog/main.go +++ b/hack/gen-catalog/main.go @@ -168,7 +168,7 @@ func generateCommandsDocs(out io.Writer) error { for _, c := range toolSubCommand.Commands() { var cmdDesc bytes.Buffer if err := doc.GenMarkdown(c, &cmdDesc); err != nil { - return err + return fmt.Errorf("error generating Markdown for command: %v : %w", c, err) } for _, line := range strings.Split(cmdDesc.String(), "\n") { if strings.HasPrefix(line, "### SEE ALSO") { @@ -194,19 +194,19 @@ func buildConfigFromFS(templatesDir string, triggersDir string) (map[string]serv templatesCfg := map[string]services.Notification{} err := filepath.Walk(templatesDir, func(p string, info os.FileInfo, e error) error { if e != nil { - return e + return fmt.Errorf("error navigating the templates dirctory: %s : %w", templatesDir, e) } if info.IsDir() { return nil } data, err := os.ReadFile(p) if err != nil { - return err + return fmt.Errorf("error reading the template file: %s : %w", p, err) } name := strings.Split(path.Base(p), ".")[0] var template services.Notification if err := yaml.Unmarshal(data, &template); err != nil { - return err + return fmt.Errorf("error unmarshaling the data from file: %s : %w", p, err) } templatesCfg[name] = template return nil @@ -218,19 +218,19 @@ func buildConfigFromFS(templatesDir string, triggersDir string) (map[string]serv triggersCfg := map[string][]triggers.Condition{} err = filepath.Walk(triggersDir, func(p string, info os.FileInfo, e error) error { if e != nil { - return e + return fmt.Errorf("error navigating the triggers dirctory: %s : %w", triggersDir, e) } if info.IsDir() { return nil } data, err := os.ReadFile(p) if err != nil { - return err + return fmt.Errorf("error reading the trigger file: %s : %w", p, err) } name := strings.Split(path.Base(p), ".")[0] var trigger []triggers.Condition if err := yaml.Unmarshal(data, &trigger); err != nil { - return err + return fmt.Errorf("error unmarshaling the data from file: %s : %w", p, err) } triggersCfg[name] = trigger return nil diff --git a/hack/gen-docs/main.go b/hack/gen-docs/main.go index c641e833417d3..c39f4628a432c 100644 --- a/hack/gen-docs/main.go +++ b/hack/gen-docs/main.go @@ -37,7 +37,7 @@ func updateMkDocsNav(parent string, child string, subchild string, files []strin sort.Strings(files) data, err := os.ReadFile("mkdocs.yml") if err != nil { - return err + return fmt.Errorf("error reading mkdocs.yml: %w", err) } var un unstructured.Unstructured if e := yaml.Unmarshal(data, &un.Object); e != nil { @@ -46,12 +46,12 @@ func updateMkDocsNav(parent string, child string, subchild string, files []strin nav := un.Object["nav"].([]interface{}) rootitem, _ := findNavItem(nav, parent) if rootitem == nil { - return fmt.Errorf("Can't find '%s' root item in mkdoc.yml", parent) + return fmt.Errorf("can't find '%s' root item in mkdoc.yml", parent) } rootnavitemmap := rootitem.(map[interface{}]interface{}) childnav, _ := findNavItem(rootnavitemmap[parent].([]interface{}), child) if childnav == nil { - return fmt.Errorf("Can't find '%s' chile item under '%s' parent item in mkdoc.yml", child, parent) + return fmt.Errorf("can't find '%s' chile item under '%s' parent item in mkdoc.yml", child, parent) } childnavmap := childnav.(map[interface{}]interface{}) @@ -63,7 +63,7 @@ func updateMkDocsNav(parent string, child string, subchild string, files []strin childnavmap[child] = append(childnavitems, commands) newmkdocs, err := yaml.Marshal(un.Object) if err != nil { - return err + return fmt.Errorf("error in marshaling final configmap: %w", err) } // The marshaller drops custom tags, so re-add this one. Turns out this is much less invasive than trying to handle diff --git a/hack/gen-resources/generators/cluster_generator.go b/hack/gen-resources/generators/cluster_generator.go index 6f125723c35ef..ff5e03e8755fe 100644 --- a/hack/gen-resources/generators/cluster_generator.go +++ b/hack/gen-resources/generators/cluster_generator.go @@ -139,7 +139,7 @@ func (cg *ClusterGenerator) getClusterCredentials(namespace string, releaseSuffi // TODO: also should provision service for vcluster pod func (cg *ClusterGenerator) installVCluster(opts *util.GenerateOpts, namespace string, releaseName string) error { - cmd, err := helm.NewCmd("/tmp", "v3", "") + cmd, err := helm.NewCmd("/tmp", "v3", "", "") if err != nil { return err } @@ -157,22 +157,22 @@ func (cg *ClusterGenerator) getClusterServerUri(namespace string, releaseSuffix return "", err } // TODO: should be moved to service instead pod - log.Printf("Get service for https://" + pod.Status.PodIP + ":8443") + log.Printf("Get service for https://%s:8443", pod.Status.PodIP) return "https://" + pod.Status.PodIP + ":8443", nil } -func (cg *ClusterGenerator) retrieveClusterUri(namespace, releaseSuffix string) (string, error) { +func (cg *ClusterGenerator) retrieveClusterUri(namespace, releaseSuffix string) string { for i := 0; i < 10; i++ { - log.Printf("Attempting to get cluster uri") + log.Print("Attempting to get cluster uri") 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) continue } - return uri, nil + return uri } - return "", nil + return "" } func (cg *ClusterGenerator) generate(i int, opts *util.GenerateOpts) error { @@ -208,11 +208,7 @@ func (cg *ClusterGenerator) generate(i int, opts *util.GenerateOpts) error { log.Print("Get cluster server uri") - uri, err := cg.retrieveClusterUri(namespace, releaseSuffix) - if err != nil { - return err - } - + uri := cg.retrieveClusterUri(namespace, releaseSuffix) log.Printf("Cluster server uri is %s", uri) log.Print("Create cluster") diff --git a/hack/gen-resources/util/gen_options_parser.go b/hack/gen-resources/util/gen_options_parser.go index 8446dd5c07754..22c36ab661a58 100644 --- a/hack/gen-resources/util/gen_options_parser.go +++ b/hack/gen-resources/util/gen_options_parser.go @@ -1,6 +1,7 @@ package util import ( + "fmt" "os" "gopkg.in/yaml.v2" @@ -55,7 +56,7 @@ func setDefaults(opts *GenerateOpts) { func Parse(opts *GenerateOpts, file string) error { fp, err := os.ReadFile(file) if err != nil { - return err + return fmt.Errorf("error reading the template file: %s : %w", file, err) } if e := yaml.Unmarshal(fp, &opts); e != nil { diff --git a/hack/generate-actions-list.sh b/hack/generate-actions-list.sh new file mode 100755 index 0000000000000..61b0b4c7aa5ce --- /dev/null +++ b/hack/generate-actions-list.sh @@ -0,0 +1 @@ +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 new file mode 100755 index 0000000000000..0371b156ac139 --- /dev/null +++ b/hack/generate-mock.sh @@ -0,0 +1,18 @@ +#! /usr/bin/env bash + +set -x +set -o errexit +set -o nounset +set -o pipefail + +# shellcheck disable=SC2128 +PROJECT_ROOT=$( + cd "$(dirname "${BASH_SOURCE}")"/.. + pwd +) +PATH="${PROJECT_ROOT}/dist:${PATH}" + +# output tool versions +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 fa5d7322c7f81..83f542a9d21ab 100755 --- a/hack/generate-proto.sh +++ b/hack/generate-proto.sh @@ -56,6 +56,12 @@ else protoc_include=${PROJECT_ROOT}/dist/protoc-include fi +# go-to-protobuf expects dependency proto files to be in $GOPATH/src. Copy them there. +rm -rf "${GOPATH}/src/github.com/gogo/protobuf" && mkdir -p "${GOPATH}/src/github.com/gogo" && cp -r "${PROJECT_ROOT}/vendor/github.com/gogo/protobuf" "${GOPATH}/src/github.com/gogo" +rm -rf "${GOPATH}/src/k8s.io/apimachinery" && mkdir -p "${GOPATH}/src/k8s.io" && cp -r "${PROJECT_ROOT}/vendor/k8s.io/apimachinery" "${GOPATH}/src/k8s.io" +rm -rf "${GOPATH}/src/k8s.io/api" && mkdir -p "${GOPATH}/src/k8s.io" && cp -r "${PROJECT_ROOT}/vendor/k8s.io/api" "${GOPATH}/src/k8s.io" +rm -rf "${GOPATH}/src/k8s.io/apiextensions-apiserver" && mkdir -p "${GOPATH}/src/k8s.io" && cp -r "${PROJECT_ROOT}/vendor/k8s.io/apiextensions-apiserver" "${GOPATH}/src/k8s.io" + go-to-protobuf \ --go-header-file="${PROJECT_ROOT}"/hack/custom-boilerplate.go.txt \ --packages="$( @@ -68,7 +74,10 @@ go-to-protobuf \ )" \ --proto-import="${PROJECT_ROOT}"/vendor \ --proto-import="${protoc_include}" \ - --output-base="${GOPATH}/src/" + --output-dir="${GOPATH}/src/" + +# go-to-protobuf modifies vendored code. Re-vendor code so it's available for subsequent steps. +go mod vendor # Either protoc-gen-go, protoc-gen-gofast, or protoc-gen-gogofast can be used to build # server/*/.pb.go from .proto files. golang/protobuf and gogo/protobuf can be used diff --git a/hack/installers/checksums/add-protoc-checksums.sh b/hack/installers/checksums/add-protoc-checksums.sh new file mode 100755 index 0000000000000..1c13e6cfaefdf --- /dev/null +++ b/hack/installers/checksums/add-protoc-checksums.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env sh + +# Usage: ./add-protoc-checksums.sh 27.2 # use the desired version + +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" + sha256sum "protoc-$1-linux-$arch.zip" > "protoc-$1-linux-$arch.zip.sha256" + rm "protoc-$1-linux-$arch.zip" +done + +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 \ No newline at end of file diff --git a/hack/installers/checksums/kustomize_5.4.3_darwin_amd64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.4.3_darwin_amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..296ad23aa6ff2 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.4.3_darwin_amd64.tar.gz.sha256 @@ -0,0 +1 @@ +6a708ef727594bbb5f2b8f9f8049375a6028d57fa8897c1f9e78effde4e403a2 kustomize_5.4.3_darwin_amd64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.4.3_darwin_arm64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.4.3_darwin_arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..36c2d941fc11d --- /dev/null +++ b/hack/installers/checksums/kustomize_5.4.3_darwin_arm64.tar.gz.sha256 @@ -0,0 +1 @@ +3e159813a5feae46726fb22736b8764f2dbac83ba982c91ccd0244762456272c kustomize_5.4.3_darwin_arm64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.4.3_linux_amd64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.4.3_linux_amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..5dbbd76cb3a39 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.4.3_linux_amd64.tar.gz.sha256 @@ -0,0 +1 @@ +3669470b454d865c8184d6bce78df05e977c9aea31c30df3c669317d43bcc7a7 kustomize_5.4.3_linux_amd64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.4.3_linux_arm64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.4.3_linux_arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..a825d8b1a7f48 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.4.3_linux_arm64.tar.gz.sha256 @@ -0,0 +1 @@ +1b515578b0af12c15d9856720066ce2fe66756d63785b2cbccaf2885beb2381c kustomize_5.4.3_linux_arm64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.4.3_linux_ppc64le.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.4.3_linux_ppc64le.tar.gz.sha256 new file mode 100644 index 0000000000000..f258e84c6579a --- /dev/null +++ b/hack/installers/checksums/kustomize_5.4.3_linux_ppc64le.tar.gz.sha256 @@ -0,0 +1 @@ +56bbb3d0f5e499410932da0b0c347ea3dcd18006a93039e0e993b5193933e721 kustomize_5.4.3_linux_ppc64le.tar.gz diff --git a/hack/installers/checksums/kustomize_5.4.3_linux_s390x.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.4.3_linux_s390x.tar.gz.sha256 new file mode 100644 index 0000000000000..4b4e98494b45d --- /dev/null +++ b/hack/installers/checksums/kustomize_5.4.3_linux_s390x.tar.gz.sha256 @@ -0,0 +1 @@ +c575eba2f46c4701d1897a9b27c422d42d6381adb679435bc3e0d7c0da5abe44 kustomize_5.4.3_linux_s390x.tar.gz diff --git a/hack/installers/checksums/protoc-27.2-linux-aarch_64.zip.sha256 b/hack/installers/checksums/protoc-27.2-linux-aarch_64.zip.sha256 new file mode 100644 index 0000000000000..c5afce5689ae1 --- /dev/null +++ b/hack/installers/checksums/protoc-27.2-linux-aarch_64.zip.sha256 @@ -0,0 +1 @@ +ff4760bd4ae510d533e528cc6deb8e32e53f383f0ec01b0327233b4c2e8db314 protoc-27.2-linux-aarch_64.zip diff --git a/hack/installers/checksums/protoc-27.2-linux-ppcle_64.zip.sha256 b/hack/installers/checksums/protoc-27.2-linux-ppcle_64.zip.sha256 new file mode 100644 index 0000000000000..ca890c445cd74 --- /dev/null +++ b/hack/installers/checksums/protoc-27.2-linux-ppcle_64.zip.sha256 @@ -0,0 +1 @@ +35076bf2074eaef76a88546c09f4894dfe84c3f2d06615c14d87d97850f2d907 protoc-27.2-linux-ppcle_64.zip diff --git a/hack/installers/checksums/protoc-27.2-linux-s390_64.zip.sha256 b/hack/installers/checksums/protoc-27.2-linux-s390_64.zip.sha256 new file mode 100644 index 0000000000000..513a72876d311 --- /dev/null +++ b/hack/installers/checksums/protoc-27.2-linux-s390_64.zip.sha256 @@ -0,0 +1 @@ +4f01c22339734187dc7878507ee80346d63da3989908b716990f40876fc96f30 protoc-27.2-linux-s390_64.zip diff --git a/hack/installers/checksums/protoc-27.2-linux-x86_64.zip.sha256 b/hack/installers/checksums/protoc-27.2-linux-x86_64.zip.sha256 new file mode 100644 index 0000000000000..3e20c6886aef6 --- /dev/null +++ b/hack/installers/checksums/protoc-27.2-linux-x86_64.zip.sha256 @@ -0,0 +1 @@ +4a95e0ea2e51720af86a92f48d4997c8756923a9d0c58fd8a850657cd7479caf protoc-27.2-linux-x86_64.zip diff --git a/hack/installers/checksums/protoc-27.2-osx-aarch_64.zip.sha256 b/hack/installers/checksums/protoc-27.2-osx-aarch_64.zip.sha256 new file mode 100644 index 0000000000000..36e92d7242c85 --- /dev/null +++ b/hack/installers/checksums/protoc-27.2-osx-aarch_64.zip.sha256 @@ -0,0 +1 @@ +877de17b5d2662b96e68a6e208cb1851437ab3e2b419c2ef5b7b873ffac5357d protoc-27.2-osx-aarch_64.zip diff --git a/hack/installers/checksums/protoc-27.2-osx-x86_64.zip.sha256 b/hack/installers/checksums/protoc-27.2-osx-x86_64.zip.sha256 new file mode 100644 index 0000000000000..38b28b6e726ee --- /dev/null +++ b/hack/installers/checksums/protoc-27.2-osx-x86_64.zip.sha256 @@ -0,0 +1 @@ +abc25a236571612d45eb4b6b6e6abe3ac9aecc34b195f76f248786844f5619c7 protoc-27.2-osx-x86_64.zip diff --git a/hack/installers/install-codegen-go-tools.sh b/hack/installers/install-codegen-go-tools.sh index 373d6977d127a..1fd3ea5434afe 100755 --- a/hack/installers/install-codegen-go-tools.sh +++ b/hack/installers/install-codegen-go-tools.sh @@ -52,3 +52,6 @@ go install github.com/go-swagger/go-swagger/cmd/swagger@v0.28.0 # goimports is used to auto-format generated code go install golang.org/x/tools/cmd/goimports@v0.1.8 + +# mockery is used to generate mock +go install github.com/vektra/mockery/v2@v2.43.2 \ No newline at end of file diff --git a/hack/installers/install-protoc.sh b/hack/installers/install-protoc.sh index 82d491c81c3c0..f0fb244064ef7 100755 --- a/hack/installers/install-protoc.sh +++ b/hack/installers/install-protoc.sh @@ -34,7 +34,7 @@ case $OS in ;; esac -export TARGET_FILE=protoc_${protoc_version}_${OS}_${ARCHITECTURE}.zip +export TARGET_FILE=protoc-${protoc_version}-${protoc_os}-${protoc_arch}.zip url=https://github.com/protocolbuffers/protobuf/releases/download/v${protoc_version}/protoc-${protoc_version}-${protoc_os}-${protoc_arch}.zip [ -e $DOWNLOADS/${TARGET_FILE} ] || curl -sLf --retry 3 -o $DOWNLOADS/${TARGET_FILE} ${url} $(dirname $0)/compare-chksum.sh diff --git a/hack/known_types/main.go b/hack/known_types/main.go index e6647396c3c39..247fadffd908c 100644 --- a/hack/known_types/main.go +++ b/hack/known_types/main.go @@ -42,7 +42,7 @@ func newCommand() *cobra.Command { imprt := importer.ForCompiler(token.NewFileSet(), "source", nil) pkg, err := imprt.Import(packagePath) if err != nil { - return err + return fmt.Errorf("error while importing the package at: %s : %w", packagePath, err) } shortPackagePath := strings.TrimPrefix(packagePath, packagePrefix) @@ -78,7 +78,7 @@ func init() {%s }`, strings.Join(mapItems, "")) if docsOutputPath != "" { if err = os.WriteFile(docsOutputPath, []byte(strings.Join(docs, "\n")), 0o644); err != nil { - return err + return fmt.Errorf("error while writing to the %s: %w", docsOutputPath, err) } } diff --git a/hack/start-redis-with-password.sh b/hack/start-redis-with-password.sh new file mode 100755 index 0000000000000..e42ecaf28f54d --- /dev/null +++ b/hack/start-redis-with-password.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Default values for environment variables +REDIS_PORT="${ARGOCD_E2E_REDIS_PORT:-6379}" +REDIS_IMAGE_TAG=$(grep 'image: redis' manifests/base/redis/argocd-redis-deployment.yaml | cut -d':' -f3) + +if [ "$ARGOCD_REDIS_LOCAL" = 'true' ]; then + if ! command -v redis-server &>/dev/null; then + echo "Redis server is not installed locally. Please install Redis or set ARGOCD_REDIS_LOCAL to false." + exit 1 + fi + + # Start local Redis server with password if defined + if [ -z "$REDIS_PASSWORD" ]; then + echo "Starting local Redis server without password." + redis-server --save '' --appendonly no --port "$REDIS_PORT" + else + echo "Starting local Redis server with password." + redis-server --save '' --appendonly no --port "$REDIS_PORT" --requirepass "$REDIS_PASSWORD" + fi +else + # Run Redis in a Docker container with password if defined + if [ -z "$REDIS_PASSWORD" ]; then + echo "Starting Docker container without password." + docker run --rm --name argocd-redis -i -p "$REDIS_PORT:$REDIS_PORT" docker.io/library/redis:"$REDIS_IMAGE_TAG" --save '' --appendonly no --port "$REDIS_PORT" + else + echo "Starting Docker container with password." + docker run --rm --name argocd-redis -i -p "$REDIS_PORT:$REDIS_PORT" -e REDIS_PASSWORD="$REDIS_PASSWORD" docker.io/library/redis:"$REDIS_IMAGE_TAG" redis-server --save '' --requirepass "$REDIS_PASSWORD" --appendonly no --port "$REDIS_PORT" + fi +fi \ No newline at end of file diff --git a/hack/tool-versions.sh b/hack/tool-versions.sh index d37fad005f803..28ca1cda431da 100644 --- a/hack/tool-versions.sh +++ b/hack/tool-versions.sh @@ -14,5 +14,5 @@ helm3_version=3.15.2 kubectl_version=1.17.8 kubectx_version=0.6.3 -kustomize5_version=5.4.2 -protoc_version=3.17.3 +kustomize5_version=5.4.3 +protoc_version=27.2 diff --git a/hack/update-openapi.sh b/hack/update-openapi.sh index 0250ed45b93ac..39d821b99212a 100755 --- a/hack/update-openapi.sh +++ b/hack/update-openapi.sh @@ -20,10 +20,9 @@ VERSION="v1alpha1" openapi-gen \ --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ - --input-dirs github.com/argoproj/argo-cd/v2/pkg/apis/application/${VERSION} \ - --output-package github.com/argoproj/argo-cd/v2/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-base "${GOPATH}/src" \ + --output-dir "${GOPATH}/src" \ $@ [ -L "${GOPATH_PROJECT_ROOT}" ] && rm -rf "${GOPATH_PROJECT_ROOT}" 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 815e4123d05e3..619c4ca4817b8 100644 --- a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml +++ b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml @@ -225,6 +225,8 @@ spec: mountPath: /app/config/controller/tls - name: argocd-home mountPath: /home/argocd + - name: argocd-cmd-params-cm + mountPath: /home/argocd/params serviceAccountName: argocd-application-controller affinity: podAntiAffinity: @@ -255,3 +257,10 @@ spec: path: tls.key - key: ca.crt path: ca.crt + - name: argocd-cmd-params-cm + configMap: + optional: true + name: argocd-cmd-params-cm + items: + - key: controller.profile.enabled + path: profiler.enabled diff --git a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml index 2219f5f9b4731..ca09f482c35f7 100644 --- a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml +++ b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml @@ -234,6 +234,8 @@ spec: mountPath: /app/config/controller/tls - name: argocd-home mountPath: /home/argocd + - name: argocd-cmd-params-cm + mountPath: /home/argocd/params serviceAccountName: argocd-application-controller affinity: podAntiAffinity: @@ -264,3 +266,10 @@ spec: path: tls.key - key: ca.crt path: ca.crt + - name: argocd-cmd-params-cm + configMap: + optional: true + name: argocd-cmd-params-cm + items: + - key: controller.profile.enabled + path: profiler.enabled \ No newline at end of file diff --git a/manifests/base/applicationset-controller/argocd-applicationset-controller-deployment.yaml b/manifests/base/applicationset-controller/argocd-applicationset-controller-deployment.yaml index b24124ccb833f..6bade745f76c1 100644 --- a/manifests/base/applicationset-controller/argocd-applicationset-controller-deployment.yaml +++ b/manifests/base/applicationset-controller/argocd-applicationset-controller-deployment.yaml @@ -157,6 +157,12 @@ spec: name: argocd-cmd-params-cm key: applicationsetcontroller.enable.scm.providers optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: applicationsetcontroller.webhook.parallelism.limit + optional: true volumeMounts: - mountPath: /app/config/ssh name: ssh-known-hosts diff --git a/manifests/base/applicationset-controller/argocd-applicationset-controller-role.yaml b/manifests/base/applicationset-controller/argocd-applicationset-controller-role.yaml index 47c7ac9805a50..3eaf779dd6c31 100644 --- a/manifests/base/applicationset-controller/argocd-applicationset-controller-role.yaml +++ b/manifests/base/applicationset-controller/argocd-applicationset-controller-role.yaml @@ -27,6 +27,8 @@ rules: - appprojects verbs: - get + - list + - watch - apiGroups: - argoproj.io resources: @@ -62,4 +64,4 @@ rules: verbs: - get - list - - watch \ No newline at end of file + - watch diff --git a/manifests/base/dex/argocd-dex-server-deployment.yaml b/manifests/base/dex/argocd-dex-server-deployment.yaml index 7ff5985f44a90..f2d77c6ac1f6a 100644 --- a/manifests/base/dex/argocd-dex-server-deployment.yaml +++ b/manifests/base/dex/argocd-dex-server-deployment.yaml @@ -37,10 +37,22 @@ spec: type: RuntimeDefault containers: - name: dex - image: ghcr.io/dexidp/dex:v2.38.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always command: [/shared/argocd-dex, rundex] env: + - name: ARGOCD_DEX_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: dexserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEX_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: dexserver.log.level + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: diff --git a/manifests/base/notification/argocd-notifications-controller-deployment.yaml b/manifests/base/notification/argocd-notifications-controller-deployment.yaml index 876a207c16e42..b13acf718f93c 100644 --- a/manifests/base/notification/argocd-notifications-controller-deployment.yaml +++ b/manifests/base/notification/argocd-notifications-controller-deployment.yaml @@ -60,6 +60,12 @@ spec: key: notificationscontroller.selfservice.enabled name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: notificationscontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true workingDir: /app livenessProbe: tcpSocket: diff --git a/manifests/base/repo-server/argocd-repo-server-deployment.yaml b/manifests/base/repo-server/argocd-repo-server-deployment.yaml index 0e86acd3e3b5e..f6a073c32d6e9 100644 --- a/manifests/base/repo-server/argocd-repo-server-deployment.yaml +++ b/manifests/base/repo-server/argocd-repo-server-deployment.yaml @@ -149,6 +149,12 @@ spec: name: argocd-cmd-params-cm key: reposerver.plugin.tar.exclusions optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: + configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS valueFrom: configMapKeyRef: diff --git a/manifests/base/server/argocd-server-deployment.yaml b/manifests/base/server/argocd-server-deployment.yaml index 1107323b2e3b9..56b479fdcfd44 100644 --- a/manifests/base/server/argocd-server-deployment.yaml +++ b/manifests/base/server/argocd-server-deployment.yaml @@ -17,332 +17,371 @@ spec: spec: serviceAccountName: argocd-server containers: - - name: argocd-server - image: quay.io/argoproj/argocd:latest - imagePullPolicy: Always - args: - - /usr/local/bin/argocd-server - env: - - name: REDIS_PASSWORD - valueFrom: - secretKeyRef: - key: auth - name: argocd-redis - - name: ARGOCD_SERVER_INSECURE - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.insecure - optional: true - - name: ARGOCD_SERVER_BASEHREF - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.basehref - optional: true - - name: ARGOCD_SERVER_ROOTPATH - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.rootpath - optional: true - - name: ARGOCD_SERVER_LOGFORMAT - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.log.format - optional: true - - name: ARGOCD_SERVER_LOG_LEVEL - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.log.level - optional: true - - name: ARGOCD_SERVER_REPO_SERVER - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: repo.server - optional: true - - name: ARGOCD_SERVER_DEX_SERVER - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.dex.server - optional: true - - name: ARGOCD_SERVER_DISABLE_AUTH - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.disable.auth - optional: true - - name: ARGOCD_SERVER_ENABLE_GZIP - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.enable.gzip - optional: true - - name: ARGOCD_SERVER_REPO_SERVER_TIMEOUT_SECONDS - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.repo.server.timeout.seconds - optional: true - - name: ARGOCD_SERVER_X_FRAME_OPTIONS - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.x.frame.options - optional: true - - name: ARGOCD_SERVER_CONTENT_SECURITY_POLICY - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.content.security.policy - optional: true - - name: ARGOCD_SERVER_REPO_SERVER_PLAINTEXT - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.repo.server.plaintext - optional: true - - name: ARGOCD_SERVER_REPO_SERVER_STRICT_TLS - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.repo.server.strict.tls - optional: true - - name: ARGOCD_SERVER_DEX_SERVER_PLAINTEXT - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.dex.server.plaintext - optional: true - - name: ARGOCD_SERVER_DEX_SERVER_STRICT_TLS - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.dex.server.strict.tls - optional: true - - name: ARGOCD_TLS_MIN_VERSION - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.tls.minversion - optional: true - - name: ARGOCD_TLS_MAX_VERSION - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.tls.maxversion - optional: true - - name: ARGOCD_TLS_CIPHERS - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.tls.ciphers - optional: true - - name: ARGOCD_SERVER_CONNECTION_STATUS_CACHE_EXPIRATION - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.connection.status.cache.expiration - optional: true - - name: ARGOCD_SERVER_OIDC_CACHE_EXPIRATION - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.oidc.cache.expiration - optional: true - - name: ARGOCD_SERVER_LOGIN_ATTEMPTS_EXPIRATION - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.login.attempts.expiration - optional: true - - name: ARGOCD_SERVER_STATIC_ASSETS - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.staticassets - optional: true - - name: ARGOCD_APP_STATE_CACHE_EXPIRATION - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.app.state.cache.expiration - optional: true - - name: REDIS_SERVER - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: redis.server - optional: true - - name: REDIS_COMPRESSION - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: redis.compression - optional: true - - name: REDISDB - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: redis.db - optional: true - - name: ARGOCD_DEFAULT_CACHE_EXPIRATION - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.default.cache.expiration - optional: true - - name: ARGOCD_MAX_COOKIE_NUMBER - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.http.cookie.maxnumber - optional: true - - name: ARGOCD_SERVER_LISTEN_ADDRESS - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.listen.address - optional: true - - name: ARGOCD_SERVER_METRICS_LISTEN_ADDRESS - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.metrics.listen.address - optional: true - - name: ARGOCD_SERVER_OTLP_ADDRESS - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.address - optional: true - - name: ARGOCD_SERVER_OTLP_INSECURE - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.insecure - optional: true - - name: ARGOCD_SERVER_OTLP_HEADERS - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.headers - optional: true - - name: ARGOCD_APPLICATION_NAMESPACES - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: application.namespaces - optional: true - - name: ARGOCD_SERVER_ENABLE_PROXY_EXTENSION - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.enable.proxy.extension - optional: true - - name: ARGOCD_K8SCLIENT_RETRY_MAX - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.k8sclient.retry.max - optional: true - - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.k8sclient.retry.base.backoff - optional: true - - name: ARGOCD_API_CONTENT_TYPES - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.api.content.types - optional: true - volumeMounts: + - name: argocd-server + image: quay.io/argoproj/argocd:latest + imagePullPolicy: Always + args: + - /usr/local/bin/argocd-server + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + key: auth + name: argocd-redis + - name: ARGOCD_SERVER_INSECURE + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.insecure + optional: true + - name: ARGOCD_SERVER_BASEHREF + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.basehref + optional: true + - name: ARGOCD_SERVER_ROOTPATH + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.rootpath + optional: true + - name: ARGOCD_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.log.format + optional: true + - name: ARGOCD_SERVER_LOG_LEVEL + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.log.level + optional: true + - name: ARGOCD_SERVER_REPO_SERVER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: repo.server + optional: true + - name: ARGOCD_SERVER_DEX_SERVER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.dex.server + optional: true + - name: ARGOCD_SERVER_DISABLE_AUTH + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.disable.auth + optional: true + - name: ARGOCD_SERVER_ENABLE_GZIP + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.enable.gzip + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.repo.server.timeout.seconds + optional: true + - name: ARGOCD_SERVER_X_FRAME_OPTIONS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.x.frame.options + optional: true + - name: ARGOCD_SERVER_CONTENT_SECURITY_POLICY + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.content.security.policy + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.repo.server.plaintext + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.repo.server.strict.tls + optional: true + - name: ARGOCD_SERVER_DEX_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.dex.server.plaintext + optional: true + - name: ARGOCD_SERVER_DEX_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.dex.server.strict.tls + optional: true + - name: ARGOCD_TLS_MIN_VERSION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.tls.minversion + optional: true + - name: ARGOCD_TLS_MAX_VERSION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.tls.maxversion + optional: true + - name: ARGOCD_TLS_CIPHERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.tls.ciphers + optional: true + - name: ARGOCD_SERVER_CONNECTION_STATUS_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.connection.status.cache.expiration + optional: true + - name: ARGOCD_SERVER_OIDC_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.oidc.cache.expiration + optional: true + - name: ARGOCD_SERVER_LOGIN_ATTEMPTS_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.login.attempts.expiration + optional: true + - name: ARGOCD_SERVER_STATIC_ASSETS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.staticassets + optional: true + - name: ARGOCD_APP_STATE_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.app.state.cache.expiration + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.server + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.compression + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.db + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.default.cache.expiration + optional: true + - name: ARGOCD_MAX_COOKIE_NUMBER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.http.cookie.maxnumber + optional: true + - name: ARGOCD_SERVER_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.listen.address + optional: true + - name: ARGOCD_SERVER_METRICS_LISTEN_ADDRESS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.metrics.listen.address + optional: true + - name: ARGOCD_SERVER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.address + optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.insecure + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.headers + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: application.namespaces + optional: true + - name: ARGOCD_SERVER_ENABLE_PROXY_EXTENSION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.enable.proxy.extension + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.k8sclient.retry.max + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.k8sclient.retry.base.backoff + optional: true + - name: ARGOCD_API_CONTENT_TYPES + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.api.content.types + optional: true + - name: ARGOCD_SERVER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.webhook.parallelism.limit + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: applicationsetcontroller.allowed.scm.providers + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: applicationsetcontroller.enable.scm.providers + optional: true + volumeMounts: + - name: ssh-known-hosts + mountPath: /app/config/ssh + - name: tls-certs + mountPath: /app/config/tls + - name: argocd-repo-server-tls + mountPath: /app/config/server/tls + - name: argocd-dex-server-tls + mountPath: /app/config/dex/tls + - mountPath: /home/argocd + name: plugins-home + - mountPath: /tmp + name: tmp + - name: argocd-cmd-params-cm + mountPath: /home/argocd/params + ports: + - containerPort: 8080 + - containerPort: 8083 + livenessProbe: + httpGet: + path: /healthz?full=true + port: 8080 + initialDelaySeconds: 3 + periodSeconds: 30 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 3 + periodSeconds: 30 + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + seccompProfile: + type: RuntimeDefault + volumes: + - emptyDir: {} + name: plugins-home + - emptyDir: {} + name: tmp - name: ssh-known-hosts - mountPath: /app/config/ssh + configMap: + name: argocd-ssh-known-hosts-cm - name: tls-certs - mountPath: /app/config/tls + configMap: + name: argocd-tls-certs-cm - name: argocd-repo-server-tls - mountPath: /app/config/server/tls + secret: + secretName: argocd-repo-server-tls + optional: true + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt - name: argocd-dex-server-tls - mountPath: /app/config/dex/tls - - mountPath: /home/argocd - name: plugins-home - - mountPath: /tmp - name: tmp - ports: - - containerPort: 8080 - - containerPort: 8083 - livenessProbe: - httpGet: - path: /healthz?full=true - port: 8080 - initialDelaySeconds: 3 - periodSeconds: 30 - timeoutSeconds: 5 - readinessProbe: - httpGet: - path: /healthz - port: 8080 - initialDelaySeconds: 3 - periodSeconds: 30 - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - seccompProfile: - type: RuntimeDefault - volumes: - - emptyDir: {} - name: plugins-home - - emptyDir: {} - name: tmp - - name: ssh-known-hosts - configMap: - name: argocd-ssh-known-hosts-cm - - name: tls-certs - configMap: - name: argocd-tls-certs-cm - - name: argocd-repo-server-tls - secret: - secretName: argocd-repo-server-tls - optional: true - items: - - key: tls.crt - path: tls.crt - - key: tls.key - path: tls.key - - key: ca.crt - path: ca.crt - - name: argocd-dex-server-tls - secret: - secretName: argocd-dex-server-tls - optional: true - items: - - key: tls.crt - path: tls.crt - - key: ca.crt - path: ca.crt + secret: + secretName: argocd-dex-server-tls + optional: true + items: + - key: tls.crt + path: tls.crt + - key: ca.crt + path: ca.crt + - name: argocd-cmd-params-cm + configMap: + optional: true + name: argocd-cmd-params-cm + items: + - key: server.profile.enabled + path: profiler.enabled affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - podAffinityTerm: - labelSelector: - matchLabels: - app.kubernetes.io/name: argocd-server - topologyKey: kubernetes.io/hostname - - weight: 5 - podAffinityTerm: - labelSelector: - matchLabels: - app.kubernetes.io/part-of: argocd - topologyKey: kubernetes.io/hostname + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: argocd-server + topologyKey: kubernetes.io/hostname + - weight: 5 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/part-of: argocd + topologyKey: kubernetes.io/hostname diff --git a/manifests/cluster-rbac/applicationset-controller/argocd-applicationset-controller-clusterrole.yaml b/manifests/cluster-rbac/applicationset-controller/argocd-applicationset-controller-clusterrole.yaml index 259a48e7aee9e..b550e36f9ad0b 100644 --- a/manifests/cluster-rbac/applicationset-controller/argocd-applicationset-controller-clusterrole.yaml +++ b/manifests/cluster-rbac/applicationset-controller/argocd-applicationset-controller-clusterrole.yaml @@ -35,6 +35,8 @@ rules: - appprojects verbs: - get + - list + - watch - apiGroups: - "" resources: diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 63de862dd0029..b9d59aae424d0 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -234,6 +234,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -255,6 +262,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon manifest @@ -312,6 +329,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -351,6 +375,11 @@ spec: definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -570,6 +599,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -591,6 +627,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -649,6 +695,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -690,6 +743,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1025,6 +1083,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -1046,6 +1111,15 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon manifest generation @@ -1102,6 +1176,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1140,6 +1221,11 @@ spec: definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1352,6 +1438,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -1373,6 +1466,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon manifest @@ -1430,6 +1533,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1469,6 +1579,11 @@ spec: definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1844,6 +1959,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -1865,6 +1987,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -1923,6 +2055,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1964,6 +2103,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -2182,6 +2326,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -2204,6 +2355,16 @@ spec: template from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -2264,6 +2425,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -2305,6 +2473,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -2663,6 +2836,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -2687,6 +2867,16 @@ spec: not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to + the app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -2749,6 +2939,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -2791,6 +2988,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors @@ -3020,6 +3222,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -3044,6 +3253,16 @@ spec: do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults + to the app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -3108,6 +3327,13 @@ spec: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3151,6 +3377,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource @@ -3500,6 +3731,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -3522,6 +3760,16 @@ spec: template from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -3582,6 +3830,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3623,6 +3878,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -3848,6 +4108,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -3872,6 +4139,16 @@ spec: locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -3934,6 +4211,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3976,6 +4260,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4348,6 +4637,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -4370,6 +4666,16 @@ spec: template from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -4430,6 +4736,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -4471,6 +4784,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4696,6 +5014,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -4720,6 +5045,16 @@ spec: locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -4782,6 +5117,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -4824,6 +5166,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -5052,11 +5399,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5194,6 +5543,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -5205,6 +5558,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -5236,6 +5593,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -5258,6 +5619,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -5410,6 +5773,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -5421,6 +5788,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -5452,6 +5823,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -5474,6 +5849,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -5649,11 +6026,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5786,6 +6165,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -5797,6 +6180,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -5828,6 +6215,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -5850,6 +6241,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6002,6 +6395,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6013,6 +6410,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6044,6 +6445,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -6066,6 +6471,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6381,6 +6788,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6392,6 +6803,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6423,6 +6838,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -6445,6 +6864,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6597,6 +7018,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6608,6 +7033,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6639,6 +7068,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -6661,6 +7094,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6956,6 +7391,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6967,6 +7406,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6998,6 +7441,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7020,6 +7467,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -7172,6 +7621,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -7183,6 +7636,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -7214,6 +7671,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7236,6 +7697,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -7412,11 +7875,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7554,6 +8019,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -7565,6 +8034,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -7596,6 +8069,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7618,6 +8095,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -7770,9 +8249,13 @@ spec: type: object helm: properties: - fileParameters: + apiVersions: items: - properties: + type: string + type: array + fileParameters: + items: + properties: name: type: string path: @@ -7781,6 +8264,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -7812,6 +8299,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7834,6 +8325,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8009,11 +8502,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -8146,6 +8641,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8157,6 +8656,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8188,6 +8691,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -8210,6 +8717,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8362,6 +8871,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8373,6 +8886,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8404,6 +8921,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -8426,6 +8947,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8741,6 +9264,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8752,6 +9279,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8783,6 +9314,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -8805,6 +9340,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8957,6 +9494,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8968,6 +9509,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8999,6 +9544,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9021,6 +9570,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -9316,6 +9867,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -9327,6 +9882,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -9358,6 +9917,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9380,6 +9943,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -9532,6 +10097,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -9543,6 +10112,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -9574,6 +10147,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9596,6 +10173,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -9899,6 +10478,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -9910,6 +10493,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -9941,6 +10528,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9963,6 +10554,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -10115,6 +10708,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -10126,6 +10723,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -10157,6 +10758,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -10179,6 +10784,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -10437,6 +11044,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string repo: @@ -10512,6 +11146,16 @@ spec: properties: api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object insecure: type: boolean labels: @@ -10664,6 +11308,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -10675,6 +11323,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -10706,6 +11358,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -10728,6 +11384,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -10880,6 +11538,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -10891,6 +11553,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -10922,6 +11588,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -10944,6 +11614,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -11192,6 +11864,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string required: @@ -11272,6 +11971,16 @@ spec: type: boolean api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object group: type: string includeSharedProjects: @@ -11424,6 +12133,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -11435,6 +12148,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -11466,6 +12183,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -11488,6 +12209,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -11640,6 +12363,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -11651,6 +12378,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -11682,6 +12413,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -11704,6 +12439,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -11875,11 +12612,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -12014,6 +12753,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12025,6 +12768,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12056,6 +12803,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12078,6 +12829,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -12230,6 +12983,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12241,6 +12998,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12272,6 +13033,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12294,6 +13059,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -12472,11 +13239,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -12614,6 +13383,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12625,6 +13398,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12656,6 +13433,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12678,6 +13459,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -12830,6 +13613,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12841,6 +13628,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12872,6 +13663,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12894,6 +13689,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -13069,11 +13866,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -13206,6 +14005,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -13217,6 +14020,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -13248,6 +14055,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -13270,6 +14081,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -13422,6 +14235,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -13433,6 +14250,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -13464,6 +14285,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -13486,6 +14311,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -13801,6 +14628,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -13812,6 +14643,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -13843,6 +14678,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -13865,6 +14704,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14017,6 +14858,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14028,6 +14873,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -14059,6 +14908,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -14081,6 +14934,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14376,6 +15231,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14387,6 +15246,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -14418,6 +15281,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -14440,6 +15307,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14592,6 +15461,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14603,6 +15476,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -14634,6 +15511,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -14656,6 +15537,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14959,6 +15842,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14970,6 +15857,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -15001,6 +15892,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -15023,6 +15918,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -15175,6 +16072,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -15186,6 +16087,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -15217,6 +16122,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -15239,6 +16148,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -15497,6 +16408,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string repo: @@ -15572,6 +16510,16 @@ spec: properties: api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object insecure: type: boolean labels: @@ -15724,6 +16672,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -15735,6 +16687,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -15766,6 +16722,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -15788,6 +16748,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -15940,6 +16902,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -15951,6 +16917,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -15982,6 +16952,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -16004,6 +16978,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -16252,6 +17228,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string required: @@ -16332,6 +17335,16 @@ spec: type: boolean api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object group: type: string includeSharedProjects: @@ -16484,6 +17497,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -16495,6 +17512,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -16526,6 +17547,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -16548,6 +17573,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -16700,6 +17727,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -16711,6 +17742,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -16742,6 +17777,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -16764,6 +17803,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -16935,11 +17976,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -17078,6 +18121,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -17089,6 +18136,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -17120,6 +18171,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -17142,6 +18197,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -17294,6 +18351,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -17305,6 +18366,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -17336,6 +18401,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -17358,6 +18427,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -17660,6 +18731,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -17671,6 +18746,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -17702,6 +18781,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -17724,6 +18807,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -17876,6 +18961,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -17887,6 +18976,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -17918,6 +19011,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -17940,6 +19037,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -18198,6 +19297,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string repo: @@ -18273,6 +19399,16 @@ spec: properties: api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object insecure: type: boolean labels: @@ -18425,6 +19561,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -18436,6 +19576,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -18467,6 +19611,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -18489,6 +19637,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -18641,6 +19791,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -18652,6 +19806,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -18683,6 +19841,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -18705,6 +19867,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -18953,6 +20117,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string required: @@ -19033,6 +20224,16 @@ spec: type: boolean api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object group: type: string includeSharedProjects: @@ -19185,6 +20386,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -19196,6 +20401,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -19227,6 +20436,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -19249,6 +20462,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -19401,6 +20616,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -19412,6 +20631,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -19443,6 +20666,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -19465,6 +20692,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -19636,11 +20865,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -19850,6 +21081,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -19861,6 +21096,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -19892,6 +21131,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -19914,6 +21157,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -20066,6 +21311,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -20077,6 +21326,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -20108,6 +21361,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -20130,6 +21387,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -20466,6 +21725,29 @@ spec: description: description: Description contains optional project description type: string + destinationServiceAccounts: + description: DestinationServiceAccounts holds information about the + service accounts to be impersonated for the application sync operation + for each destination. + items: + description: ApplicationDestinationServiceAccount holds information + about the service account to be impersonated for the application + sync operation. + properties: + defaultServiceAccount: + description: ServiceAccountName to be used for impersonation + during the sync operation + type: string + namespace: + description: Namespace specifies the target namespace for the + application's resources. + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. + type: string + type: object + type: array destinations: description: Destinations contains list of destinations available for deployment @@ -20822,6 +22104,8 @@ rules: - appprojects verbs: - get + - list + - watch - apiGroups: - argoproj.io resources: @@ -21268,6 +22552,12 @@ spec: key: applicationsetcontroller.enable.scm.providers name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-applicationset-controller @@ -21567,6 +22857,12 @@ spec: key: reposerver.plugin.tar.exclusions name: argocd-cmd-params-cm optional: true + - configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true + name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: null - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS valueFrom: configMapKeyRef: @@ -21988,6 +23284,8 @@ spec: name: argocd-repo-server-tls - mountPath: /home/argocd name: argocd-home + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm workingDir: /home/argocd serviceAccountName: argocd-application-controller volumes: @@ -22004,6 +23302,13 @@ spec: path: ca.crt optional: true secretName: argocd-repo-server-tls + - configMap: + items: + - key: controller.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy diff --git a/manifests/crds/application-crd.yaml b/manifests/crds/application-crd.yaml index 55abcb2032ca8..5878e6eacd6a7 100644 --- a/manifests/crds/application-crd.yaml +++ b/manifests/crds/application-crd.yaml @@ -233,6 +233,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -254,6 +261,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon manifest @@ -311,6 +328,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -350,6 +374,11 @@ spec: definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -569,6 +598,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -590,6 +626,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -648,6 +694,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -689,6 +742,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1024,6 +1082,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -1045,6 +1110,15 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon manifest generation @@ -1101,6 +1175,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1139,6 +1220,11 @@ spec: definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1351,6 +1437,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -1372,6 +1465,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon manifest @@ -1429,6 +1532,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1468,6 +1578,11 @@ spec: definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1843,6 +1958,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -1864,6 +1986,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -1922,6 +2054,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1963,6 +2102,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -2181,6 +2325,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -2203,6 +2354,16 @@ spec: template from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -2263,6 +2424,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -2304,6 +2472,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -2662,6 +2835,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -2686,6 +2866,16 @@ spec: not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to + the app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -2748,6 +2938,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -2790,6 +2987,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors @@ -3019,6 +3221,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -3043,6 +3252,16 @@ spec: do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults + to the app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -3107,6 +3326,13 @@ spec: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3150,6 +3376,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource @@ -3499,6 +3730,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -3521,6 +3759,16 @@ spec: template from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -3581,6 +3829,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3622,6 +3877,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -3847,6 +4107,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -3871,6 +4138,16 @@ spec: locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -3933,6 +4210,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3975,6 +4259,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4347,6 +4636,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -4369,6 +4665,16 @@ spec: template from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -4429,6 +4735,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -4470,6 +4783,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4695,6 +5013,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -4719,6 +5044,16 @@ spec: locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -4781,6 +5116,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -4823,6 +5165,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or diff --git a/manifests/crds/applicationset-crd.yaml b/manifests/crds/applicationset-crd.yaml index 8b33949da3786..ddfa9b27be056 100644 --- a/manifests/crds/applicationset-crd.yaml +++ b/manifests/crds/applicationset-crd.yaml @@ -51,11 +51,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -193,6 +195,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -204,6 +210,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -235,6 +245,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -257,6 +271,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -409,6 +425,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -420,6 +440,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -451,6 +475,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -473,6 +501,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -648,11 +678,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -785,6 +817,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -796,6 +832,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -827,6 +867,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -849,6 +893,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -1001,6 +1047,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -1012,6 +1062,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -1043,6 +1097,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1065,6 +1123,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -1380,6 +1440,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -1391,6 +1455,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -1422,6 +1490,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1444,6 +1516,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -1596,6 +1670,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -1607,6 +1685,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -1638,6 +1720,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1660,6 +1746,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -1955,6 +2043,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -1966,6 +2058,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -1997,6 +2093,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -2019,6 +2119,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -2171,6 +2273,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -2182,6 +2288,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -2213,6 +2323,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -2235,6 +2349,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -2411,11 +2527,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -2553,6 +2671,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -2564,6 +2686,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -2595,6 +2721,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -2617,6 +2747,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -2769,6 +2901,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -2780,6 +2916,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -2811,6 +2951,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -2833,6 +2977,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -3008,11 +3154,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -3145,6 +3293,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -3156,6 +3308,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -3187,6 +3343,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3209,6 +3369,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -3361,6 +3523,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -3372,6 +3538,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -3403,6 +3573,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3425,6 +3599,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -3740,6 +3916,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -3751,6 +3931,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -3782,6 +3966,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3804,6 +3992,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -3956,6 +4146,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -3967,6 +4161,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -3998,6 +4196,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -4020,6 +4222,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -4315,6 +4519,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -4326,6 +4534,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -4357,6 +4569,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -4379,6 +4595,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -4531,6 +4749,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -4542,6 +4764,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -4573,6 +4799,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -4595,6 +4825,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -4898,6 +5130,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -4909,6 +5145,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -4940,6 +5180,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -4962,6 +5206,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -5114,6 +5360,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -5125,6 +5375,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -5156,6 +5410,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -5178,6 +5436,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -5436,6 +5696,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string repo: @@ -5511,6 +5798,16 @@ spec: properties: api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object insecure: type: boolean labels: @@ -5663,6 +5960,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -5674,6 +5975,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -5705,6 +6010,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -5727,6 +6036,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -5879,6 +6190,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -5890,6 +6205,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -5921,6 +6240,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -5943,6 +6266,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6191,6 +6516,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string required: @@ -6271,7 +6623,17 @@ spec: type: boolean api: type: string - group: + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + group: type: string includeSharedProjects: type: boolean @@ -6423,6 +6785,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6434,6 +6800,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6465,6 +6835,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -6487,6 +6861,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6639,6 +7015,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6650,6 +7030,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6681,6 +7065,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -6703,6 +7091,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6874,11 +7264,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7013,6 +7405,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -7024,6 +7420,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -7055,6 +7455,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7077,6 +7481,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -7229,6 +7635,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -7240,6 +7650,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -7271,6 +7685,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7293,6 +7711,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -7471,11 +7891,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7613,6 +8035,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -7624,6 +8050,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -7655,6 +8085,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7677,6 +8111,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -7829,6 +8265,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -7840,6 +8280,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -7871,6 +8315,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7893,6 +8341,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8068,11 +8518,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -8205,6 +8657,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8216,6 +8672,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8247,6 +8707,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -8269,6 +8733,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8421,6 +8887,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8432,6 +8902,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8463,6 +8937,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -8485,6 +8963,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8800,6 +9280,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8811,6 +9295,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8842,6 +9330,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -8864,6 +9356,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -9016,6 +9510,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -9027,6 +9525,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -9058,6 +9560,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9080,6 +9586,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -9375,6 +9883,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -9386,6 +9898,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -9417,6 +9933,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9439,6 +9959,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -9591,6 +10113,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -9602,6 +10128,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -9633,6 +10163,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9655,6 +10189,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -9958,6 +10494,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -9969,6 +10509,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -10000,6 +10544,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -10022,6 +10570,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -10174,6 +10724,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -10185,6 +10739,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -10216,6 +10774,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -10238,6 +10800,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -10496,6 +11060,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string repo: @@ -10571,6 +11162,16 @@ spec: properties: api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object insecure: type: boolean labels: @@ -10723,6 +11324,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -10734,6 +11339,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -10765,6 +11374,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -10787,6 +11400,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -10939,6 +11554,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -10950,6 +11569,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -10981,6 +11604,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -11003,6 +11630,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -11251,6 +11880,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string required: @@ -11331,6 +11987,16 @@ spec: type: boolean api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object group: type: string includeSharedProjects: @@ -11483,6 +12149,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -11494,6 +12164,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -11525,6 +12199,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -11547,6 +12225,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -11699,6 +12379,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -11710,6 +12394,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -11741,6 +12429,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -11763,6 +12455,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -11934,11 +12628,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -12077,6 +12773,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12088,6 +12788,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12119,6 +12823,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12141,6 +12849,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -12293,6 +13003,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12304,6 +13018,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12335,6 +13053,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12357,6 +13079,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -12659,6 +13383,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12670,6 +13398,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12701,6 +13433,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12723,6 +13459,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -12875,6 +13613,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12886,6 +13628,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12917,6 +13663,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12939,6 +13689,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -13197,6 +13949,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string repo: @@ -13272,6 +14051,16 @@ spec: properties: api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object insecure: type: boolean labels: @@ -13424,6 +14213,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -13435,6 +14228,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -13466,6 +14263,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -13488,6 +14289,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -13640,6 +14443,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -13651,6 +14458,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -13682,6 +14493,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -13704,6 +14519,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -13952,6 +14769,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string required: @@ -14032,6 +14876,16 @@ spec: type: boolean api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object group: type: string includeSharedProjects: @@ -14184,6 +15038,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14195,6 +15053,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -14226,6 +15088,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -14248,6 +15114,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14400,6 +15268,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14411,6 +15283,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -14442,6 +15318,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -14464,6 +15344,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14635,11 +15517,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -14849,6 +15733,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14860,6 +15748,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -14891,6 +15783,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -14913,6 +15809,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -15065,6 +15963,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -15076,6 +15978,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -15107,6 +16013,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -15129,6 +16039,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: diff --git a/manifests/crds/appproject-crd.yaml b/manifests/crds/appproject-crd.yaml index 2ebe3c2f4e325..07e98e13b5928 100644 --- a/manifests/crds/appproject-crd.yaml +++ b/manifests/crds/appproject-crd.yaml @@ -85,6 +85,29 @@ spec: description: description: Description contains optional project description type: string + destinationServiceAccounts: + description: DestinationServiceAccounts holds information about the + service accounts to be impersonated for the application sync operation + for each destination. + items: + description: ApplicationDestinationServiceAccount holds information + about the service account to be impersonated for the application + sync operation. + properties: + defaultServiceAccount: + description: ServiceAccountName to be used for impersonation + during the sync operation + type: string + namespace: + description: Namespace specifies the target namespace for the + application's resources. + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. + type: string + type: object + type: array destinations: description: Destinations contains list of destinations available for deployment diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index d77bb1b84fabb..334b2befea9f1 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -234,6 +234,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -255,6 +262,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon manifest @@ -312,6 +329,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -351,6 +375,11 @@ spec: definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -570,6 +599,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -591,6 +627,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -649,6 +695,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -690,6 +743,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1025,6 +1083,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -1046,6 +1111,15 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon manifest generation @@ -1102,6 +1176,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1140,6 +1221,11 @@ spec: definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1352,6 +1438,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -1373,6 +1466,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon manifest @@ -1430,6 +1533,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1469,6 +1579,11 @@ spec: definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1844,6 +1959,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -1865,6 +1987,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -1923,6 +2055,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1964,6 +2103,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -2182,6 +2326,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -2204,6 +2355,16 @@ spec: template from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -2264,6 +2425,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -2305,6 +2473,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -2663,6 +2836,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -2687,6 +2867,16 @@ spec: not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to + the app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -2749,6 +2939,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -2791,6 +2988,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors @@ -3020,6 +3222,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -3044,6 +3253,16 @@ spec: do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults + to the app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -3108,6 +3327,13 @@ spec: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3151,6 +3377,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource @@ -3500,6 +3731,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -3522,6 +3760,16 @@ spec: template from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -3582,6 +3830,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3623,6 +3878,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -3848,6 +4108,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -3872,6 +4139,16 @@ spec: locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -3934,6 +4211,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3976,6 +4260,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4348,6 +4637,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -4370,6 +4666,16 @@ spec: template from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -4430,6 +4736,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -4471,6 +4784,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4696,6 +5014,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -4720,6 +5045,16 @@ spec: locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -4782,6 +5117,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -4824,6 +5166,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -5052,11 +5399,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5194,6 +5543,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -5205,6 +5558,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -5236,6 +5593,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -5258,6 +5619,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -5410,6 +5773,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -5421,6 +5788,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -5452,6 +5823,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -5474,6 +5849,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -5649,11 +6026,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5786,6 +6165,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -5797,6 +6180,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -5828,6 +6215,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -5850,6 +6241,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6002,6 +6395,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6013,6 +6410,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6044,6 +6445,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -6066,6 +6471,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6381,6 +6788,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6392,6 +6803,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6423,6 +6838,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -6445,6 +6864,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6597,6 +7018,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6608,6 +7033,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6639,6 +7068,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -6661,6 +7094,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6956,6 +7391,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6967,6 +7406,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6998,6 +7441,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7020,6 +7467,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -7172,6 +7621,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -7183,6 +7636,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -7214,6 +7671,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7236,6 +7697,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -7412,11 +7875,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7554,6 +8019,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -7565,6 +8034,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -7596,6 +8069,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7618,6 +8095,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -7770,9 +8249,13 @@ spec: type: object helm: properties: - fileParameters: + apiVersions: items: - properties: + type: string + type: array + fileParameters: + items: + properties: name: type: string path: @@ -7781,6 +8264,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -7812,6 +8299,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7834,6 +8325,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8009,11 +8502,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -8146,6 +8641,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8157,6 +8656,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8188,6 +8691,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -8210,6 +8717,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8362,6 +8871,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8373,6 +8886,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8404,6 +8921,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -8426,6 +8947,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8741,6 +9264,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8752,6 +9279,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8783,6 +9314,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -8805,6 +9340,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8957,6 +9494,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8968,6 +9509,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8999,6 +9544,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9021,6 +9570,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -9316,6 +9867,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -9327,6 +9882,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -9358,6 +9917,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9380,6 +9943,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -9532,6 +10097,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -9543,6 +10112,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -9574,6 +10147,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9596,6 +10173,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -9899,6 +10478,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -9910,6 +10493,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -9941,6 +10528,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9963,6 +10554,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -10115,6 +10708,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -10126,6 +10723,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -10157,6 +10758,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -10179,6 +10784,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -10437,6 +11044,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string repo: @@ -10512,6 +11146,16 @@ spec: properties: api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object insecure: type: boolean labels: @@ -10664,6 +11308,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -10675,6 +11323,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -10706,6 +11358,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -10728,6 +11384,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -10880,6 +11538,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -10891,6 +11553,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -10922,6 +11588,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -10944,6 +11614,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -11192,6 +11864,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string required: @@ -11272,6 +11971,16 @@ spec: type: boolean api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object group: type: string includeSharedProjects: @@ -11424,6 +12133,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -11435,6 +12148,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -11466,6 +12183,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -11488,6 +12209,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -11640,6 +12363,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -11651,6 +12378,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -11682,6 +12413,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -11704,6 +12439,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -11875,11 +12612,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -12014,6 +12753,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12025,6 +12768,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12056,6 +12803,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12078,6 +12829,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -12230,6 +12983,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12241,6 +12998,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12272,6 +13033,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12294,6 +13059,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -12472,11 +13239,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -12614,6 +13383,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12625,6 +13398,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12656,6 +13433,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12678,6 +13459,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -12830,6 +13613,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12841,6 +13628,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12872,6 +13663,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12894,6 +13689,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -13069,11 +13866,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -13206,6 +14005,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -13217,6 +14020,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -13248,6 +14055,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -13270,6 +14081,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -13422,6 +14235,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -13433,6 +14250,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -13464,6 +14285,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -13486,6 +14311,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -13801,6 +14628,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -13812,6 +14643,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -13843,6 +14678,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -13865,6 +14704,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14017,6 +14858,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14028,6 +14873,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -14059,6 +14908,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -14081,6 +14934,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14376,6 +15231,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14387,6 +15246,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -14418,6 +15281,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -14440,6 +15307,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14592,6 +15461,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14603,6 +15476,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -14634,6 +15511,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -14656,6 +15537,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14959,6 +15842,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14970,6 +15857,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -15001,6 +15892,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -15023,6 +15918,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -15175,6 +16072,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -15186,6 +16087,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -15217,6 +16122,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -15239,6 +16148,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -15497,6 +16408,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string repo: @@ -15572,6 +16510,16 @@ spec: properties: api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object insecure: type: boolean labels: @@ -15724,6 +16672,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -15735,6 +16687,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -15766,6 +16722,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -15788,6 +16748,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -15940,6 +16902,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -15951,6 +16917,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -15982,6 +16952,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -16004,6 +16978,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -16252,6 +17228,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string required: @@ -16332,6 +17335,16 @@ spec: type: boolean api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object group: type: string includeSharedProjects: @@ -16484,6 +17497,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -16495,6 +17512,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -16526,6 +17547,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -16548,6 +17573,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -16700,6 +17727,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -16711,6 +17742,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -16742,6 +17777,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -16764,6 +17803,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -16935,11 +17976,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -17078,6 +18121,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -17089,6 +18136,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -17120,6 +18171,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -17142,6 +18197,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -17294,6 +18351,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -17305,6 +18366,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -17336,6 +18401,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -17358,6 +18427,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -17660,6 +18731,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -17671,6 +18746,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -17702,6 +18781,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -17724,6 +18807,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -17876,6 +18961,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -17887,6 +18976,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -17918,6 +19011,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -17940,6 +19037,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -18198,6 +19297,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string repo: @@ -18273,6 +19399,16 @@ spec: properties: api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object insecure: type: boolean labels: @@ -18425,6 +19561,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -18436,6 +19576,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -18467,6 +19611,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -18489,6 +19637,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -18641,6 +19791,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -18652,6 +19806,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -18683,6 +19841,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -18705,6 +19867,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -18953,6 +20117,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string required: @@ -19033,6 +20224,16 @@ spec: type: boolean api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object group: type: string includeSharedProjects: @@ -19185,6 +20386,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -19196,6 +20401,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -19227,6 +20436,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -19249,6 +20462,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -19401,6 +20616,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -19412,6 +20631,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -19443,6 +20666,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -19465,6 +20692,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -19636,11 +20865,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -19850,6 +21081,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -19861,6 +21096,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -19892,6 +21131,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -19914,6 +21157,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -20066,6 +21311,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -20077,6 +21326,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -20108,6 +21361,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -20130,6 +21387,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -20466,6 +21725,29 @@ spec: description: description: Description contains optional project description type: string + destinationServiceAccounts: + description: DestinationServiceAccounts holds information about the + service accounts to be impersonated for the application sync operation + for each destination. + items: + description: ApplicationDestinationServiceAccount holds information + about the service account to be impersonated for the application + sync operation. + properties: + defaultServiceAccount: + description: ServiceAccountName to be used for impersonation + during the sync operation + type: string + namespace: + description: Namespace specifies the target namespace for the + application's resources. + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. + type: string + type: object + type: array destinations: description: Destinations contains list of destinations available for deployment @@ -20860,6 +22142,8 @@ rules: - appprojects verbs: - get + - list + - watch - apiGroups: - argoproj.io resources: @@ -21108,6 +22392,8 @@ rules: - appprojects verbs: - get + - list + - watch - apiGroups: - "" resources: @@ -22609,6 +23895,12 @@ spec: key: applicationsetcontroller.enable.scm.providers name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-applicationset-controller @@ -22697,13 +23989,25 @@ spec: - /shared/argocd-dex - rundex env: + - name: ARGOCD_DEX_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: dexserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEX_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: dexserver.log.level + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.38.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always name: dex ports: @@ -22814,6 +24118,12 @@ spec: key: notificationscontroller.selfservice.enabled name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: notificationscontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -23142,6 +24452,11 @@ spec: key: reposerver.plugin.tar.exclusions name: argocd-cmd-params-cm optional: true + - configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true + name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS valueFrom: configMapKeyRef: @@ -23590,6 +24905,36 @@ spec: key: server.api.content.types name: argocd-cmd-params-cm optional: true + - name: ARGOCD_SERVER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: server.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.allowed.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.scm.providers + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -23631,6 +24976,8 @@ spec: name: plugins-home - mountPath: /tmp name: tmp + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm serviceAccountName: argocd-server volumes: - emptyDir: {} @@ -23663,6 +25010,13 @@ spec: path: ca.crt optional: true secretName: argocd-dex-server-tls + - configMap: + items: + - key: server.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm --- apiVersion: apps/v1 kind: StatefulSet @@ -23914,6 +25268,8 @@ spec: name: argocd-repo-server-tls - mountPath: /home/argocd name: argocd-home + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm workingDir: /home/argocd serviceAccountName: argocd-application-controller volumes: @@ -23930,6 +25286,13 @@ spec: path: ca.crt optional: true secretName: argocd-repo-server-tls + - configMap: + items: + - key: controller.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm --- apiVersion: apps/v1 kind: StatefulSet diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index bd0f32fdadd70..eb8efee763024 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -149,6 +149,8 @@ rules: - appprojects verbs: - get + - list + - watch - apiGroups: - argoproj.io resources: @@ -1686,6 +1688,12 @@ spec: key: applicationsetcontroller.enable.scm.providers name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-applicationset-controller @@ -1774,13 +1782,25 @@ spec: - /shared/argocd-dex - rundex env: + - name: ARGOCD_DEX_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: dexserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEX_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: dexserver.log.level + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.38.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always name: dex ports: @@ -1891,6 +1911,12 @@ spec: key: notificationscontroller.selfservice.enabled name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: notificationscontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -2219,6 +2245,11 @@ spec: key: reposerver.plugin.tar.exclusions name: argocd-cmd-params-cm optional: true + - configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true + name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS valueFrom: configMapKeyRef: @@ -2667,6 +2698,36 @@ spec: key: server.api.content.types name: argocd-cmd-params-cm optional: true + - name: ARGOCD_SERVER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: server.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.allowed.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.scm.providers + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -2708,6 +2769,8 @@ spec: name: plugins-home - mountPath: /tmp name: tmp + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm serviceAccountName: argocd-server volumes: - emptyDir: {} @@ -2740,6 +2803,13 @@ spec: path: ca.crt optional: true secretName: argocd-dex-server-tls + - configMap: + items: + - key: server.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm --- apiVersion: apps/v1 kind: StatefulSet @@ -2991,6 +3061,8 @@ spec: name: argocd-repo-server-tls - mountPath: /home/argocd name: argocd-home + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm workingDir: /home/argocd serviceAccountName: argocd-application-controller volumes: @@ -3007,6 +3079,13 @@ spec: path: ca.crt optional: true secretName: argocd-repo-server-tls + - configMap: + items: + - key: controller.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm --- apiVersion: apps/v1 kind: StatefulSet diff --git a/manifests/install.yaml b/manifests/install.yaml index 585483dbc76b0..868793d2f8e52 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -234,6 +234,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -255,6 +262,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon manifest @@ -312,6 +329,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -351,6 +375,11 @@ spec: definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -570,6 +599,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -591,6 +627,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -649,6 +695,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -690,6 +743,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1025,6 +1083,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -1046,6 +1111,15 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon manifest generation @@ -1102,6 +1176,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1140,6 +1221,11 @@ spec: definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1352,6 +1438,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -1373,6 +1466,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon manifest @@ -1430,6 +1533,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1469,6 +1579,11 @@ spec: definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -1844,6 +1959,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -1865,6 +1987,16 @@ spec: from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to template + with. If left empty, defaults to the app's destination + namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -1923,6 +2055,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -1964,6 +2103,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or not @@ -2182,6 +2326,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -2204,6 +2355,16 @@ spec: template from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -2264,6 +2425,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -2305,6 +2473,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -2663,6 +2836,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -2687,6 +2867,16 @@ spec: not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to + the app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -2749,6 +2939,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -2791,6 +2988,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors @@ -3020,6 +3222,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -3044,6 +3253,16 @@ spec: do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults + to the app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -3108,6 +3327,13 @@ spec: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3151,6 +3377,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource @@ -3500,6 +3731,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -3522,6 +3760,16 @@ spec: template from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -3582,6 +3830,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3623,6 +3878,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -3848,6 +4108,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -3872,6 +4139,16 @@ spec: locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -3934,6 +4211,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -3976,6 +4260,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4348,6 +4637,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -4370,6 +4666,16 @@ spec: template from failing when valueFiles do not exist locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace to + template with. If left empty, defaults to the app's + destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command upon @@ -4430,6 +4736,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -4471,6 +4784,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -4696,6 +5014,13 @@ spec: helm: description: Helm holds helm specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array fileParameters: description: FileParameters are file parameters to the helm template @@ -4720,6 +5045,16 @@ spec: locally by not appending them to helm template --values type: boolean + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string + namespace: + description: Namespace is an optional namespace + to template with. If left empty, defaults to the + app's destination namespace. + type: string parameters: description: Parameters is a list of Helm parameters which are passed to the helm template command @@ -4782,6 +5117,13 @@ spec: kustomize: description: Kustomize holds kustomize specific options properties: + apiVersions: + description: |- + APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -4824,6 +5166,11 @@ spec: image definition in the format [old_image_name=]: type: string type: array + kubeVersion: + description: |- + KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD + uses the Kubernetes version of the target cluster. + type: string labelWithoutSelector: description: LabelWithoutSelector specifies whether to apply common labels to resource selectors or @@ -5052,11 +5399,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5194,6 +5543,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -5205,6 +5558,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -5236,6 +5593,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -5258,6 +5619,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -5410,6 +5773,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -5421,6 +5788,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -5452,6 +5823,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -5474,6 +5849,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -5649,11 +6026,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -5786,6 +6165,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -5797,6 +6180,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -5828,6 +6215,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -5850,6 +6241,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6002,6 +6395,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6013,6 +6410,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6044,6 +6445,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -6066,6 +6471,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6381,6 +6788,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6392,6 +6803,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6423,6 +6838,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -6445,6 +6864,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6597,6 +7018,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6608,6 +7033,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6639,6 +7068,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -6661,6 +7094,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -6956,6 +7391,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -6967,6 +7406,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -6998,6 +7441,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7020,6 +7467,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -7172,6 +7621,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -7183,6 +7636,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -7214,6 +7671,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7236,6 +7697,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -7412,11 +7875,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -7554,6 +8019,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -7565,6 +8034,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -7596,6 +8069,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7618,6 +8095,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -7770,9 +8249,13 @@ spec: type: object helm: properties: - fileParameters: + apiVersions: items: - properties: + type: string + type: array + fileParameters: + items: + properties: name: type: string path: @@ -7781,6 +8264,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -7812,6 +8299,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -7834,6 +8325,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8009,11 +8502,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -8146,6 +8641,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8157,6 +8656,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8188,6 +8691,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -8210,6 +8717,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8362,6 +8871,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8373,6 +8886,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8404,6 +8921,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -8426,6 +8947,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8741,6 +9264,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8752,6 +9279,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8783,6 +9314,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -8805,6 +9340,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -8957,6 +9494,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -8968,6 +9509,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -8999,6 +9544,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9021,6 +9570,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -9316,6 +9867,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -9327,6 +9882,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -9358,6 +9917,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9380,6 +9943,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -9532,6 +10097,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -9543,6 +10112,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -9574,6 +10147,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9596,6 +10173,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -9899,6 +10478,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -9910,6 +10493,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -9941,6 +10528,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -9963,6 +10554,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -10115,6 +10708,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -10126,6 +10723,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -10157,6 +10758,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -10179,6 +10784,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -10437,6 +11044,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string repo: @@ -10512,6 +11146,16 @@ spec: properties: api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object insecure: type: boolean labels: @@ -10664,6 +11308,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -10675,6 +11323,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -10706,6 +11358,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -10728,6 +11384,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -10880,6 +11538,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -10891,6 +11553,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -10922,6 +11588,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -10944,6 +11614,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -11192,6 +11864,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string required: @@ -11272,6 +11971,16 @@ spec: type: boolean api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object group: type: string includeSharedProjects: @@ -11424,6 +12133,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -11435,6 +12148,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -11466,6 +12183,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -11488,6 +12209,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -11640,6 +12363,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -11651,6 +12378,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -11682,6 +12413,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -11704,6 +12439,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -11875,11 +12612,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -12014,6 +12753,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12025,6 +12768,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12056,6 +12803,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12078,6 +12829,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -12230,6 +12983,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12241,6 +12998,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12272,6 +13033,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12294,6 +13059,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -12472,11 +13239,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -12614,6 +13383,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12625,6 +13398,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12656,6 +13433,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12678,6 +13459,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -12830,6 +13613,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -12841,6 +13628,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -12872,6 +13663,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -12894,6 +13689,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -13069,11 +13866,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -13206,6 +14005,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -13217,6 +14020,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -13248,6 +14055,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -13270,6 +14081,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -13422,6 +14235,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -13433,6 +14250,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -13464,6 +14285,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -13486,6 +14311,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -13801,6 +14628,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -13812,6 +14643,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -13843,6 +14678,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -13865,6 +14704,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14017,6 +14858,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14028,6 +14873,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -14059,6 +14908,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -14081,6 +14934,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14376,6 +15231,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14387,6 +15246,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -14418,6 +15281,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -14440,6 +15307,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14592,6 +15461,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14603,6 +15476,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -14634,6 +15511,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -14656,6 +15537,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -14959,6 +15842,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -14970,6 +15857,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -15001,6 +15892,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -15023,6 +15918,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -15175,6 +16072,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -15186,6 +16087,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -15217,6 +16122,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -15239,6 +16148,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -15497,6 +16408,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string repo: @@ -15572,6 +16510,16 @@ spec: properties: api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object insecure: type: boolean labels: @@ -15724,6 +16672,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -15735,6 +16687,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -15766,6 +16722,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -15788,6 +16748,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -15940,6 +16902,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -15951,6 +16917,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -15982,6 +16952,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -16004,6 +16978,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -16252,6 +17228,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string required: @@ -16332,6 +17335,16 @@ spec: type: boolean api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object group: type: string includeSharedProjects: @@ -16484,6 +17497,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -16495,6 +17512,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -16526,6 +17547,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -16548,6 +17573,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -16700,6 +17727,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -16711,6 +17742,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -16742,6 +17777,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -16764,6 +17803,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -16935,11 +17976,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -17078,6 +18121,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -17089,6 +18136,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -17120,6 +18171,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -17142,6 +18197,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -17294,6 +18351,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -17305,6 +18366,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -17336,6 +18401,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -17358,6 +18427,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -17660,6 +18731,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -17671,6 +18746,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -17702,6 +18781,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -17724,6 +18807,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -17876,6 +18961,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -17887,6 +18976,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -17918,6 +19011,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -17940,6 +19037,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -18198,6 +19297,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string repo: @@ -18273,6 +19399,16 @@ spec: properties: api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object insecure: type: boolean labels: @@ -18425,6 +19561,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -18436,6 +19576,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -18467,6 +19611,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -18489,6 +19637,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -18641,6 +19791,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -18652,6 +19806,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -18683,6 +19841,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -18705,6 +19867,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -18953,6 +20117,33 @@ spec: - passwordRef - username type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object + insecure: + type: boolean project: type: string required: @@ -19033,6 +20224,16 @@ spec: type: boolean api: type: string + caRef: + properties: + configMapName: + type: string + key: + type: string + required: + - configMapName + - key + type: object group: type: string includeSharedProjects: @@ -19185,6 +20386,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -19196,6 +20401,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -19227,6 +20436,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -19249,6 +20462,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -19401,6 +20616,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -19412,6 +20631,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -19443,6 +20666,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -19465,6 +20692,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -19636,11 +20865,13 @@ spec: items: type: string type: array + x-kubernetes-list-type: atomic required: - key - operator type: object type: array + x-kubernetes-list-type: atomic matchLabels: additionalProperties: type: string @@ -19850,6 +21081,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -19861,6 +21096,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -19892,6 +21131,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -19914,6 +21157,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -20066,6 +21311,10 @@ spec: type: object helm: properties: + apiVersions: + items: + type: string + type: array fileParameters: items: properties: @@ -20077,6 +21326,10 @@ spec: type: array ignoreMissingValueFiles: type: boolean + kubeVersion: + type: string + namespace: + type: string parameters: items: properties: @@ -20108,6 +21361,10 @@ spec: type: object kustomize: properties: + apiVersions: + items: + type: string + type: array commonAnnotations: additionalProperties: type: string @@ -20130,6 +21387,8 @@ spec: items: type: string type: array + kubeVersion: + type: string labelWithoutSelector: type: boolean namePrefix: @@ -20466,6 +21725,29 @@ spec: description: description: Description contains optional project description type: string + destinationServiceAccounts: + description: DestinationServiceAccounts holds information about the + service accounts to be impersonated for the application sync operation + for each destination. + items: + description: ApplicationDestinationServiceAccount holds information + about the service account to be impersonated for the application + sync operation. + properties: + defaultServiceAccount: + description: ServiceAccountName to be used for impersonation + during the sync operation + type: string + namespace: + description: Namespace specifies the target namespace for the + application's resources. + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. + type: string + type: object + type: array destinations: description: Destinations contains list of destinations available for deployment @@ -20849,6 +22131,8 @@ rules: - appprojects verbs: - get + - list + - watch - apiGroups: - argoproj.io resources: @@ -21075,6 +22359,8 @@ rules: - appprojects verbs: - get + - list + - watch - apiGroups: - "" resources: @@ -21726,6 +23012,12 @@ spec: key: applicationsetcontroller.enable.scm.providers name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-applicationset-controller @@ -21814,13 +23106,25 @@ spec: - /shared/argocd-dex - rundex env: + - name: ARGOCD_DEX_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: dexserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEX_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: dexserver.log.level + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.38.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always name: dex ports: @@ -21931,6 +23235,12 @@ spec: key: notificationscontroller.selfservice.enabled name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: notificationscontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -22212,6 +23522,12 @@ spec: key: reposerver.plugin.tar.exclusions name: argocd-cmd-params-cm optional: true + - configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true + name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: null - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS valueFrom: configMapKeyRef: @@ -22658,6 +23974,36 @@ spec: key: server.api.content.types name: argocd-cmd-params-cm optional: true + - name: ARGOCD_SERVER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: server.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.allowed.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.scm.providers + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -22699,6 +24045,8 @@ spec: name: plugins-home - mountPath: /tmp name: tmp + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm serviceAccountName: argocd-server volumes: - emptyDir: {} @@ -22731,6 +24079,13 @@ spec: path: ca.crt optional: true secretName: argocd-dex-server-tls + - configMap: + items: + - key: server.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm --- apiVersion: apps/v1 kind: StatefulSet @@ -22982,6 +24337,8 @@ spec: name: argocd-repo-server-tls - mountPath: /home/argocd name: argocd-home + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm workingDir: /home/argocd serviceAccountName: argocd-application-controller volumes: @@ -22998,6 +24355,13 @@ spec: path: ca.crt optional: true secretName: argocd-repo-server-tls + - configMap: + items: + - key: controller.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index a1b2b31f0265d..905bd717f05b9 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -138,6 +138,8 @@ rules: - appprojects verbs: - get + - list + - watch - apiGroups: - argoproj.io resources: @@ -803,6 +805,12 @@ spec: key: applicationsetcontroller.enable.scm.providers name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-applicationset-controller @@ -891,13 +899,25 @@ spec: - /shared/argocd-dex - rundex env: + - name: ARGOCD_DEX_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: dexserver.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_DEX_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: dexserver.log.level + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_DEX_SERVER_DISABLE_TLS valueFrom: configMapKeyRef: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.38.0 + image: ghcr.io/dexidp/dex:v2.41.1 imagePullPolicy: Always name: dex ports: @@ -1008,6 +1028,12 @@ spec: key: notificationscontroller.selfservice.enabled name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + key: notificationscontroller.repo.server.plaintext + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -1289,6 +1315,12 @@ spec: key: reposerver.plugin.tar.exclusions name: argocd-cmd-params-cm optional: true + - configMapKeyRef: + key: reposerver.plugin.use.manifest.generate.paths + name: argocd-cmd-params-cm + optional: true + name: ARGOCD_REPO_SERVER_PLUGIN_USE_MANIFEST_GENERATE_PATHS + valueFrom: null - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS valueFrom: configMapKeyRef: @@ -1735,6 +1767,36 @@ spec: key: server.api.content.types name: argocd-cmd-params-cm optional: true + - name: ARGOCD_SERVER_WEBHOOK_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: server.webhook.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_NEW_GIT_FILE_GLOBBING + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.new.git.file.globbing + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_SCM_ROOT_CA_PATH + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.scm.root.ca.path + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.allowed.scm.providers + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.scm.providers + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -1776,6 +1838,8 @@ spec: name: plugins-home - mountPath: /tmp name: tmp + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm serviceAccountName: argocd-server volumes: - emptyDir: {} @@ -1808,6 +1872,13 @@ spec: path: ca.crt optional: true secretName: argocd-dex-server-tls + - configMap: + items: + - key: server.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm --- apiVersion: apps/v1 kind: StatefulSet @@ -2059,6 +2130,8 @@ spec: name: argocd-repo-server-tls - mountPath: /home/argocd name: argocd-home + - mountPath: /home/argocd/params + name: argocd-cmd-params-cm workingDir: /home/argocd serviceAccountName: argocd-application-controller volumes: @@ -2075,6 +2148,13 @@ spec: path: ca.crt optional: true secretName: argocd-repo-server-tls + - configMap: + items: + - key: controller.profile.enabled + path: profiler.enabled + name: argocd-cmd-params-cm + optional: true + name: argocd-cmd-params-cm --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy diff --git a/mkdocs.yml b/mkdocs.yml index c9eb3061d4e2e..1fea9734a8710 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -47,6 +47,7 @@ nav: - snyk/index.md - operator-manual/signed-release-assets.md - operator-manual/tls.md + - operator-manual/cluster-management.md - operator-manual/cluster-bootstrapping.md - operator-manual/secret-management.md - operator-manual/disaster_recovery.md @@ -128,6 +129,8 @@ nav: - operator-manual/server-commands/additional-configuration-method.md - Upgrading: - operator-manual/upgrading/overview.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 - operator-manual/upgrading/2.9-2.10.md - operator-manual/upgrading/2.8-2.9.md @@ -208,7 +211,7 @@ nav: - developer-guide/dependencies.md - developer-guide/ci.md - developer-guide/releasing.md - - developer-guide/site.md + - developer-guide/docs-site.md - developer-guide/static-code-analysis.md - Extensions: - developer-guide/extensions/ui-extensions.md diff --git a/notification_controller/controller/controller.go b/notification_controller/controller/controller.go index 1bc3e73a6fbd7..5137e0dfc12cb 100644 --- a/notification_controller/controller/controller.go +++ b/notification_controller/controller/controller.go @@ -122,7 +122,7 @@ func NewController( // Check if app is not in the namespace where the controller is in, and also app is not in one of the applicationNamespaces func checkAppNotInAdditionalNamespaces(app *unstructured.Unstructured, namespace string, applicationNamespaces []string) bool { - return namespace != app.GetNamespace() && !glob.MatchStringInList(applicationNamespaces, app.GetNamespace(), false) + return namespace != app.GetNamespace() && !glob.MatchStringInList(applicationNamespaces, app.GetNamespace(), glob.REGEXP) } func (c *notificationController) alterDestinations(obj v1.Object, destinations services.Destinations, cfg api.Config) services.Destinations { @@ -151,7 +151,7 @@ func newInformer(resClient dynamic.ResourceInterface, controllerNamespace string } newItems := []unstructured.Unstructured{} for _, res := range appList.Items { - if controllerNamespace == res.GetNamespace() || glob.MatchStringInList(applicationNamespaces, res.GetNamespace(), false) { + if controllerNamespace == res.GetNamespace() || glob.MatchStringInList(applicationNamespaces, res.GetNamespace(), glob.REGEXP) { newItems = append(newItems, res) } } diff --git a/notification_controller/controller/controller_test.go b/notification_controller/controller/controller_test.go index 5cef5023473aa..ca901cf2c1890 100644 --- a/notification_controller/controller/controller_test.go +++ b/notification_controller/controller/controller_test.go @@ -7,6 +7,7 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/dynamic/fake" @@ -133,7 +134,7 @@ func TestInit(t *testing.T) { err = nc.Init(ctx) - assert.NoError(t, err) + require.NoError(t, err) } } @@ -169,7 +170,7 @@ func TestInitTimeout(t *testing.T) { err = nc.Init(ctx) // Expect an error & add assertion for the error message - assert.Error(t, err) + require.Error(t, err) assert.Equal(t, "Timed out waiting for caches to sync", err.Error()) } diff --git a/pkg/apiclient/apiclient.go b/pkg/apiclient/apiclient.go index 4e0b5bce9782b..52164255164ae 100644 --- a/pkg/apiclient/apiclient.go +++ b/pkg/apiclient/apiclient.go @@ -56,12 +56,6 @@ import ( tls_util "github.com/argoproj/argo-cd/v2/util/tls" ) -// These mocks are not currently used, but they are part of the public API of this package. -//go:generate -command mockery go run github.com/vektra/mockery/v2@v2.40.2 -//go:generate mockery --dir=./session --name=SessionServiceServer --output=./session/mocks -//go:generate mockery --dir=./session --name=SessionServiceClient --output=./session/mocks -//go:generate mockery --dir=./cluster --name=ClusterServiceServer --output=./cluster/mocks - const ( MetaDataTokenKey = "token" // EnvArgoCDServer is the environment variable to look for an Argo CD server address diff --git a/pkg/apiclient/apiclient_test.go b/pkg/apiclient/apiclient_test.go index b1dc9278ce76a..221b20eb07bcc 100644 --- a/pkg/apiclient/apiclient_test.go +++ b/pkg/apiclient/apiclient_test.go @@ -4,13 +4,14 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func Test_parseHeaders(t *testing.T) { t.Run("Header parsed successfully", func(t *testing.T) { headerString := []string{"foo:", "foo1:bar1", "foo2:bar2:bar2"} headers, err := parseHeaders(headerString) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "", headers.Get("foo")) assert.Equal(t, "bar1", headers.Get("foo1")) assert.Equal(t, "bar2:bar2", headers.Get("foo2")) @@ -27,7 +28,7 @@ func Test_parseGRPCHeaders(t *testing.T) { t.Run("Header parsed successfully", func(t *testing.T) { headerStrings := []string{"origin: https://foo.bar", "content-length: 123"} headers, err := parseGRPCHeaders(headerStrings) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []string{" https://foo.bar"}, headers.Get("origin")) assert.Equal(t, []string{" 123"}, headers.Get("content-length")) }) diff --git a/pkg/apiclient/application/forwarder_overwrite.go b/pkg/apiclient/application/forwarder_overwrite.go index 9a4bcae10e5a7..4769775f9671f 100644 --- a/pkg/apiclient/application/forwarder_overwrite.go +++ b/pkg/apiclient/application/forwarder_overwrite.go @@ -116,10 +116,13 @@ func init() { if req.URL.Query().Get("download") == "true" { w.Header().Set("Content-Type", "application/octet-stream") fileName := "log" - if container := req.URL.Query().Get("container"); len(container) > 0 && kube.IsValidResourceName(container) { - fileName = container + namespace := req.URL.Query().Get("namespace") + podName := req.URL.Query().Get("podName") + container := req.URL.Query().Get("container") + if kube.IsValidResourceName(namespace) && kube.IsValidResourceName(podName) && kube.IsValidResourceName(container) { + fileName = fmt.Sprintf("%s-%s-%s", namespace, podName, container) } - w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment;filename="%s.txt"`, fileName)) + w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment;filename="%s.log"`, fileName)) for { msg, err := recv() if err != nil { diff --git a/pkg/apiclient/applicationset/applicationset.pb.go b/pkg/apiclient/applicationset/applicationset.pb.go index 68db654fe9c4e..874ed5663b7c9 100644 --- a/pkg/apiclient/applicationset/applicationset.pb.go +++ b/pkg/apiclient/applicationset/applicationset.pb.go @@ -214,6 +214,7 @@ func (m *ApplicationSetResponse) GetApplicationset() *v1alpha1.ApplicationSet { type ApplicationSetCreateRequest struct { Applicationset *v1alpha1.ApplicationSet `protobuf:"bytes,1,opt,name=applicationset,proto3" json:"applicationset,omitempty"` Upsert bool `protobuf:"varint,2,opt,name=upsert,proto3" json:"upsert,omitempty"` + DryRun bool `protobuf:"varint,3,opt,name=dryRun,proto3" json:"dryRun,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -266,6 +267,13 @@ func (m *ApplicationSetCreateRequest) GetUpsert() bool { return false } +func (m *ApplicationSetCreateRequest) GetDryRun() bool { + if m != nil { + return m.DryRun + } + return false +} + type ApplicationSetDeleteRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // The application set namespace. Default empty is argocd control plane namespace @@ -378,6 +386,103 @@ func (m *ApplicationSetTreeQuery) GetAppsetNamespace() string { return "" } +// ApplicationSetGetQuery is a query for applicationset resources +type ApplicationSetGenerateRequest struct { + // the applicationsets + ApplicationSet *v1alpha1.ApplicationSet `protobuf:"bytes,1,opt,name=applicationSet,proto3" json:"applicationSet,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ApplicationSetGenerateRequest) Reset() { *m = ApplicationSetGenerateRequest{} } +func (m *ApplicationSetGenerateRequest) String() string { return proto.CompactTextString(m) } +func (*ApplicationSetGenerateRequest) ProtoMessage() {} +func (*ApplicationSetGenerateRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_eacb9df0ce5738fa, []int{6} +} +func (m *ApplicationSetGenerateRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ApplicationSetGenerateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ApplicationSetGenerateRequest.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 *ApplicationSetGenerateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplicationSetGenerateRequest.Merge(m, src) +} +func (m *ApplicationSetGenerateRequest) XXX_Size() int { + return m.Size() +} +func (m *ApplicationSetGenerateRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ApplicationSetGenerateRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplicationSetGenerateRequest proto.InternalMessageInfo + +func (m *ApplicationSetGenerateRequest) GetApplicationSet() *v1alpha1.ApplicationSet { + if m != nil { + return m.ApplicationSet + } + return nil +} + +// ApplicationSetGenerateResponse is a response for applicationset generate request +type ApplicationSetGenerateResponse struct { + Applications []*v1alpha1.Application `protobuf:"bytes,1,rep,name=applications,proto3" json:"applications,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ApplicationSetGenerateResponse) Reset() { *m = ApplicationSetGenerateResponse{} } +func (m *ApplicationSetGenerateResponse) String() string { return proto.CompactTextString(m) } +func (*ApplicationSetGenerateResponse) ProtoMessage() {} +func (*ApplicationSetGenerateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_eacb9df0ce5738fa, []int{7} +} +func (m *ApplicationSetGenerateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ApplicationSetGenerateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ApplicationSetGenerateResponse.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 *ApplicationSetGenerateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplicationSetGenerateResponse.Merge(m, src) +} +func (m *ApplicationSetGenerateResponse) XXX_Size() int { + return m.Size() +} +func (m *ApplicationSetGenerateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ApplicationSetGenerateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplicationSetGenerateResponse proto.InternalMessageInfo + +func (m *ApplicationSetGenerateResponse) GetApplications() []*v1alpha1.Application { + if m != nil { + return m.Applications + } + return nil +} + func init() { proto.RegisterType((*ApplicationSetGetQuery)(nil), "applicationset.ApplicationSetGetQuery") proto.RegisterType((*ApplicationSetListQuery)(nil), "applicationset.ApplicationSetListQuery") @@ -385,6 +490,8 @@ func init() { proto.RegisterType((*ApplicationSetCreateRequest)(nil), "applicationset.ApplicationSetCreateRequest") proto.RegisterType((*ApplicationSetDeleteRequest)(nil), "applicationset.ApplicationSetDeleteRequest") proto.RegisterType((*ApplicationSetTreeQuery)(nil), "applicationset.ApplicationSetTreeQuery") + proto.RegisterType((*ApplicationSetGenerateRequest)(nil), "applicationset.ApplicationSetGenerateRequest") + proto.RegisterType((*ApplicationSetGenerateResponse)(nil), "applicationset.ApplicationSetGenerateResponse") } func init() { @@ -392,43 +499,49 @@ func init() { } var fileDescriptor_eacb9df0ce5738fa = []byte{ - // 573 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x95, 0x4f, 0x8b, 0x13, 0x3f, - 0x18, 0xc7, 0xc9, 0x76, 0xe9, 0x6f, 0x37, 0x3f, 0x51, 0x08, 0xb8, 0x5b, 0x47, 0xa9, 0x65, 0x0e, - 0x6b, 0x5d, 0xdd, 0x84, 0x56, 0x4f, 0x7a, 0xf2, 0x0f, 0x2c, 0x42, 0x11, 0x9d, 0x15, 0x05, 0x3d, - 0x48, 0x76, 0xfa, 0x30, 0x3b, 0xee, 0x74, 0x12, 0x93, 0x74, 0x40, 0x16, 0x2f, 0x82, 0xaf, 0xc0, - 0x77, 0xa0, 0x17, 0xc1, 0xab, 0x77, 0xaf, 0x1e, 0x05, 0xdf, 0x80, 0x54, 0x5f, 0x88, 0x4c, 0x66, - 0xda, 0xee, 0x84, 0x6e, 0x2b, 0x58, 0x6f, 0x79, 0xf2, 0xe7, 0x79, 0x3e, 0x79, 0x9e, 0xef, 0x93, - 0xe0, 0x6d, 0x0d, 0x2a, 0x03, 0xc5, 0xb8, 0x94, 0x49, 0x1c, 0x72, 0x13, 0x8b, 0x54, 0x83, 0x71, - 0x4c, 0x2a, 0x95, 0x30, 0x82, 0x9c, 0xae, 0xce, 0x7a, 0x17, 0x22, 0x21, 0xa2, 0x04, 0x18, 0x97, - 0x31, 0xe3, 0x69, 0x2a, 0x4c, 0xb1, 0x52, 0xec, 0xf6, 0x7a, 0x51, 0x6c, 0x0e, 0x86, 0xfb, 0x34, - 0x14, 0x03, 0xc6, 0x55, 0x24, 0xa4, 0x12, 0x2f, 0xec, 0x60, 0x27, 0xec, 0xb3, 0xac, 0xcb, 0xe4, - 0x61, 0x94, 0x9f, 0xd4, 0xc7, 0x63, 0xb1, 0xac, 0xc3, 0x13, 0x79, 0xc0, 0x3b, 0x2c, 0x82, 0x14, - 0x14, 0x37, 0xd0, 0x2f, 0xbc, 0xf9, 0x8f, 0xf1, 0xc6, 0xad, 0xe9, 0xbe, 0x3d, 0x30, 0xbb, 0x60, - 0x1e, 0x0e, 0x41, 0xbd, 0x22, 0x04, 0xaf, 0xa6, 0x7c, 0x00, 0x0d, 0xd4, 0x42, 0xed, 0xf5, 0xc0, - 0x8e, 0x49, 0x1b, 0x9f, 0xe1, 0x52, 0x6a, 0x30, 0xf7, 0xf9, 0x00, 0xb4, 0xe4, 0x21, 0x34, 0x56, - 0xec, 0xb2, 0x3b, 0xed, 0x1f, 0xe1, 0xcd, 0xaa, 0xdf, 0x5e, 0xac, 0x4b, 0xc7, 0x1e, 0x5e, 0xcb, - 0x99, 0x21, 0x34, 0xba, 0x81, 0x5a, 0xb5, 0xf6, 0x7a, 0x30, 0xb1, 0xf3, 0x35, 0x0d, 0x09, 0x84, - 0x46, 0xa8, 0xd2, 0xf3, 0xc4, 0x9e, 0x15, 0xbc, 0x36, 0x3b, 0xf8, 0x47, 0xe4, 0xde, 0x2a, 0x00, - 0x2d, 0xf3, 0xe4, 0x92, 0x06, 0xfe, 0xaf, 0x0c, 0x56, 0x5e, 0x6c, 0x6c, 0x12, 0x83, 0x9d, 0x3a, - 0x58, 0x80, 0xff, 0xbb, 0x3d, 0x3a, 0x4d, 0x38, 0x1d, 0x27, 0xdc, 0x0e, 0x9e, 0x87, 0x7d, 0x9a, - 0x75, 0xa9, 0x3c, 0x8c, 0x68, 0x9e, 0x70, 0x7a, 0xec, 0x38, 0x1d, 0x27, 0x9c, 0x3a, 0x1c, 0x4e, - 0x0c, 0xff, 0x13, 0xc2, 0xe7, 0xab, 0x5b, 0xee, 0x28, 0xe0, 0x06, 0x02, 0x78, 0x39, 0x04, 0x3d, - 0x8b, 0x0a, 0xfd, 0x7b, 0x2a, 0xb2, 0x81, 0xeb, 0x43, 0xa9, 0x41, 0x15, 0x39, 0x58, 0x0b, 0x4a, - 0xcb, 0x7f, 0xe6, 0xc2, 0xde, 0x85, 0x04, 0xa6, 0xb0, 0x7f, 0x27, 0x99, 0x27, 0xae, 0x64, 0x1e, - 0x29, 0x80, 0x25, 0x68, 0xb1, 0xfb, 0xb3, 0x8e, 0xcf, 0x56, 0x3d, 0xef, 0x81, 0xca, 0xe2, 0x10, - 0xc8, 0x07, 0x84, 0x6b, 0xbb, 0x60, 0xc8, 0x16, 0x75, 0x1a, 0x73, 0x76, 0x4f, 0x78, 0x4b, 0xcd, - 0xba, 0xbf, 0xf5, 0xe6, 0xfb, 0xaf, 0x77, 0x2b, 0x2d, 0xd2, 0xb4, 0x9d, 0x9e, 0x75, 0x9c, 0xd7, - 0x41, 0xb3, 0xa3, 0xfc, 0xa2, 0xaf, 0xc9, 0x7b, 0x84, 0x57, 0xf3, 0xf6, 0x21, 0x97, 0xe6, 0x63, - 0x4e, 0x5a, 0xcc, 0x7b, 0xb0, 0x4c, 0xce, 0xdc, 0xad, 0x7f, 0xd1, 0xb2, 0x9e, 0x23, 0x9b, 0x27, - 0xb0, 0x92, 0xcf, 0x08, 0xd7, 0x0b, 0xe9, 0x92, 0x2b, 0xf3, 0x31, 0x2b, 0x02, 0x5f, 0x72, 0x4a, - 0x99, 0xc5, 0xbc, 0xec, 0x9f, 0x84, 0x79, 0xc3, 0x55, 0xfa, 0x5b, 0x84, 0xeb, 0x85, 0x88, 0x17, - 0x61, 0x57, 0xa4, 0xee, 0x2d, 0x50, 0xcc, 0xf8, 0xbd, 0x19, 0xd7, 0x78, 0x7b, 0x51, 0x8d, 0xbf, - 0x20, 0x7c, 0x2a, 0x00, 0x2d, 0x86, 0x2a, 0x84, 0x5c, 0xf7, 0x8b, 0x6a, 0x3d, 0xe9, 0x8d, 0xe5, - 0xd6, 0x3a, 0x77, 0xeb, 0x5f, 0xb7, 0xcc, 0x94, 0x5c, 0x9d, 0xcf, 0xcc, 0x54, 0xc9, 0xbb, 0x63, - 0x14, 0xc0, 0xed, 0x7b, 0x5f, 0x47, 0x4d, 0xf4, 0x6d, 0xd4, 0x44, 0x3f, 0x46, 0x4d, 0xf4, 0xf4, - 0xe6, 0x9f, 0xfd, 0x52, 0x61, 0x12, 0x43, 0xea, 0x7e, 0x8b, 0xfb, 0x75, 0xfb, 0x37, 0x5d, 0xfb, - 0x1d, 0x00, 0x00, 0xff, 0xff, 0xfa, 0x8f, 0x0f, 0xad, 0x45, 0x07, 0x00, 0x00, + // 660 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, 0xeb, 0x5a, 0x72, + 0xa8, 0xb5, 0xda, 0x09, 0x5d, 0x3d, 0xe9, 0xc9, 0x3f, 0x50, 0x0a, 0x45, 0x34, 0x2b, 0x0a, 0x7a, + 0x90, 0x69, 0xf6, 0x21, 0x8d, 0xcd, 0x26, 0xe3, 0xcc, 0x24, 0x50, 0x8a, 0x17, 0xc1, 0xa3, 0x78, + 0x10, 0xdf, 0x80, 0x5e, 0x7c, 0x01, 0xde, 0x3d, 0x78, 0xf1, 0x28, 0xf8, 0x06, 0xa4, 0xf8, 0x0e, + 0x7c, 0x03, 0x92, 0x49, 0xf6, 0x4f, 0x86, 0xfd, 0x53, 0x30, 0x7a, 0x9b, 0x67, 0x66, 0xf2, 0xcc, + 0x67, 0xbe, 0xcf, 0x93, 0x2f, 0x83, 0x37, 0x25, 0x88, 0x14, 0x84, 0xc3, 0x38, 0x0f, 0x03, 0x8f, + 0xa9, 0x20, 0x8e, 0x24, 0x28, 0x23, 0xa4, 0x5c, 0xc4, 0x2a, 0x26, 0xff, 0x95, 0x67, 0xad, 0x55, + 0x3f, 0x8e, 0xfd, 0x10, 0x1c, 0xc6, 0x03, 0x87, 0x45, 0x51, 0xac, 0xf2, 0x95, 0x7c, 0xb7, 0xb5, + 0xe7, 0x07, 0xea, 0x20, 0xd9, 0xa7, 0x5e, 0xdc, 0x75, 0x98, 0xf0, 0x63, 0x2e, 0xe2, 0x67, 0x7a, + 0xb0, 0xe5, 0x75, 0x9c, 0xb4, 0xe5, 0xf0, 0x43, 0x3f, 0xfb, 0x52, 0x0e, 0x9f, 0xe5, 0xa4, 0xdb, + 0x2c, 0xe4, 0x07, 0x6c, 0xdb, 0xf1, 0x21, 0x02, 0xc1, 0x14, 0x74, 0xf2, 0x6c, 0xf6, 0x43, 0xbc, + 0x7c, 0x73, 0xb0, 0xaf, 0x0d, 0x6a, 0x07, 0xd4, 0xfd, 0x04, 0xc4, 0x11, 0x21, 0x78, 0x2e, 0x62, + 0x5d, 0x68, 0xa0, 0x35, 0xb4, 0xb1, 0xe0, 0xea, 0x31, 0xd9, 0xc0, 0xff, 0x33, 0xce, 0x25, 0xa8, + 0xbb, 0xac, 0x0b, 0x92, 0x33, 0x0f, 0x1a, 0x33, 0x7a, 0xd9, 0x9c, 0xb6, 0x8f, 0xf1, 0x4a, 0x39, + 0xef, 0x5e, 0x20, 0x8b, 0xc4, 0x16, 0xae, 0x67, 0xcc, 0xe0, 0x29, 0xd9, 0x40, 0x6b, 0xb3, 0x1b, + 0x0b, 0x6e, 0x3f, 0xce, 0xd6, 0x24, 0x84, 0xe0, 0xa9, 0x58, 0x14, 0x99, 0xfb, 0xf1, 0xa8, 0xc3, + 0x67, 0x47, 0x1f, 0xfe, 0x11, 0x99, 0xb7, 0x72, 0x41, 0xf2, 0x4c, 0x5c, 0xd2, 0xc0, 0xf3, 0xc5, + 0x61, 0xc5, 0xc5, 0x7a, 0x21, 0x51, 0xd8, 0xa8, 0x83, 0x06, 0x58, 0x6c, 0xed, 0xd1, 0x81, 0xe0, + 0xb4, 0x27, 0xb8, 0x1e, 0x3c, 0xf5, 0x3a, 0x34, 0x6d, 0x51, 0x7e, 0xe8, 0xd3, 0x4c, 0x70, 0x3a, + 0xf4, 0x39, 0xed, 0x09, 0x4e, 0x0d, 0x0e, 0xe3, 0x0c, 0xfb, 0x0b, 0xc2, 0xe7, 0xca, 0x5b, 0x6e, + 0x0b, 0x60, 0x0a, 0x5c, 0x78, 0x9e, 0x80, 0x1c, 0x45, 0x85, 0xfe, 0x3e, 0x15, 0x59, 0xc6, 0xb5, + 0x84, 0x4b, 0x10, 0xb9, 0x06, 0x75, 0xb7, 0x88, 0xb2, 0xf9, 0x8e, 0x38, 0x72, 0x93, 0x48, 0x2b, + 0x5f, 0x77, 0x8b, 0xc8, 0x7e, 0x62, 0x5e, 0xe2, 0x0e, 0x84, 0x30, 0xb8, 0xc4, 0x9f, 0xb5, 0xd2, + 0x23, 0xb3, 0x95, 0x1e, 0x08, 0x80, 0x2a, 0x7a, 0xf4, 0x1d, 0xc2, 0xe7, 0xcd, 0xe6, 0xcf, 0xff, + 0x8e, 0xd1, 0xea, 0xb7, 0xff, 0x81, 0xfa, 0x6d, 0x50, 0xf6, 0x1b, 0x84, 0x9b, 0xe3, 0xb8, 0x8a, + 0x36, 0xee, 0xe2, 0xa5, 0xe1, 0x92, 0xe9, 0xff, 0x68, 0xb1, 0xb5, 0x5b, 0x19, 0x96, 0x5b, 0x4a, + 0xdf, 0xfa, 0x35, 0x8f, 0xcf, 0x94, 0x89, 0xda, 0x20, 0xd2, 0xc0, 0x03, 0xf2, 0x01, 0xe1, 0xd9, + 0x1d, 0x50, 0x64, 0x9d, 0x1a, 0xd6, 0x36, 0xda, 0x55, 0xac, 0x4a, 0x95, 0xb3, 0xd7, 0x5f, 0x7e, + 0xff, 0xf9, 0x76, 0x66, 0x8d, 0x34, 0xb5, 0x57, 0xa6, 0xdb, 0x86, 0xbf, 0x4a, 0xe7, 0x38, 0x6b, + 0x89, 0x17, 0xe4, 0x35, 0xc2, 0xf5, 0x9e, 0x86, 0x64, 0x6b, 0x1a, 0x6a, 0xa9, 0x07, 0x2c, 0x7a, + 0xda, 0xed, 0x79, 0x69, 0x6c, 0x5b, 0x33, 0xad, 0xda, 0x2b, 0x63, 0x98, 0xae, 0xa3, 0x4d, 0xf2, + 0x1e, 0xe1, 0xb9, 0xcc, 0x10, 0xc9, 0xc5, 0xc9, 0xc9, 0xfb, 0xa6, 0x69, 0xdd, 0xab, 0x52, 0xb7, + 0x2c, 0xad, 0x7d, 0x41, 0x73, 0x9e, 0x25, 0xe3, 0x38, 0xc9, 0x27, 0x84, 0x6b, 0xb9, 0x19, 0x91, + 0xcb, 0x93, 0x31, 0x4b, 0x96, 0x55, 0x71, 0x89, 0x1d, 0x8d, 0x79, 0x69, 0xbc, 0x9c, 0xa6, 0x77, + 0xbd, 0x42, 0xb8, 0x96, 0xdb, 0xcf, 0x34, 0xec, 0x92, 0x49, 0x59, 0x53, 0x3a, 0xb8, 0x5f, 0xdf, + 0xa2, 0xe7, 0x36, 0xa7, 0xf5, 0xdc, 0x67, 0x84, 0x97, 0x5c, 0x90, 0x71, 0x22, 0x3c, 0xc8, 0x1c, + 0x6b, 0x5a, 0xad, 0xfb, 0xae, 0x56, 0x6d, 0xad, 0xb3, 0xb4, 0xf6, 0x35, 0xcd, 0x4c, 0xc9, 0x95, + 0xc9, 0xcc, 0x8e, 0x28, 0x78, 0xb7, 0x94, 0x00, 0xb8, 0xb5, 0xfb, 0xf5, 0xa4, 0x89, 0xbe, 0x9d, + 0x34, 0xd1, 0x8f, 0x93, 0x26, 0x7a, 0x7c, 0xe3, 0x74, 0xef, 0x0e, 0x2f, 0x0c, 0x20, 0x32, 0x1f, + 0x3a, 0xfb, 0x35, 0xfd, 0xda, 0xb8, 0xfa, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x30, 0x08, 0x85, 0x97, + 0x17, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -445,6 +558,8 @@ const _ = grpc.SupportPackageIsVersion4 type ApplicationSetServiceClient interface { // Get returns an applicationset by name Get(ctx context.Context, in *ApplicationSetGetQuery, opts ...grpc.CallOption) (*v1alpha1.ApplicationSet, error) + // Generate generates + Generate(ctx context.Context, in *ApplicationSetGenerateRequest, opts ...grpc.CallOption) (*ApplicationSetGenerateResponse, error) //List returns list of applicationset List(ctx context.Context, in *ApplicationSetListQuery, opts ...grpc.CallOption) (*v1alpha1.ApplicationSetList, error) //Create creates an applicationset @@ -472,6 +587,15 @@ func (c *applicationSetServiceClient) Get(ctx context.Context, in *ApplicationSe return out, nil } +func (c *applicationSetServiceClient) Generate(ctx context.Context, in *ApplicationSetGenerateRequest, opts ...grpc.CallOption) (*ApplicationSetGenerateResponse, error) { + out := new(ApplicationSetGenerateResponse) + err := c.cc.Invoke(ctx, "/applicationset.ApplicationSetService/Generate", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *applicationSetServiceClient) List(ctx context.Context, in *ApplicationSetListQuery, opts ...grpc.CallOption) (*v1alpha1.ApplicationSetList, error) { out := new(v1alpha1.ApplicationSetList) err := c.cc.Invoke(ctx, "/applicationset.ApplicationSetService/List", in, out, opts...) @@ -512,6 +636,8 @@ func (c *applicationSetServiceClient) ResourceTree(ctx context.Context, in *Appl type ApplicationSetServiceServer interface { // Get returns an applicationset by name Get(context.Context, *ApplicationSetGetQuery) (*v1alpha1.ApplicationSet, error) + // Generate generates + Generate(context.Context, *ApplicationSetGenerateRequest) (*ApplicationSetGenerateResponse, error) //List returns list of applicationset List(context.Context, *ApplicationSetListQuery) (*v1alpha1.ApplicationSetList, error) //Create creates an applicationset @@ -529,6 +655,9 @@ type UnimplementedApplicationSetServiceServer struct { func (*UnimplementedApplicationSetServiceServer) Get(ctx context.Context, req *ApplicationSetGetQuery) (*v1alpha1.ApplicationSet, error) { return nil, status.Errorf(codes.Unimplemented, "method Get not implemented") } +func (*UnimplementedApplicationSetServiceServer) Generate(ctx context.Context, req *ApplicationSetGenerateRequest) (*ApplicationSetGenerateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Generate not implemented") +} func (*UnimplementedApplicationSetServiceServer) List(ctx context.Context, req *ApplicationSetListQuery) (*v1alpha1.ApplicationSetList, error) { return nil, status.Errorf(codes.Unimplemented, "method List not implemented") } @@ -564,6 +693,24 @@ func _ApplicationSetService_Get_Handler(srv interface{}, ctx context.Context, de return interceptor(ctx, in, info, handler) } +func _ApplicationSetService_Generate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ApplicationSetGenerateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ApplicationSetServiceServer).Generate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/applicationset.ApplicationSetService/Generate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ApplicationSetServiceServer).Generate(ctx, req.(*ApplicationSetGenerateRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _ApplicationSetService_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ApplicationSetListQuery) if err := dec(in); err != nil { @@ -644,6 +791,10 @@ var _ApplicationSetService_serviceDesc = grpc.ServiceDesc{ MethodName: "Get", Handler: _ApplicationSetService_Get_Handler, }, + { + MethodName: "Generate", + Handler: _ApplicationSetService_Generate_Handler, + }, { MethodName: "List", Handler: _ApplicationSetService_List_Handler, @@ -826,6 +977,16 @@ func (m *ApplicationSetCreateRequest) MarshalToSizedBuffer(dAtA []byte) (int, er i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DryRun { + i-- + if m.DryRun { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } if m.Upsert { i-- if m.Upsert { @@ -933,6 +1094,86 @@ func (m *ApplicationSetTreeQuery) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *ApplicationSetGenerateRequest) 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 *ApplicationSetGenerateRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ApplicationSetGenerateRequest) 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.ApplicationSet != nil { + { + size, err := m.ApplicationSet.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintApplicationset(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ApplicationSetGenerateResponse) 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 *ApplicationSetGenerateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ApplicationSetGenerateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Applications) > 0 { + for iNdEx := len(m.Applications) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Applications[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintApplicationset(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func encodeVarintApplicationset(dAtA []byte, offset int, v uint64) int { offset -= sovApplicationset(v) base := offset @@ -1023,6 +1264,9 @@ func (m *ApplicationSetCreateRequest) Size() (n int) { if m.Upsert { n += 2 } + if m.DryRun { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -1069,6 +1313,40 @@ func (m *ApplicationSetTreeQuery) Size() (n int) { return n } +func (m *ApplicationSetGenerateRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ApplicationSet != nil { + l = m.ApplicationSet.Size() + n += 1 + l + sovApplicationset(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ApplicationSetGenerateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Applications) > 0 { + for _, e := range m.Applications { + l = e.Size() + n += 1 + l + sovApplicationset(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func sovApplicationset(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1541,6 +1819,26 @@ func (m *ApplicationSetCreateRequest) Unmarshal(dAtA []byte) error { } } m.Upsert = bool(v != 0) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DryRun", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplicationset + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DryRun = bool(v != 0) default: iNdEx = preIndex skippy, err := skipApplicationset(dAtA[iNdEx:]) @@ -1793,6 +2091,178 @@ func (m *ApplicationSetTreeQuery) Unmarshal(dAtA []byte) error { } return nil } +func (m *ApplicationSetGenerateRequest) 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 ErrIntOverflowApplicationset + } + 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: ApplicationSetGenerateRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ApplicationSetGenerateRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ApplicationSet", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplicationset + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApplicationset + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApplicationset + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ApplicationSet == nil { + m.ApplicationSet = &v1alpha1.ApplicationSet{} + } + if err := m.ApplicationSet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApplicationset(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthApplicationset + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ApplicationSetGenerateResponse) 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 ErrIntOverflowApplicationset + } + 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: ApplicationSetGenerateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ApplicationSetGenerateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Applications", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplicationset + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthApplicationset + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthApplicationset + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Applications = append(m.Applications, &v1alpha1.Application{}) + if err := m.Applications[len(m.Applications)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApplicationset(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthApplicationset + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipApplicationset(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/pkg/apiclient/applicationset/applicationset.pb.gw.go b/pkg/apiclient/applicationset/applicationset.pb.gw.go index daad3043c52ca..349c5729bea94 100644 --- a/pkg/apiclient/applicationset/applicationset.pb.gw.go +++ b/pkg/apiclient/applicationset/applicationset.pb.gw.go @@ -105,6 +105,40 @@ func local_request_ApplicationSetService_Get_0(ctx context.Context, marshaler ru } +func request_ApplicationSetService_Generate_0(ctx context.Context, marshaler runtime.Marshaler, client ApplicationSetServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ApplicationSetGenerateRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Generate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ApplicationSetService_Generate_0(ctx context.Context, marshaler runtime.Marshaler, server ApplicationSetServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ApplicationSetGenerateRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Generate(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_ApplicationSetService_List_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) @@ -366,6 +400,29 @@ func RegisterApplicationSetServiceHandlerServer(ctx context.Context, mux *runtim }) + mux.Handle("POST", pattern_ApplicationSetService_Generate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ApplicationSetService_Generate_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ApplicationSetService_Generate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_ApplicationSetService_List_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -519,6 +576,26 @@ func RegisterApplicationSetServiceHandlerClient(ctx context.Context, mux *runtim }) + mux.Handle("POST", pattern_ApplicationSetService_Generate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ApplicationSetService_Generate_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ApplicationSetService_Generate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_ApplicationSetService_List_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -605,6 +682,8 @@ func RegisterApplicationSetServiceHandlerClient(ctx context.Context, mux *runtim var ( pattern_ApplicationSetService_Get_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "applicationsets", "name"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_ApplicationSetService_Generate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "applicationsets"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_ApplicationSetService_List_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "applicationsets"}, "", runtime.AssumeColonVerbOpt(true))) pattern_ApplicationSetService_Create_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "applicationsets"}, "", runtime.AssumeColonVerbOpt(true))) @@ -617,6 +696,8 @@ var ( var ( forward_ApplicationSetService_Get_0 = runtime.ForwardResponseMessage + forward_ApplicationSetService_Generate_0 = runtime.ForwardResponseMessage + forward_ApplicationSetService_List_0 = runtime.ForwardResponseMessage forward_ApplicationSetService_Create_0 = runtime.ForwardResponseMessage diff --git a/pkg/apiclient/cluster/mocks/ClusterServiceServer.go b/pkg/apiclient/cluster/mocks/ClusterServiceServer.go index ae63bfae8810b..27e33721be747 100644 --- a/pkg/apiclient/cluster/mocks/ClusterServiceServer.go +++ b/pkg/apiclient/cluster/mocks/ClusterServiceServer.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.40.2. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks diff --git a/pkg/apiclient/session/mocks/SessionServiceClient.go b/pkg/apiclient/session/mocks/SessionServiceClient.go index 91f0e45c25899..9505a424619d9 100644 --- a/pkg/apiclient/session/mocks/SessionServiceClient.go +++ b/pkg/apiclient/session/mocks/SessionServiceClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.40.2. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks diff --git a/pkg/apiclient/session/mocks/SessionServiceServer.go b/pkg/apiclient/session/mocks/SessionServiceServer.go index 46d8a6d322ce7..710176a62ed23 100644 --- a/pkg/apiclient/session/mocks/SessionServiceServer.go +++ b/pkg/apiclient/session/mocks/SessionServiceServer.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.40.2. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks diff --git a/pkg/apiclient/settings/settings.pb.go b/pkg/apiclient/settings/settings.pb.go index b74110f9005d7..3345756bd0aad 100644 --- a/pkg/apiclient/settings/settings.pb.go +++ b/pkg/apiclient/settings/settings.pb.go @@ -101,6 +101,7 @@ type Settings struct { ExecEnabled bool `protobuf:"varint,22,opt,name=execEnabled,proto3" json:"execEnabled,omitempty"` ControllerNamespace string `protobuf:"bytes,23,opt,name=controllerNamespace,proto3" json:"controllerNamespace,omitempty"` AppsInAnyNamespaceEnabled bool `protobuf:"varint,24,opt,name=appsInAnyNamespaceEnabled,proto3" json:"appsInAnyNamespaceEnabled,omitempty"` + ImpersonationEnabled bool `protobuf:"varint,25,opt,name=impersonationEnabled,proto3" json:"impersonationEnabled,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -307,6 +308,13 @@ func (m *Settings) GetAppsInAnyNamespaceEnabled() bool { return false } +func (m *Settings) GetImpersonationEnabled() bool { + if m != nil { + return m.ImpersonationEnabled + } + return false +} + type GoogleAnalyticsConfig struct { TrackingID string `protobuf:"bytes,1,opt,name=trackingID,proto3" json:"trackingID,omitempty"` AnonymizeUsers bool `protobuf:"varint,2,opt,name=anonymizeUsers,proto3" json:"anonymizeUsers,omitempty"` @@ -740,83 +748,84 @@ func init() { func init() { proto.RegisterFile("server/settings/settings.proto", fileDescriptor_a480d494da040caa) } var fileDescriptor_a480d494da040caa = []byte{ - // 1215 bytes of a gzipped FileDescriptorProto + // 1232 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4f, 0x6f, 0x1b, 0x45, - 0x14, 0xd7, 0xd6, 0x69, 0x62, 0x3f, 0x37, 0x75, 0x32, 0x6d, 0xd3, 0xad, 0x55, 0x12, 0xe3, 0x43, - 0x65, 0x10, 0xac, 0x9b, 0x54, 0x08, 0x54, 0x51, 0x41, 0x6d, 0x57, 0xad, 0x69, 0xda, 0x86, 0x69, - 0xd3, 0x03, 0x97, 0x6a, 0xb2, 0x7e, 0xac, 0x97, 0xac, 0x67, 0x56, 0x33, 0xb3, 0xa6, 0xee, 0x91, - 0x0f, 0xc0, 0x05, 0x3e, 0x0b, 0x07, 0xee, 0x08, 0x8e, 0x48, 0xdc, 0x23, 0x64, 0xf1, 0x41, 0xd0, - 0xce, 0xfe, 0xc9, 0x66, 0xed, 0x14, 0xa4, 0xde, 0x66, 0x7e, 0xbf, 0xf7, 0x6f, 0xde, 0xbc, 0x37, - 0xf3, 0x60, 0x5b, 0xa1, 0x9c, 0xa2, 0xec, 0x2a, 0xd4, 0xda, 0xe7, 0x9e, 0xca, 0x17, 0x4e, 0x28, - 0x85, 0x16, 0x64, 0xcd, 0x0d, 0x22, 0xa5, 0x51, 0x36, 0xaf, 0x7a, 0xc2, 0x13, 0x06, 0xeb, 0xc6, - 0xab, 0x84, 0x6e, 0xde, 0xf4, 0x84, 0xf0, 0x02, 0xec, 0xb2, 0xd0, 0xef, 0x32, 0xce, 0x85, 0x66, - 0xda, 0x17, 0x3c, 0x55, 0x6e, 0xee, 0x7b, 0xbe, 0x1e, 0x47, 0x47, 0x8e, 0x2b, 0x26, 0x5d, 0x26, - 0x8d, 0xfa, 0x77, 0x66, 0xf1, 0xb1, 0x3b, 0xea, 0x4e, 0xf7, 0xba, 0xe1, 0xb1, 0x17, 0x6b, 0xaa, - 0x2e, 0x0b, 0xc3, 0xc0, 0x77, 0x8d, 0x6e, 0x77, 0xba, 0xcb, 0x82, 0x70, 0xcc, 0x76, 0xbb, 0x1e, - 0x72, 0x94, 0x4c, 0xe3, 0x28, 0xb5, 0xf6, 0xe5, 0x7f, 0x58, 0x2b, 0x9f, 0x44, 0xf8, 0x23, 0xb7, - 0xeb, 0x06, 0xcc, 0x9f, 0xa4, 0xf1, 0xb4, 0x1b, 0xb0, 0xfe, 0x3c, 0x65, 0xbf, 0x8e, 0x50, 0xce, - 0xda, 0xbf, 0xd4, 0xa1, 0x9a, 0x21, 0xe4, 0x06, 0x54, 0x22, 0x19, 0xd8, 0x56, 0xcb, 0xea, 0xd4, - 0x7a, 0x6b, 0xf3, 0x93, 0x9d, 0xca, 0x21, 0xdd, 0xa7, 0x31, 0x46, 0x6e, 0x43, 0x6d, 0x84, 0xaf, - 0xfb, 0x82, 0x7f, 0xeb, 0x7b, 0xf6, 0x85, 0x96, 0xd5, 0xa9, 0xef, 0x11, 0x27, 0xcd, 0x8c, 0x33, - 0xc8, 0x18, 0x7a, 0x2a, 0x44, 0xfa, 0x00, 0xb1, 0xff, 0x54, 0xa5, 0x62, 0x54, 0xae, 0xe4, 0x2a, - 0xcf, 0x86, 0x83, 0x7e, 0x42, 0xf5, 0x2e, 0xcf, 0x4f, 0x76, 0xe0, 0x74, 0x4f, 0x0b, 0x6a, 0xa4, - 0x05, 0x75, 0x16, 0x86, 0xfb, 0xec, 0x08, 0x83, 0xc7, 0x38, 0xb3, 0x57, 0xe2, 0xc8, 0x68, 0x11, - 0x22, 0x2f, 0x61, 0x53, 0xa2, 0x12, 0x91, 0x74, 0xf1, 0xd9, 0x14, 0xa5, 0xf4, 0x47, 0xa8, 0xec, - 0x8b, 0xad, 0x4a, 0xa7, 0xbe, 0xd7, 0xc9, 0xbd, 0x65, 0x27, 0x74, 0x68, 0x59, 0xf4, 0x01, 0xd7, - 0x72, 0x46, 0x17, 0x4d, 0x10, 0x07, 0x88, 0xd2, 0x4c, 0x47, 0xaa, 0xc7, 0x46, 0x1e, 0x3e, 0xe0, - 0xec, 0x28, 0xc0, 0x91, 0xbd, 0xda, 0xb2, 0x3a, 0x55, 0xba, 0x84, 0x21, 0x8f, 0xa0, 0x91, 0x54, - 0xc2, 0x7d, 0xce, 0x82, 0x99, 0xf6, 0x5d, 0x65, 0xaf, 0x99, 0x33, 0x6f, 0xe7, 0x51, 0x3c, 0x3c, - 0xcb, 0xa7, 0xc7, 0x2d, 0xab, 0x91, 0x37, 0xb0, 0x71, 0x1c, 0x29, 0x2d, 0x26, 0xfe, 0x1b, 0x7c, - 0x16, 0x9a, 0x6a, 0xb2, 0xab, 0xc6, 0xd4, 0x53, 0xe7, 0xb4, 0x00, 0x9c, 0xac, 0x00, 0xcc, 0xe2, - 0x95, 0x3b, 0x72, 0xa6, 0x7b, 0x4e, 0x78, 0xec, 0x39, 0x71, 0x39, 0x39, 0x85, 0x72, 0x72, 0xb2, - 0x72, 0x72, 0x1e, 0x97, 0xac, 0xd2, 0x05, 0x3f, 0xe4, 0x7d, 0x58, 0x19, 0x63, 0x10, 0xda, 0x35, - 0xe3, 0x6f, 0x3d, 0x0f, 0xfd, 0x11, 0x06, 0x21, 0x35, 0x14, 0xf9, 0x00, 0xd6, 0xc2, 0x20, 0xf2, - 0x7c, 0xae, 0x6c, 0x30, 0x69, 0x6e, 0xe4, 0x52, 0x07, 0x06, 0xa7, 0x19, 0x1f, 0xe7, 0x30, 0x52, - 0x28, 0xf7, 0x45, 0xbc, 0x1b, 0xf8, 0x2a, 0xc9, 0x61, 0x3d, 0xc9, 0xe1, 0x22, 0x43, 0x7e, 0xb4, - 0xe0, 0xba, 0x6b, 0xb2, 0xf2, 0x84, 0x71, 0xe6, 0xe1, 0x04, 0xb9, 0x3e, 0x48, 0x7d, 0x5d, 0x32, - 0xbe, 0x5e, 0xbc, 0x5b, 0x06, 0xfa, 0x4b, 0x8d, 0xd3, 0xf3, 0x9c, 0x92, 0x8f, 0x60, 0x33, 0x4f, - 0xd1, 0x4b, 0x94, 0xca, 0xdc, 0xc5, 0x7a, 0xab, 0xd2, 0xa9, 0xd1, 0x45, 0x82, 0x34, 0xa1, 0x1a, - 0xf9, 0x7d, 0xa5, 0x0e, 0xe9, 0xbe, 0x7d, 0xd9, 0x54, 0x6a, 0xbe, 0x27, 0x1d, 0x68, 0x44, 0x7e, - 0x8f, 0x71, 0x8e, 0xb2, 0x2f, 0xb8, 0x46, 0xae, 0xed, 0x86, 0x11, 0x29, 0xc3, 0x71, 0xc9, 0x67, - 0x50, 0x6c, 0x68, 0x23, 0x29, 0xf9, 0x02, 0x14, 0xdb, 0x0a, 0x99, 0x52, 0xdf, 0x0b, 0x39, 0x3a, - 0x60, 0x5a, 0xa3, 0xe4, 0xf6, 0x66, 0x62, 0xab, 0x04, 0x93, 0x5b, 0x70, 0x59, 0x4b, 0xe6, 0x1e, - 0xfb, 0xdc, 0x7b, 0x82, 0x7a, 0x2c, 0x46, 0x36, 0x31, 0x82, 0x25, 0x34, 0x3e, 0x67, 0xe6, 0xe0, - 0x00, 0xe5, 0x84, 0xf1, 0x38, 0xbe, 0x2b, 0xe6, 0x9e, 0x16, 0x09, 0xf2, 0x21, 0x6c, 0xe4, 0xa0, - 0x50, 0x7e, 0x9c, 0x62, 0xfb, 0xaa, 0xb1, 0xbb, 0x80, 0x97, 0xda, 0x88, 0x0a, 0xa1, 0x0f, 0x65, - 0x60, 0x5f, 0x33, 0xd2, 0x4b, 0x98, 0xf8, 0xf4, 0xf8, 0x1a, 0xdd, 0xac, 0xdf, 0xb6, 0x4c, 0x0c, - 0x45, 0x88, 0xdc, 0x86, 0x2b, 0xae, 0xe0, 0x5a, 0x8a, 0x20, 0x40, 0xf9, 0x94, 0x4d, 0x50, 0x85, - 0xcc, 0x45, 0xfb, 0xba, 0x31, 0xb9, 0x8c, 0x22, 0x9f, 0xc3, 0x0d, 0x16, 0x86, 0x6a, 0xc8, 0xef, - 0xf3, 0x59, 0x8e, 0x66, 0x1e, 0x6c, 0xe3, 0xe1, 0x7c, 0x81, 0xe6, 0xcf, 0x16, 0x6c, 0x2d, 0x7f, - 0x36, 0xc8, 0x06, 0x54, 0x8e, 0x71, 0x96, 0xbc, 0x97, 0x34, 0x5e, 0x92, 0x11, 0x5c, 0x9c, 0xb2, - 0x20, 0xc2, 0xf4, 0x89, 0x7c, 0xc7, 0x86, 0x2d, 0xbb, 0xa5, 0x89, 0xf1, 0xbb, 0x17, 0x3e, 0xb3, - 0xda, 0xaf, 0xe0, 0xda, 0xd2, 0xf7, 0x84, 0x6c, 0x03, 0x64, 0xb7, 0x3b, 0x1c, 0xa4, 0xb1, 0x15, - 0x90, 0xb8, 0x26, 0x18, 0x17, 0x7c, 0x16, 0x97, 0xee, 0xa1, 0x42, 0xa9, 0x4c, 0xac, 0x55, 0x5a, - 0x42, 0xdb, 0x03, 0xb8, 0x9e, 0x3d, 0x9b, 0x69, 0x3b, 0x50, 0x54, 0xa1, 0xe0, 0x0a, 0x8b, 0x4f, - 0x80, 0xf5, 0xf6, 0x27, 0xa0, 0xfd, 0xab, 0x05, 0x2b, 0xf1, 0xe3, 0x41, 0x6c, 0x58, 0x73, 0xc7, - 0xcc, 0xdc, 0x7e, 0x12, 0x53, 0xb6, 0x8d, 0xdb, 0x26, 0x5e, 0xbe, 0xc0, 0xd7, 0xda, 0x84, 0x52, - 0xa3, 0xf9, 0x9e, 0xdc, 0x03, 0x38, 0xf2, 0x39, 0x93, 0xb3, 0x43, 0x19, 0x28, 0xbb, 0x62, 0x9c, - 0xbd, 0x77, 0xe6, 0x55, 0x72, 0x7a, 0x39, 0x9f, 0xbc, 0xe5, 0x05, 0x85, 0xe6, 0x3d, 0x68, 0x94, - 0xe8, 0x25, 0x77, 0x76, 0xb5, 0x78, 0x67, 0xb5, 0x62, 0x8e, 0x6f, 0xc2, 0x6a, 0x72, 0x1e, 0x42, - 0x60, 0x85, 0xb3, 0x09, 0xa6, 0x6a, 0x66, 0xdd, 0xfe, 0x02, 0x6a, 0xf9, 0xc7, 0x47, 0xf6, 0x00, - 0x5c, 0xc1, 0x39, 0xba, 0x5a, 0xc8, 0x2c, 0x2b, 0xa7, 0x1f, 0x64, 0x3f, 0xa3, 0x68, 0x41, 0xaa, - 0x7d, 0x07, 0x6a, 0x39, 0xb1, 0xcc, 0x43, 0x8c, 0xe9, 0x59, 0x98, 0x05, 0x66, 0xd6, 0xed, 0xdf, - 0x2a, 0x50, 0xf8, 0x2c, 0x97, 0xaa, 0x6d, 0xc1, 0xaa, 0xaf, 0x54, 0x84, 0x32, 0x55, 0x4c, 0x77, - 0xa4, 0x03, 0x55, 0x37, 0xf0, 0x91, 0xeb, 0xe1, 0xc0, 0xfc, 0xc7, 0xb5, 0xde, 0xa5, 0xf9, 0xc9, - 0x4e, 0xb5, 0x9f, 0x62, 0x34, 0x67, 0xc9, 0x2e, 0xd4, 0xdd, 0xc0, 0xcf, 0x88, 0xe4, 0xdb, 0xed, - 0x35, 0xe6, 0x27, 0x3b, 0xf5, 0xfe, 0xfe, 0x30, 0x97, 0x2f, 0xca, 0xc4, 0x4e, 0x95, 0x2b, 0xc2, - 0xf4, 0xf3, 0xad, 0xd1, 0x74, 0x47, 0x5e, 0xc1, 0xba, 0x3f, 0x7a, 0x21, 0x8e, 0x91, 0xf7, 0xcd, - 0x20, 0x62, 0xaf, 0x9a, 0xdc, 0xdc, 0x5a, 0x32, 0x09, 0x38, 0xc3, 0xa2, 0xa0, 0xb9, 0xae, 0xde, - 0xe6, 0xfc, 0x64, 0x67, 0x7d, 0x38, 0x28, 0xe0, 0xf4, 0xac, 0x3d, 0x72, 0x17, 0x6c, 0x34, 0xad, - 0x7a, 0xf0, 0xb8, 0xff, 0xe0, 0x7e, 0xa4, 0xc7, 0xc8, 0x75, 0xda, 0x49, 0xe6, 0x07, 0xae, 0xd2, - 0x73, 0xf9, 0xe6, 0x0c, 0xc8, 0xa2, 0xcf, 0x25, 0x25, 0xf2, 0xe4, 0x6c, 0x5b, 0x7f, 0xfa, 0xd6, - 0xb6, 0x4e, 0xa6, 0x30, 0x27, 0x1f, 0x23, 0xe3, 0x71, 0xc6, 0x31, 0xf6, 0x0b, 0xb5, 0xb5, 0xf7, - 0xbb, 0x05, 0x8d, 0xac, 0xbf, 0x9e, 0xa3, 0x9c, 0xfa, 0x2e, 0x92, 0xaf, 0xa0, 0xf2, 0x10, 0x35, - 0xd9, 0x5a, 0x98, 0x5b, 0xcc, 0xac, 0xd6, 0xdc, 0x5c, 0xc0, 0xdb, 0xf6, 0x0f, 0x7f, 0xfd, 0xf3, - 0xd3, 0x05, 0x42, 0x36, 0xcc, 0xfc, 0x39, 0xdd, 0xcd, 0x67, 0x3f, 0x32, 0x06, 0x78, 0x88, 0xf9, - 0x47, 0x76, 0x9e, 0xc9, 0xd6, 0x02, 0x5e, 0xea, 0xf5, 0x76, 0xcb, 0x78, 0x68, 0x12, 0xbb, 0xec, - 0xa1, 0x9b, 0xb6, 0x78, 0xaf, 0xff, 0xc7, 0x7c, 0xdb, 0xfa, 0x73, 0xbe, 0x6d, 0xfd, 0x3d, 0xdf, - 0xb6, 0xbe, 0xf9, 0xe4, 0xff, 0x4d, 0xbc, 0x49, 0xa9, 0xe5, 0xc6, 0x8e, 0x56, 0xcd, 0x7c, 0x7a, - 0xe7, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf1, 0x4f, 0xb0, 0x2d, 0x8e, 0x0b, 0x00, 0x00, + 0x14, 0x97, 0xeb, 0x34, 0xb1, 0x9f, 0x9b, 0x3a, 0x99, 0xa6, 0xe9, 0xd6, 0x2a, 0x89, 0xf1, 0xa1, + 0x32, 0x08, 0xd6, 0x8d, 0x2b, 0x04, 0xaa, 0xa8, 0xa0, 0xb6, 0xab, 0xd6, 0x34, 0x6d, 0xc3, 0xb4, + 0xe9, 0x81, 0x4b, 0x35, 0x59, 0x3f, 0xd6, 0x4b, 0xd6, 0x33, 0xab, 0x99, 0x59, 0x13, 0xf7, 0xc8, + 0x07, 0xe0, 0x02, 0x9f, 0x86, 0x3b, 0x82, 0x23, 0x12, 0xf7, 0x08, 0x59, 0x9c, 0xf8, 0x14, 0x68, + 0x67, 0xff, 0x64, 0xb3, 0x76, 0x0a, 0x52, 0x6f, 0x33, 0xbf, 0xdf, 0xfb, 0x37, 0x6f, 0xde, 0x9b, + 0x79, 0xb0, 0xa3, 0x50, 0x4e, 0x51, 0x76, 0x14, 0x6a, 0xed, 0x71, 0x57, 0x65, 0x0b, 0x3b, 0x90, + 0x42, 0x0b, 0xb2, 0xe6, 0xf8, 0xa1, 0xd2, 0x28, 0x1b, 0x5b, 0xae, 0x70, 0x85, 0xc1, 0x3a, 0xd1, + 0x2a, 0xa6, 0x1b, 0xb7, 0x5c, 0x21, 0x5c, 0x1f, 0x3b, 0x2c, 0xf0, 0x3a, 0x8c, 0x73, 0xa1, 0x99, + 0xf6, 0x04, 0x4f, 0x94, 0x1b, 0xfb, 0xae, 0xa7, 0xc7, 0xe1, 0x91, 0xed, 0x88, 0x49, 0x87, 0x49, + 0xa3, 0xfe, 0x9d, 0x59, 0x7c, 0xec, 0x8c, 0x3a, 0xd3, 0x6e, 0x27, 0x38, 0x76, 0x23, 0x4d, 0xd5, + 0x61, 0x41, 0xe0, 0x7b, 0x8e, 0xd1, 0xed, 0x4c, 0xf7, 0x98, 0x1f, 0x8c, 0xd9, 0x5e, 0xc7, 0x45, + 0x8e, 0x92, 0x69, 0x1c, 0x25, 0xd6, 0xbe, 0xfc, 0x0f, 0x6b, 0xc5, 0x93, 0x08, 0x6f, 0xe4, 0x74, + 0x1c, 0x9f, 0x79, 0x93, 0x24, 0x9e, 0x56, 0x1d, 0xd6, 0x5f, 0x24, 0xec, 0xd7, 0x21, 0xca, 0x59, + 0xeb, 0x9f, 0x1a, 0x54, 0x52, 0x84, 0xdc, 0x84, 0x72, 0x28, 0x7d, 0xab, 0xd4, 0x2c, 0xb5, 0xab, + 0xbd, 0xb5, 0xf9, 0xe9, 0x6e, 0xf9, 0x90, 0xee, 0xd3, 0x08, 0x23, 0x77, 0xa0, 0x3a, 0xc2, 0x93, + 0xbe, 0xe0, 0xdf, 0x7a, 0xae, 0x75, 0xa9, 0x59, 0x6a, 0xd7, 0xba, 0xc4, 0x4e, 0x32, 0x63, 0x0f, + 0x52, 0x86, 0x9e, 0x09, 0x91, 0x3e, 0x40, 0xe4, 0x3f, 0x51, 0x29, 0x1b, 0x95, 0x6b, 0x99, 0xca, + 0xf3, 0xe1, 0xa0, 0x1f, 0x53, 0xbd, 0xab, 0xf3, 0xd3, 0x5d, 0x38, 0xdb, 0xd3, 0x9c, 0x1a, 0x69, + 0x42, 0x8d, 0x05, 0xc1, 0x3e, 0x3b, 0x42, 0xff, 0x09, 0xce, 0xac, 0x95, 0x28, 0x32, 0x9a, 0x87, + 0xc8, 0x2b, 0xd8, 0x94, 0xa8, 0x44, 0x28, 0x1d, 0x7c, 0x3e, 0x45, 0x29, 0xbd, 0x11, 0x2a, 0xeb, + 0x72, 0xb3, 0xdc, 0xae, 0x75, 0xdb, 0x99, 0xb7, 0xf4, 0x84, 0x36, 0x2d, 0x8a, 0x3e, 0xe4, 0x5a, + 0xce, 0xe8, 0xa2, 0x09, 0x62, 0x03, 0x51, 0x9a, 0xe9, 0x50, 0xf5, 0xd8, 0xc8, 0xc5, 0x87, 0x9c, + 0x1d, 0xf9, 0x38, 0xb2, 0x56, 0x9b, 0xa5, 0x76, 0x85, 0x2e, 0x61, 0xc8, 0x63, 0xa8, 0xc7, 0x95, + 0xf0, 0x80, 0x33, 0x7f, 0xa6, 0x3d, 0x47, 0x59, 0x6b, 0xe6, 0xcc, 0x3b, 0x59, 0x14, 0x8f, 0xce, + 0xf3, 0xc9, 0x71, 0x8b, 0x6a, 0xe4, 0x0d, 0x6c, 0x1c, 0x87, 0x4a, 0x8b, 0x89, 0xf7, 0x06, 0x9f, + 0x07, 0xa6, 0x9a, 0xac, 0x8a, 0x31, 0xf5, 0xcc, 0x3e, 0x2b, 0x00, 0x3b, 0x2d, 0x00, 0xb3, 0x78, + 0xed, 0x8c, 0xec, 0x69, 0xd7, 0x0e, 0x8e, 0x5d, 0x3b, 0x2a, 0x27, 0x3b, 0x57, 0x4e, 0x76, 0x5a, + 0x4e, 0xf6, 0x93, 0x82, 0x55, 0xba, 0xe0, 0x87, 0xbc, 0x0f, 0x2b, 0x63, 0xf4, 0x03, 0xab, 0x6a, + 0xfc, 0xad, 0x67, 0xa1, 0x3f, 0x46, 0x3f, 0xa0, 0x86, 0x22, 0x1f, 0xc0, 0x5a, 0xe0, 0x87, 0xae, + 0xc7, 0x95, 0x05, 0x26, 0xcd, 0xf5, 0x4c, 0xea, 0xc0, 0xe0, 0x34, 0xe5, 0xa3, 0x1c, 0x86, 0x0a, + 0xe5, 0xbe, 0x88, 0x76, 0x03, 0x4f, 0xc5, 0x39, 0xac, 0xc5, 0x39, 0x5c, 0x64, 0xc8, 0x8f, 0x25, + 0xb8, 0xe1, 0x98, 0xac, 0x3c, 0x65, 0x9c, 0xb9, 0x38, 0x41, 0xae, 0x0f, 0x12, 0x5f, 0x57, 0x8c, + 0xaf, 0x97, 0xef, 0x96, 0x81, 0xfe, 0x52, 0xe3, 0xf4, 0x22, 0xa7, 0xe4, 0x23, 0xd8, 0xcc, 0x52, + 0xf4, 0x0a, 0xa5, 0x32, 0x77, 0xb1, 0xde, 0x2c, 0xb7, 0xab, 0x74, 0x91, 0x20, 0x0d, 0xa8, 0x84, + 0x5e, 0x5f, 0xa9, 0x43, 0xba, 0x6f, 0x5d, 0x35, 0x95, 0x9a, 0xed, 0x49, 0x1b, 0xea, 0xa1, 0xd7, + 0x63, 0x9c, 0xa3, 0xec, 0x0b, 0xae, 0x91, 0x6b, 0xab, 0x6e, 0x44, 0x8a, 0x70, 0x54, 0xf2, 0x29, + 0x14, 0x19, 0xda, 0x88, 0x4b, 0x3e, 0x07, 0x45, 0xb6, 0x02, 0xa6, 0xd4, 0xf7, 0x42, 0x8e, 0x0e, + 0x98, 0xd6, 0x28, 0xb9, 0xb5, 0x19, 0xdb, 0x2a, 0xc0, 0xe4, 0x36, 0x5c, 0xd5, 0x92, 0x39, 0xc7, + 0x1e, 0x77, 0x9f, 0xa2, 0x1e, 0x8b, 0x91, 0x45, 0x8c, 0x60, 0x01, 0x8d, 0xce, 0x99, 0x3a, 0x38, + 0x40, 0x39, 0x61, 0x3c, 0x8a, 0xef, 0x9a, 0xb9, 0xa7, 0x45, 0x82, 0x7c, 0x08, 0x1b, 0x19, 0x28, + 0x94, 0x17, 0xa5, 0xd8, 0xda, 0x32, 0x76, 0x17, 0xf0, 0x42, 0x1b, 0x51, 0x21, 0xf4, 0xa1, 0xf4, + 0xad, 0xeb, 0x46, 0x7a, 0x09, 0x13, 0x9d, 0x1e, 0x4f, 0xd0, 0x49, 0xfb, 0x6d, 0xdb, 0xc4, 0x90, + 0x87, 0xc8, 0x1d, 0xb8, 0xe6, 0x08, 0xae, 0xa5, 0xf0, 0x7d, 0x94, 0xcf, 0xd8, 0x04, 0x55, 0xc0, + 0x1c, 0xb4, 0x6e, 0x18, 0x93, 0xcb, 0x28, 0xf2, 0x39, 0xdc, 0x64, 0x41, 0xa0, 0x86, 0xfc, 0x01, + 0x9f, 0x65, 0x68, 0xea, 0xc1, 0x32, 0x1e, 0x2e, 0x16, 0x20, 0x5d, 0xd8, 0xf2, 0x26, 0x01, 0x4a, + 0x25, 0xb8, 0xa9, 0xa6, 0x54, 0xf1, 0xa6, 0x51, 0x5c, 0xca, 0x35, 0x7e, 0x2e, 0xc1, 0xf6, 0xf2, + 0xa7, 0x86, 0x6c, 0x40, 0xf9, 0x18, 0x67, 0xf1, 0x1b, 0x4b, 0xa3, 0x25, 0x19, 0xc1, 0xe5, 0x29, + 0xf3, 0x43, 0x4c, 0x9e, 0xd5, 0x77, 0x6c, 0xf2, 0xa2, 0x5b, 0x1a, 0x1b, 0xbf, 0x77, 0xe9, 0xb3, + 0x52, 0xeb, 0x35, 0x5c, 0x5f, 0xfa, 0x06, 0x91, 0x1d, 0x80, 0xb4, 0x22, 0x86, 0x83, 0x24, 0xb6, + 0x1c, 0x12, 0xd5, 0x11, 0xe3, 0x82, 0xcf, 0xa2, 0x72, 0x3f, 0x54, 0x28, 0x95, 0x89, 0xb5, 0x42, + 0x0b, 0x68, 0x6b, 0x00, 0x37, 0xd2, 0xa7, 0x36, 0x69, 0x21, 0x8a, 0x2a, 0x10, 0x5c, 0x61, 0xfe, + 0xd9, 0x28, 0xbd, 0xfd, 0xd9, 0x68, 0xfd, 0x52, 0x82, 0x95, 0xe8, 0xc1, 0x21, 0x16, 0xac, 0x39, + 0x63, 0x66, 0x2a, 0x26, 0x8e, 0x29, 0xdd, 0x46, 0xad, 0x16, 0x2d, 0x5f, 0xe2, 0x89, 0x36, 0xa1, + 0x54, 0x69, 0xb6, 0x27, 0xf7, 0x01, 0x8e, 0x3c, 0xce, 0xe4, 0xec, 0x50, 0xfa, 0xca, 0x2a, 0x1b, + 0x67, 0xef, 0x9d, 0x7b, 0xc9, 0xec, 0x5e, 0xc6, 0xc7, 0xef, 0x7f, 0x4e, 0xa1, 0x71, 0x1f, 0xea, + 0x05, 0x7a, 0xc9, 0x9d, 0x6d, 0xe5, 0xef, 0xac, 0x9a, 0xcf, 0xf1, 0x2d, 0x58, 0x8d, 0xcf, 0x43, + 0x08, 0xac, 0x70, 0x36, 0xc1, 0x44, 0xcd, 0xac, 0x5b, 0x5f, 0x40, 0x35, 0xfb, 0x2c, 0x49, 0x17, + 0xc0, 0x11, 0x9c, 0xa3, 0xa3, 0x85, 0x4c, 0xb3, 0x72, 0xf6, 0xa9, 0xf6, 0x53, 0x8a, 0xe6, 0xa4, + 0x5a, 0x77, 0xa1, 0x9a, 0x11, 0xcb, 0x3c, 0x44, 0x98, 0x9e, 0x05, 0x69, 0x60, 0x66, 0xdd, 0xfa, + 0xb5, 0x0c, 0xb9, 0x0f, 0x76, 0xa9, 0xda, 0x36, 0xac, 0x7a, 0x4a, 0x85, 0x28, 0x13, 0xc5, 0x64, + 0x47, 0xda, 0x50, 0x71, 0x7c, 0x0f, 0xb9, 0x1e, 0x0e, 0xcc, 0x1f, 0x5e, 0xed, 0x5d, 0x99, 0x9f, + 0xee, 0x56, 0xfa, 0x09, 0x46, 0x33, 0x96, 0xec, 0x41, 0xcd, 0xf1, 0xbd, 0x94, 0x88, 0xbf, 0xea, + 0x5e, 0x7d, 0x7e, 0xba, 0x5b, 0xeb, 0xef, 0x0f, 0x33, 0xf9, 0xbc, 0x4c, 0xe4, 0x54, 0x39, 0x22, + 0x48, 0x3e, 0xec, 0x2a, 0x4d, 0x76, 0xe4, 0x35, 0xac, 0x7b, 0xa3, 0x97, 0xe2, 0x18, 0x79, 0xdf, + 0x0c, 0x2f, 0xd6, 0xaa, 0xc9, 0xcd, 0xed, 0x25, 0xd3, 0x83, 0x3d, 0xcc, 0x0b, 0x9a, 0xeb, 0xea, + 0x6d, 0xce, 0x4f, 0x77, 0xd7, 0x87, 0x83, 0x1c, 0x4e, 0xcf, 0xdb, 0x23, 0xf7, 0xc0, 0x42, 0xd3, + 0xaa, 0x07, 0x4f, 0xfa, 0x0f, 0x1f, 0x84, 0x7a, 0x8c, 0x5c, 0x27, 0x9d, 0x64, 0x7e, 0xed, 0x0a, + 0xbd, 0x90, 0x6f, 0xcc, 0x80, 0x2c, 0xfa, 0x5c, 0x52, 0x22, 0x4f, 0xcf, 0xb7, 0xf5, 0xa7, 0x6f, + 0x6d, 0xeb, 0x78, 0x72, 0xb3, 0xb3, 0xd1, 0x33, 0x1a, 0x81, 0x6c, 0x63, 0x3f, 0x57, 0x5b, 0xdd, + 0xdf, 0x4a, 0x50, 0x4f, 0xfb, 0xeb, 0x05, 0xca, 0xa9, 0xe7, 0x20, 0xf9, 0x0a, 0xca, 0x8f, 0x50, + 0x93, 0xed, 0x85, 0x59, 0xc7, 0xcc, 0x77, 0x8d, 0xcd, 0x05, 0xbc, 0x65, 0xfd, 0xf0, 0xe7, 0xdf, + 0x3f, 0x5d, 0x22, 0x64, 0xc3, 0xcc, 0xac, 0xd3, 0xbd, 0x6c, 0x5e, 0x24, 0x63, 0x80, 0x47, 0x98, + 0x7d, 0x7e, 0x17, 0x99, 0x6c, 0x2e, 0xe0, 0x85, 0x5e, 0x6f, 0x35, 0x8d, 0x87, 0x06, 0xb1, 0x8a, + 0x1e, 0x3a, 0x49, 0x8b, 0xf7, 0xfa, 0xbf, 0xcf, 0x77, 0x4a, 0x7f, 0xcc, 0x77, 0x4a, 0x7f, 0xcd, + 0x77, 0x4a, 0xdf, 0x7c, 0xf2, 0xff, 0xa6, 0xe4, 0xb8, 0xd4, 0x32, 0x63, 0x47, 0xab, 0x66, 0xa6, + 0xbd, 0xfb, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8d, 0xd6, 0x25, 0xb7, 0xc2, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -990,6 +999,18 @@ func (m *Settings) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.ImpersonationEnabled { + i-- + if m.ImpersonationEnabled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xc8 + } if m.AppsInAnyNamespaceEnabled { i-- if m.AppsInAnyNamespaceEnabled { @@ -1750,6 +1771,9 @@ func (m *Settings) Size() (n int) { if m.AppsInAnyNamespaceEnabled { n += 3 } + if m.ImpersonationEnabled { + n += 3 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -2840,6 +2864,26 @@ func (m *Settings) Unmarshal(dAtA []byte) error { } } m.AppsInAnyNamespaceEnabled = bool(v != 0) + case 25: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ImpersonationEnabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettings + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ImpersonationEnabled = bool(v != 0) default: iNdEx = preIndex skippy, err := skipSettings(dAtA[iNdEx:]) diff --git a/pkg/apis/api-rules/violation_exceptions.list b/pkg/apis/api-rules/violation_exceptions.list index 0992ad394ccfa..e69de29bb2d1d 100644 --- a/pkg/apis/api-rules/violation_exceptions.list +++ b/pkg/apis/api-rules/violation_exceptions.list @@ -1,135 +0,0 @@ -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,AppProjectSpec,ClusterResourceBlacklist -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,AppProjectSpec,ClusterResourceWhitelist -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,AppProjectSpec,Destinations -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,AppProjectSpec,NamespaceResourceBlacklist -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,AppProjectSpec,NamespaceResourceWhitelist -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,AppProjectSpec,Roles -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,AppProjectSpec,SignatureKeys -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,AppProjectSpec,SourceNamespaces -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,AppProjectSpec,SourceRepos -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationMatchExpression,Values -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationPreservedFields,Annotations -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationPreservedFields,Labels -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSetApplicationStatus,TargetRevisions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSetResourceIgnoreDifferences,JQPathExpressions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSetResourceIgnoreDifferences,JSONPointers -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSetRolloutStep,MatchExpressions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSetRolloutStrategy,Steps -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSetSpec,Generators -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSetSpec,GoTemplateOptions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSetStatus,ApplicationStatus -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSetStatus,Conditions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSetStatus,Resources -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSetTemplateMeta,Finalizers -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSetTree,Nodes -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourceHelm,FileParameters -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourceHelm,Parameters -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourceHelm,ValueFiles -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourceJsonnet,ExtVars -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourceJsonnet,Libs -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourceJsonnet,TLAs -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourceKustomize,Components -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSpec,Info -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationStatus,Conditions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationStatus,Resources -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationStatus,SourceTypes -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSummary,ExternalURLs -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSummary,Images -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationTree,Hosts -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationTree,Nodes -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationTree,OrphanedNodes -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ChartDetails,Maintainers -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,Cluster,Namespaces -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ClusterInfo,APIVersions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,Command,Args -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,Command,Command -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ExecProviderConfig,Args -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,GitGenerator,Directories -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,GitGenerator,Files -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,HelmOptions,ValuesFileSchemes -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,HostInfo,ResourcesInfo -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,JWTTokens,Items -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ListGenerator,Elements -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,MatrixGenerator,Generators -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,MergeGenerator,Generators -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,MergeGenerator,MergeKeys -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,NestedMergeGenerator,MergeKeys -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,Operation,Info -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,OptionalArray,Array -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,OrphanedResourcesMonitorSettings,Ignore -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,OverrideIgnoreDiff,JQPathExpressions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,OverrideIgnoreDiff,JSONPointers -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,OverrideIgnoreDiff,ManagedFieldsManagers -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ProjectRole,Groups -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ProjectRole,JWTTokens -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ProjectRole,Policies -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,PullRequestGenerator,Filters -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,PullRequestGeneratorAzureDevOps,Labels -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,PullRequestGeneratorGitLab,Labels -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,PullRequestGeneratorGithub,Labels -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RepositoryCertificate,CertData -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceAction,Params -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceActions,Definitions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceIgnoreDifferences,JQPathExpressions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceIgnoreDifferences,JSONPointers -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceIgnoreDifferences,ManagedFieldsManagers -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceNetworkingInfo,ExternalURLs -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceNetworkingInfo,Ingress -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceNetworkingInfo,TargetRefs -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceNode,Images -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceNode,Info -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceNode,ParentRefs -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceOverride,KnownTypeFields -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RevisionHistory,Revisions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RevisionMetadata,Tags -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SCMProviderGenerator,Filters -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SCMProviderGeneratorAWSCodeCommit,TagFilters -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SCMProviderGeneratorFilter,PathsDoNotExist -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SCMProviderGeneratorFilter,PathsExist -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncOperation,Manifests -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncOperation,Resources -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncOperation,Revisions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncOperationResult,Revisions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncStatus,Revisions -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncWindow,Applications -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncWindow,Clusters -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,SyncWindow,Namespaces -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,TLSClientConfig,CAData -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,TLSClientConfig,CertData -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,TLSClientConfig,KeyData -API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,rawResourceOverride,KnownTypeFields -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourceJsonnet,TLAs -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourcePluginParameter,String_ -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ClusterCacheInfo,APIsCount -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ConnectionState,ModifiedAt -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ErrApplicationNotAllowedToUseProject,application -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ErrApplicationNotAllowedToUseProject,namespace -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ErrApplicationNotAllowedToUseProject,project -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,HelmOptions,ValuesFileSchemes -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,JWTToken,ExpiresAt -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,JWTToken,IssuedAt -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,KustomizeOptions,BinaryPath -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,KustomizeOptions,BuildOptions -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,PullRequestGenerator,AzureDevOps -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,PullRequestGenerator,GitLab -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RefTarget,Chart -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RefTarget,Repo -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RefTarget,TargetRevision -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RepoCreds,GitHubAppEnterpriseBaseURL -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RepoCreds,GithubAppId -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,RepoCreds,GithubAppInstallationId -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,Repository,EnableLFS -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,Repository,GitHubAppEnterpriseBaseURL -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,Repository,GithubAppId -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,Repository,GithubAppInstallationId -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceActionDefinition,ActionLua -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceActions,ActionDiscoveryLua -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceOverride,Actions -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceOverride,HealthLua -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceOverride,IgnoreDifferences -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceOverride,IgnoreResourceUpdates -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceOverride,KnownTypeFields -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ResourceOverride,UseOpenLibs -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,objectMeta,Name -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,rawResourceOverride,HealthLua -API rule violation: names_match,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,rawResourceOverride,UseOpenLibs diff --git a/pkg/apis/application/v1alpha1/app_project_types.go b/pkg/apis/application/v1alpha1/app_project_types.go index 48a90d5a8233a..b888cd37391b3 100644 --- a/pkg/apis/application/v1alpha1/app_project_types.go +++ b/pkg/apis/application/v1alpha1/app_project_types.go @@ -265,6 +265,23 @@ func (p *AppProject) ValidateProject() error { } } + destServiceAccts := make(map[string]bool) + for _, destServiceAcct := range p.Spec.DestinationServiceAccounts { + if destServiceAcct.Server == "!*" { + return status.Errorf(codes.InvalidArgument, "server has an invalid format, '!*'") + } + + if destServiceAcct.Namespace == "!*" { + return status.Errorf(codes.InvalidArgument, "namespace has an invalid format, '!*'") + } + + key := fmt.Sprintf("%s/%s", destServiceAcct.Server, destServiceAcct.Namespace) + if _, ok := destServiceAccts[key]; ok { + return status.Errorf(codes.InvalidArgument, "destinationServiceAccount '%s' already added", key) + } + destServiceAccts[key] = true + } + return nil } @@ -562,5 +579,5 @@ func (p AppProject) IsAppNamespacePermitted(app *Application, controllerNs strin return true } - return glob.MatchStringInList(p.Spec.SourceNamespaces, app.Namespace, false) + 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 6c2b629dfdaa9..d4446130c7026 100644 --- a/pkg/apis/application/v1alpha1/applicationset_types.go +++ b/pkg/apis/application/v1alpha1/applicationset_types.go @@ -35,6 +35,12 @@ type SecretRef struct { Key string `json:"key" protobuf:"bytes,2,opt,name=key"` } +// Utility struct for a reference to a configmap key. +type ConfigMapKeyRef struct { + ConfigMapName string `json:"configMapName" protobuf:"bytes,1,opt,name=configMapName"` + Key string `json:"key" protobuf:"bytes,2,opt,name=key"` +} + // ApplicationSet is a set of Application resources // +genclient // +genclient:noStatus @@ -498,6 +504,8 @@ type SCMProviderGeneratorGitlab struct { IncludeSharedProjects *bool `json:"includeSharedProjects,omitempty" protobuf:"varint,7,opt,name=includeSharedProjects"` // Filter repos list based on Gitlab Topic. Topic string `json:"topic,omitempty" protobuf:"bytes,8,opt,name=topic"` + // ConfigMap key holding the trusted certificates + CARef *ConfigMapKeyRef `json:"caRef,omitempty" protobuf:"bytes,9,opt,name=caRef"` } func (s *SCMProviderGeneratorGitlab) WillIncludeSharedProjects() bool { @@ -526,6 +534,12 @@ type SCMProviderGeneratorBitbucketServer struct { BasicAuth *BasicAuthBitbucketServer `json:"basicAuth,omitempty" protobuf:"bytes,3,opt,name=basicAuth"` // Scan all branches instead of just the default branch. AllBranches bool `json:"allBranches,omitempty" protobuf:"varint,4,opt,name=allBranches"` + // Credentials for AccessToken (Bearer auth) + BearerToken *BearerTokenBitbucket `json:"bearerToken,omitempty" protobuf:"bytes,5,opt,name=bearerToken"` + // Allow self-signed TLS / Certificates; default: false + Insecure bool `json:"insecure,omitempty" protobuf:"varint,6,opt,name=insecure"` + // ConfigMap key holding the trusted certificates + CARef *ConfigMapKeyRef `json:"caRef,omitempty" protobuf:"bytes,7,opt,name=caRef"` } // SCMProviderGeneratorAzureDevOps defines connection info specific to Azure DevOps. @@ -677,6 +691,8 @@ type PullRequestGeneratorGitLab struct { 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"` + // ConfigMap key holding the trusted certificates + CARef *ConfigMapKeyRef `json:"caRef,omitempty" protobuf:"bytes,7,opt,name=caRef"` } // PullRequestGeneratorBitbucketServer defines connection info specific to BitbucketServer. @@ -689,6 +705,12 @@ type PullRequestGeneratorBitbucketServer struct { API string `json:"api" protobuf:"bytes,3,opt,name=api"` // Credentials for Basic auth BasicAuth *BasicAuthBitbucketServer `json:"basicAuth,omitempty" protobuf:"bytes,4,opt,name=basicAuth"` + // Credentials for AccessToken (Bearer auth) + BearerToken *BearerTokenBitbucket `json:"bearerToken,omitempty" protobuf:"bytes,5,opt,name=bearerToken"` + // Allow self-signed TLS / Certificates; default: false + Insecure bool `json:"insecure,omitempty" protobuf:"varint,6,opt,name=insecure"` + // ConfigMap key holding the trusted certificates + CARef *ConfigMapKeyRef `json:"caRef,omitempty" protobuf:"bytes,7,opt,name=caRef"` } // PullRequestGeneratorBitbucket defines connection info specific to Bitbucket. @@ -705,6 +727,12 @@ type PullRequestGeneratorBitbucket struct { BearerToken *BearerTokenBitbucketCloud `json:"bearerToken,omitempty" protobuf:"bytes,5,opt,name=bearerToken"` } +// BearerTokenBitbucket defines the Bearer token for BitBucket AppToken auth. +type BearerTokenBitbucket struct { + // Password (or personal access token) reference. + TokenRef *SecretRef `json:"tokenRef" protobuf:"bytes,1,opt,name=tokenRef"` +} + // BearerTokenBitbucketCloud defines the Bearer token for BitBucket AppToken auth. type BearerTokenBitbucketCloud struct { // Password (or personal access token) reference. diff --git a/pkg/apis/application/v1alpha1/generated.pb.go b/pkg/apis/application/v1alpha1/generated.pb.go index 46f72d9eab6ef..5fc96609621ca 100644 --- a/pkg/apis/application/v1alpha1/generated.pb.go +++ b/pkg/apis/application/v1alpha1/generated.pb.go @@ -263,10 +263,38 @@ func (m *ApplicationDestination) XXX_DiscardUnknown() { var xxx_messageInfo_ApplicationDestination proto.InternalMessageInfo +func (m *ApplicationDestinationServiceAccount) Reset() { *m = ApplicationDestinationServiceAccount{} } +func (*ApplicationDestinationServiceAccount) ProtoMessage() {} +func (*ApplicationDestinationServiceAccount) Descriptor() ([]byte, []int) { + return fileDescriptor_030104ce3b95bcac, []int{8} +} +func (m *ApplicationDestinationServiceAccount) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ApplicationDestinationServiceAccount) 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 *ApplicationDestinationServiceAccount) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplicationDestinationServiceAccount.Merge(m, src) +} +func (m *ApplicationDestinationServiceAccount) XXX_Size() int { + return m.Size() +} +func (m *ApplicationDestinationServiceAccount) XXX_DiscardUnknown() { + xxx_messageInfo_ApplicationDestinationServiceAccount.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplicationDestinationServiceAccount proto.InternalMessageInfo + func (m *ApplicationList) Reset() { *m = ApplicationList{} } func (*ApplicationList) ProtoMessage() {} func (*ApplicationList) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{8} + return fileDescriptor_030104ce3b95bcac, []int{9} } func (m *ApplicationList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -294,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_030104ce3b95bcac, []int{9} + return fileDescriptor_030104ce3b95bcac, []int{10} } func (m *ApplicationMatchExpression) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -322,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_030104ce3b95bcac, []int{10} + return fileDescriptor_030104ce3b95bcac, []int{11} } func (m *ApplicationPreservedFields) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -350,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_030104ce3b95bcac, []int{11} + return fileDescriptor_030104ce3b95bcac, []int{12} } func (m *ApplicationSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -378,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_030104ce3b95bcac, []int{12} + return fileDescriptor_030104ce3b95bcac, []int{13} } func (m *ApplicationSetApplicationStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -406,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_030104ce3b95bcac, []int{13} + return fileDescriptor_030104ce3b95bcac, []int{14} } func (m *ApplicationSetCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -434,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_030104ce3b95bcac, []int{14} + return fileDescriptor_030104ce3b95bcac, []int{15} } func (m *ApplicationSetGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -462,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_030104ce3b95bcac, []int{15} + return fileDescriptor_030104ce3b95bcac, []int{16} } func (m *ApplicationSetList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -490,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_030104ce3b95bcac, []int{16} + return fileDescriptor_030104ce3b95bcac, []int{17} } func (m *ApplicationSetNestedGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -520,7 +548,7 @@ func (m *ApplicationSetResourceIgnoreDifferences) Reset() { } func (*ApplicationSetResourceIgnoreDifferences) ProtoMessage() {} func (*ApplicationSetResourceIgnoreDifferences) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{17} + return fileDescriptor_030104ce3b95bcac, []int{18} } func (m *ApplicationSetResourceIgnoreDifferences) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -548,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_030104ce3b95bcac, []int{18} + return fileDescriptor_030104ce3b95bcac, []int{19} } func (m *ApplicationSetRolloutStep) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -576,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_030104ce3b95bcac, []int{19} + return fileDescriptor_030104ce3b95bcac, []int{20} } func (m *ApplicationSetRolloutStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -604,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_030104ce3b95bcac, []int{20} + return fileDescriptor_030104ce3b95bcac, []int{21} } func (m *ApplicationSetSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -632,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_030104ce3b95bcac, []int{21} + return fileDescriptor_030104ce3b95bcac, []int{22} } func (m *ApplicationSetStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -660,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_030104ce3b95bcac, []int{22} + return fileDescriptor_030104ce3b95bcac, []int{23} } func (m *ApplicationSetStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -688,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_030104ce3b95bcac, []int{23} + return fileDescriptor_030104ce3b95bcac, []int{24} } func (m *ApplicationSetSyncPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -716,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_030104ce3b95bcac, []int{24} + return fileDescriptor_030104ce3b95bcac, []int{25} } func (m *ApplicationSetTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -744,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_030104ce3b95bcac, []int{25} + return fileDescriptor_030104ce3b95bcac, []int{26} } func (m *ApplicationSetTemplateMeta) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -772,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_030104ce3b95bcac, []int{26} + return fileDescriptor_030104ce3b95bcac, []int{27} } func (m *ApplicationSetTerminalGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -800,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_030104ce3b95bcac, []int{27} + return fileDescriptor_030104ce3b95bcac, []int{28} } func (m *ApplicationSetTree) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -828,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_030104ce3b95bcac, []int{28} + return fileDescriptor_030104ce3b95bcac, []int{29} } func (m *ApplicationSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -856,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_030104ce3b95bcac, []int{29} + return fileDescriptor_030104ce3b95bcac, []int{30} } func (m *ApplicationSourceDirectory) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -884,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_030104ce3b95bcac, []int{30} + return fileDescriptor_030104ce3b95bcac, []int{31} } func (m *ApplicationSourceHelm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -912,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_030104ce3b95bcac, []int{31} + return fileDescriptor_030104ce3b95bcac, []int{32} } func (m *ApplicationSourceJsonnet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -940,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_030104ce3b95bcac, []int{32} + return fileDescriptor_030104ce3b95bcac, []int{33} } func (m *ApplicationSourceKustomize) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -968,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_030104ce3b95bcac, []int{33} + return fileDescriptor_030104ce3b95bcac, []int{34} } func (m *ApplicationSourcePlugin) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -996,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_030104ce3b95bcac, []int{34} + return fileDescriptor_030104ce3b95bcac, []int{35} } func (m *ApplicationSourcePluginParameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1024,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_030104ce3b95bcac, []int{35} + return fileDescriptor_030104ce3b95bcac, []int{36} } func (m *ApplicationSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1052,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_030104ce3b95bcac, []int{36} + return fileDescriptor_030104ce3b95bcac, []int{37} } func (m *ApplicationStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1080,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_030104ce3b95bcac, []int{37} + return fileDescriptor_030104ce3b95bcac, []int{38} } func (m *ApplicationSummary) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1108,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_030104ce3b95bcac, []int{38} + return fileDescriptor_030104ce3b95bcac, []int{39} } func (m *ApplicationTree) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1136,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_030104ce3b95bcac, []int{39} + return fileDescriptor_030104ce3b95bcac, []int{40} } func (m *ApplicationWatchEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1164,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_030104ce3b95bcac, []int{40} + return fileDescriptor_030104ce3b95bcac, []int{41} } func (m *Backoff) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1192,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_030104ce3b95bcac, []int{41} + return fileDescriptor_030104ce3b95bcac, []int{42} } func (m *BasicAuthBitbucketServer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1217,10 +1245,38 @@ func (m *BasicAuthBitbucketServer) XXX_DiscardUnknown() { var xxx_messageInfo_BasicAuthBitbucketServer proto.InternalMessageInfo +func (m *BearerTokenBitbucket) Reset() { *m = BearerTokenBitbucket{} } +func (*BearerTokenBitbucket) ProtoMessage() {} +func (*BearerTokenBitbucket) Descriptor() ([]byte, []int) { + return fileDescriptor_030104ce3b95bcac, []int{43} +} +func (m *BearerTokenBitbucket) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BearerTokenBitbucket) 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 *BearerTokenBitbucket) XXX_Merge(src proto.Message) { + xxx_messageInfo_BearerTokenBitbucket.Merge(m, src) +} +func (m *BearerTokenBitbucket) XXX_Size() int { + return m.Size() +} +func (m *BearerTokenBitbucket) XXX_DiscardUnknown() { + xxx_messageInfo_BearerTokenBitbucket.DiscardUnknown(m) +} + +var xxx_messageInfo_BearerTokenBitbucket proto.InternalMessageInfo + func (m *BearerTokenBitbucketCloud) Reset() { *m = BearerTokenBitbucketCloud{} } func (*BearerTokenBitbucketCloud) ProtoMessage() {} func (*BearerTokenBitbucketCloud) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{42} + return fileDescriptor_030104ce3b95bcac, []int{44} } func (m *BearerTokenBitbucketCloud) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1248,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_030104ce3b95bcac, []int{43} + return fileDescriptor_030104ce3b95bcac, []int{45} } func (m *ChartDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1276,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_030104ce3b95bcac, []int{44} + return fileDescriptor_030104ce3b95bcac, []int{46} } func (m *Cluster) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1304,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_030104ce3b95bcac, []int{45} + return fileDescriptor_030104ce3b95bcac, []int{47} } func (m *ClusterCacheInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1332,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_030104ce3b95bcac, []int{46} + return fileDescriptor_030104ce3b95bcac, []int{48} } func (m *ClusterConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1360,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_030104ce3b95bcac, []int{47} + return fileDescriptor_030104ce3b95bcac, []int{49} } func (m *ClusterGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1388,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_030104ce3b95bcac, []int{48} + return fileDescriptor_030104ce3b95bcac, []int{50} } func (m *ClusterInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1416,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_030104ce3b95bcac, []int{49} + return fileDescriptor_030104ce3b95bcac, []int{51} } func (m *ClusterList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1444,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_030104ce3b95bcac, []int{50} + return fileDescriptor_030104ce3b95bcac, []int{52} } func (m *Command) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1472,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_030104ce3b95bcac, []int{51} + return fileDescriptor_030104ce3b95bcac, []int{53} } func (m *ComparedTo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1500,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_030104ce3b95bcac, []int{52} + return fileDescriptor_030104ce3b95bcac, []int{54} } func (m *ComponentParameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1528,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_030104ce3b95bcac, []int{53} + return fileDescriptor_030104ce3b95bcac, []int{55} } func (m *ConfigManagementPlugin) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1553,10 +1609,38 @@ func (m *ConfigManagementPlugin) XXX_DiscardUnknown() { var xxx_messageInfo_ConfigManagementPlugin proto.InternalMessageInfo +func (m *ConfigMapKeyRef) Reset() { *m = ConfigMapKeyRef{} } +func (*ConfigMapKeyRef) ProtoMessage() {} +func (*ConfigMapKeyRef) Descriptor() ([]byte, []int) { + return fileDescriptor_030104ce3b95bcac, []int{56} +} +func (m *ConfigMapKeyRef) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ConfigMapKeyRef) 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 *ConfigMapKeyRef) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConfigMapKeyRef.Merge(m, src) +} +func (m *ConfigMapKeyRef) XXX_Size() int { + return m.Size() +} +func (m *ConfigMapKeyRef) XXX_DiscardUnknown() { + xxx_messageInfo_ConfigMapKeyRef.DiscardUnknown(m) +} + +var xxx_messageInfo_ConfigMapKeyRef proto.InternalMessageInfo + func (m *ConnectionState) Reset() { *m = ConnectionState{} } func (*ConnectionState) ProtoMessage() {} func (*ConnectionState) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{54} + return fileDescriptor_030104ce3b95bcac, []int{57} } func (m *ConnectionState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1584,7 +1668,7 @@ var xxx_messageInfo_ConnectionState proto.InternalMessageInfo func (m *DuckTypeGenerator) Reset() { *m = DuckTypeGenerator{} } func (*DuckTypeGenerator) ProtoMessage() {} func (*DuckTypeGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{55} + return fileDescriptor_030104ce3b95bcac, []int{58} } func (m *DuckTypeGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1612,7 +1696,7 @@ var xxx_messageInfo_DuckTypeGenerator proto.InternalMessageInfo func (m *EnvEntry) Reset() { *m = EnvEntry{} } func (*EnvEntry) ProtoMessage() {} func (*EnvEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{56} + return fileDescriptor_030104ce3b95bcac, []int{59} } func (m *EnvEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1640,7 +1724,7 @@ var xxx_messageInfo_EnvEntry proto.InternalMessageInfo func (m *ErrApplicationNotAllowedToUseProject) Reset() { *m = ErrApplicationNotAllowedToUseProject{} } func (*ErrApplicationNotAllowedToUseProject) ProtoMessage() {} func (*ErrApplicationNotAllowedToUseProject) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{57} + return fileDescriptor_030104ce3b95bcac, []int{60} } func (m *ErrApplicationNotAllowedToUseProject) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1668,7 +1752,7 @@ var xxx_messageInfo_ErrApplicationNotAllowedToUseProject proto.InternalMessageIn func (m *ExecProviderConfig) Reset() { *m = ExecProviderConfig{} } func (*ExecProviderConfig) ProtoMessage() {} func (*ExecProviderConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{58} + return fileDescriptor_030104ce3b95bcac, []int{61} } func (m *ExecProviderConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1696,7 +1780,7 @@ var xxx_messageInfo_ExecProviderConfig proto.InternalMessageInfo func (m *GitDirectoryGeneratorItem) Reset() { *m = GitDirectoryGeneratorItem{} } func (*GitDirectoryGeneratorItem) ProtoMessage() {} func (*GitDirectoryGeneratorItem) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{59} + return fileDescriptor_030104ce3b95bcac, []int{62} } func (m *GitDirectoryGeneratorItem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1724,7 +1808,7 @@ var xxx_messageInfo_GitDirectoryGeneratorItem proto.InternalMessageInfo func (m *GitFileGeneratorItem) Reset() { *m = GitFileGeneratorItem{} } func (*GitFileGeneratorItem) ProtoMessage() {} func (*GitFileGeneratorItem) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{60} + return fileDescriptor_030104ce3b95bcac, []int{63} } func (m *GitFileGeneratorItem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1752,7 +1836,7 @@ var xxx_messageInfo_GitFileGeneratorItem proto.InternalMessageInfo func (m *GitGenerator) Reset() { *m = GitGenerator{} } func (*GitGenerator) ProtoMessage() {} func (*GitGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{61} + return fileDescriptor_030104ce3b95bcac, []int{64} } func (m *GitGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1780,7 +1864,7 @@ var xxx_messageInfo_GitGenerator proto.InternalMessageInfo func (m *GnuPGPublicKey) Reset() { *m = GnuPGPublicKey{} } func (*GnuPGPublicKey) ProtoMessage() {} func (*GnuPGPublicKey) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{62} + return fileDescriptor_030104ce3b95bcac, []int{65} } func (m *GnuPGPublicKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1808,7 +1892,7 @@ var xxx_messageInfo_GnuPGPublicKey proto.InternalMessageInfo func (m *GnuPGPublicKeyList) Reset() { *m = GnuPGPublicKeyList{} } func (*GnuPGPublicKeyList) ProtoMessage() {} func (*GnuPGPublicKeyList) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{63} + return fileDescriptor_030104ce3b95bcac, []int{66} } func (m *GnuPGPublicKeyList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1836,7 +1920,7 @@ var xxx_messageInfo_GnuPGPublicKeyList proto.InternalMessageInfo func (m *HealthStatus) Reset() { *m = HealthStatus{} } func (*HealthStatus) ProtoMessage() {} func (*HealthStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{64} + return fileDescriptor_030104ce3b95bcac, []int{67} } func (m *HealthStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1864,7 +1948,7 @@ var xxx_messageInfo_HealthStatus proto.InternalMessageInfo func (m *HelmFileParameter) Reset() { *m = HelmFileParameter{} } func (*HelmFileParameter) ProtoMessage() {} func (*HelmFileParameter) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{65} + return fileDescriptor_030104ce3b95bcac, []int{68} } func (m *HelmFileParameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1892,7 +1976,7 @@ var xxx_messageInfo_HelmFileParameter proto.InternalMessageInfo func (m *HelmOptions) Reset() { *m = HelmOptions{} } func (*HelmOptions) ProtoMessage() {} func (*HelmOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{66} + return fileDescriptor_030104ce3b95bcac, []int{69} } func (m *HelmOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1920,7 +2004,7 @@ var xxx_messageInfo_HelmOptions proto.InternalMessageInfo func (m *HelmParameter) Reset() { *m = HelmParameter{} } func (*HelmParameter) ProtoMessage() {} func (*HelmParameter) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{67} + return fileDescriptor_030104ce3b95bcac, []int{70} } func (m *HelmParameter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1948,7 +2032,7 @@ var xxx_messageInfo_HelmParameter proto.InternalMessageInfo func (m *HostInfo) Reset() { *m = HostInfo{} } func (*HostInfo) ProtoMessage() {} func (*HostInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{68} + return fileDescriptor_030104ce3b95bcac, []int{71} } func (m *HostInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1976,7 +2060,7 @@ var xxx_messageInfo_HostInfo proto.InternalMessageInfo func (m *HostResourceInfo) Reset() { *m = HostResourceInfo{} } func (*HostResourceInfo) ProtoMessage() {} func (*HostResourceInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{69} + return fileDescriptor_030104ce3b95bcac, []int{72} } func (m *HostResourceInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2004,7 +2088,7 @@ var xxx_messageInfo_HostResourceInfo proto.InternalMessageInfo func (m *Info) Reset() { *m = Info{} } func (*Info) ProtoMessage() {} func (*Info) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{70} + return fileDescriptor_030104ce3b95bcac, []int{73} } func (m *Info) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2032,7 +2116,7 @@ var xxx_messageInfo_Info proto.InternalMessageInfo func (m *InfoItem) Reset() { *m = InfoItem{} } func (*InfoItem) ProtoMessage() {} func (*InfoItem) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{71} + return fileDescriptor_030104ce3b95bcac, []int{74} } func (m *InfoItem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2060,7 +2144,7 @@ var xxx_messageInfo_InfoItem proto.InternalMessageInfo func (m *JWTToken) Reset() { *m = JWTToken{} } func (*JWTToken) ProtoMessage() {} func (*JWTToken) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{72} + return fileDescriptor_030104ce3b95bcac, []int{75} } func (m *JWTToken) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2088,7 +2172,7 @@ var xxx_messageInfo_JWTToken proto.InternalMessageInfo func (m *JWTTokens) Reset() { *m = JWTTokens{} } func (*JWTTokens) ProtoMessage() {} func (*JWTTokens) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{73} + return fileDescriptor_030104ce3b95bcac, []int{76} } func (m *JWTTokens) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2116,7 +2200,7 @@ var xxx_messageInfo_JWTTokens proto.InternalMessageInfo func (m *JsonnetVar) Reset() { *m = JsonnetVar{} } func (*JsonnetVar) ProtoMessage() {} func (*JsonnetVar) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{74} + return fileDescriptor_030104ce3b95bcac, []int{77} } func (m *JsonnetVar) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2144,7 +2228,7 @@ var xxx_messageInfo_JsonnetVar proto.InternalMessageInfo func (m *KnownTypeField) Reset() { *m = KnownTypeField{} } func (*KnownTypeField) ProtoMessage() {} func (*KnownTypeField) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{75} + return fileDescriptor_030104ce3b95bcac, []int{78} } func (m *KnownTypeField) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2172,7 +2256,7 @@ var xxx_messageInfo_KnownTypeField proto.InternalMessageInfo func (m *KustomizeGvk) Reset() { *m = KustomizeGvk{} } func (*KustomizeGvk) ProtoMessage() {} func (*KustomizeGvk) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{76} + return fileDescriptor_030104ce3b95bcac, []int{79} } func (m *KustomizeGvk) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2200,7 +2284,7 @@ var xxx_messageInfo_KustomizeGvk proto.InternalMessageInfo func (m *KustomizeOptions) Reset() { *m = KustomizeOptions{} } func (*KustomizeOptions) ProtoMessage() {} func (*KustomizeOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{77} + return fileDescriptor_030104ce3b95bcac, []int{80} } func (m *KustomizeOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2228,7 +2312,7 @@ var xxx_messageInfo_KustomizeOptions proto.InternalMessageInfo func (m *KustomizePatch) Reset() { *m = KustomizePatch{} } func (*KustomizePatch) ProtoMessage() {} func (*KustomizePatch) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{78} + return fileDescriptor_030104ce3b95bcac, []int{81} } func (m *KustomizePatch) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2256,7 +2340,7 @@ var xxx_messageInfo_KustomizePatch proto.InternalMessageInfo func (m *KustomizeReplica) Reset() { *m = KustomizeReplica{} } func (*KustomizeReplica) ProtoMessage() {} func (*KustomizeReplica) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{79} + return fileDescriptor_030104ce3b95bcac, []int{82} } func (m *KustomizeReplica) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2284,7 +2368,7 @@ var xxx_messageInfo_KustomizeReplica proto.InternalMessageInfo func (m *KustomizeResId) Reset() { *m = KustomizeResId{} } func (*KustomizeResId) ProtoMessage() {} func (*KustomizeResId) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{80} + return fileDescriptor_030104ce3b95bcac, []int{83} } func (m *KustomizeResId) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2312,7 +2396,7 @@ var xxx_messageInfo_KustomizeResId proto.InternalMessageInfo func (m *KustomizeSelector) Reset() { *m = KustomizeSelector{} } func (*KustomizeSelector) ProtoMessage() {} func (*KustomizeSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{81} + return fileDescriptor_030104ce3b95bcac, []int{84} } func (m *KustomizeSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2340,7 +2424,7 @@ var xxx_messageInfo_KustomizeSelector proto.InternalMessageInfo func (m *ListGenerator) Reset() { *m = ListGenerator{} } func (*ListGenerator) ProtoMessage() {} func (*ListGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{82} + return fileDescriptor_030104ce3b95bcac, []int{85} } func (m *ListGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2368,7 +2452,7 @@ var xxx_messageInfo_ListGenerator proto.InternalMessageInfo func (m *ManagedNamespaceMetadata) Reset() { *m = ManagedNamespaceMetadata{} } func (*ManagedNamespaceMetadata) ProtoMessage() {} func (*ManagedNamespaceMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{83} + return fileDescriptor_030104ce3b95bcac, []int{86} } func (m *ManagedNamespaceMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2396,7 +2480,7 @@ var xxx_messageInfo_ManagedNamespaceMetadata proto.InternalMessageInfo func (m *MatrixGenerator) Reset() { *m = MatrixGenerator{} } func (*MatrixGenerator) ProtoMessage() {} func (*MatrixGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{84} + return fileDescriptor_030104ce3b95bcac, []int{87} } func (m *MatrixGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2424,7 +2508,7 @@ var xxx_messageInfo_MatrixGenerator proto.InternalMessageInfo func (m *MergeGenerator) Reset() { *m = MergeGenerator{} } func (*MergeGenerator) ProtoMessage() {} func (*MergeGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{85} + return fileDescriptor_030104ce3b95bcac, []int{88} } func (m *MergeGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2452,7 +2536,7 @@ var xxx_messageInfo_MergeGenerator proto.InternalMessageInfo func (m *NestedMatrixGenerator) Reset() { *m = NestedMatrixGenerator{} } func (*NestedMatrixGenerator) ProtoMessage() {} func (*NestedMatrixGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{86} + return fileDescriptor_030104ce3b95bcac, []int{89} } func (m *NestedMatrixGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2480,7 +2564,7 @@ var xxx_messageInfo_NestedMatrixGenerator proto.InternalMessageInfo func (m *NestedMergeGenerator) Reset() { *m = NestedMergeGenerator{} } func (*NestedMergeGenerator) ProtoMessage() {} func (*NestedMergeGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{87} + return fileDescriptor_030104ce3b95bcac, []int{90} } func (m *NestedMergeGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2508,7 +2592,7 @@ var xxx_messageInfo_NestedMergeGenerator proto.InternalMessageInfo func (m *Operation) Reset() { *m = Operation{} } func (*Operation) ProtoMessage() {} func (*Operation) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{88} + return fileDescriptor_030104ce3b95bcac, []int{91} } func (m *Operation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2536,7 +2620,7 @@ var xxx_messageInfo_Operation proto.InternalMessageInfo func (m *OperationInitiator) Reset() { *m = OperationInitiator{} } func (*OperationInitiator) ProtoMessage() {} func (*OperationInitiator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{89} + return fileDescriptor_030104ce3b95bcac, []int{92} } func (m *OperationInitiator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2564,7 +2648,7 @@ var xxx_messageInfo_OperationInitiator proto.InternalMessageInfo func (m *OperationState) Reset() { *m = OperationState{} } func (*OperationState) ProtoMessage() {} func (*OperationState) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{90} + return fileDescriptor_030104ce3b95bcac, []int{93} } func (m *OperationState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2592,7 +2676,7 @@ var xxx_messageInfo_OperationState proto.InternalMessageInfo func (m *OptionalArray) Reset() { *m = OptionalArray{} } func (*OptionalArray) ProtoMessage() {} func (*OptionalArray) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{91} + return fileDescriptor_030104ce3b95bcac, []int{94} } func (m *OptionalArray) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2620,7 +2704,7 @@ var xxx_messageInfo_OptionalArray proto.InternalMessageInfo func (m *OptionalMap) Reset() { *m = OptionalMap{} } func (*OptionalMap) ProtoMessage() {} func (*OptionalMap) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{92} + return fileDescriptor_030104ce3b95bcac, []int{95} } func (m *OptionalMap) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2648,7 +2732,7 @@ var xxx_messageInfo_OptionalMap proto.InternalMessageInfo func (m *OrphanedResourceKey) Reset() { *m = OrphanedResourceKey{} } func (*OrphanedResourceKey) ProtoMessage() {} func (*OrphanedResourceKey) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{93} + return fileDescriptor_030104ce3b95bcac, []int{96} } func (m *OrphanedResourceKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2676,7 +2760,7 @@ var xxx_messageInfo_OrphanedResourceKey proto.InternalMessageInfo func (m *OrphanedResourcesMonitorSettings) Reset() { *m = OrphanedResourcesMonitorSettings{} } func (*OrphanedResourcesMonitorSettings) ProtoMessage() {} func (*OrphanedResourcesMonitorSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{94} + return fileDescriptor_030104ce3b95bcac, []int{97} } func (m *OrphanedResourcesMonitorSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2704,7 +2788,7 @@ var xxx_messageInfo_OrphanedResourcesMonitorSettings proto.InternalMessageInfo func (m *OverrideIgnoreDiff) Reset() { *m = OverrideIgnoreDiff{} } func (*OverrideIgnoreDiff) ProtoMessage() {} func (*OverrideIgnoreDiff) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{95} + return fileDescriptor_030104ce3b95bcac, []int{98} } func (m *OverrideIgnoreDiff) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2732,7 +2816,7 @@ var xxx_messageInfo_OverrideIgnoreDiff proto.InternalMessageInfo func (m *PluginConfigMapRef) Reset() { *m = PluginConfigMapRef{} } func (*PluginConfigMapRef) ProtoMessage() {} func (*PluginConfigMapRef) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{96} + return fileDescriptor_030104ce3b95bcac, []int{99} } func (m *PluginConfigMapRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2760,7 +2844,7 @@ var xxx_messageInfo_PluginConfigMapRef proto.InternalMessageInfo func (m *PluginGenerator) Reset() { *m = PluginGenerator{} } func (*PluginGenerator) ProtoMessage() {} func (*PluginGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{97} + return fileDescriptor_030104ce3b95bcac, []int{100} } func (m *PluginGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2788,7 +2872,7 @@ var xxx_messageInfo_PluginGenerator proto.InternalMessageInfo func (m *PluginInput) Reset() { *m = PluginInput{} } func (*PluginInput) ProtoMessage() {} func (*PluginInput) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{98} + return fileDescriptor_030104ce3b95bcac, []int{101} } func (m *PluginInput) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2816,7 +2900,7 @@ var xxx_messageInfo_PluginInput proto.InternalMessageInfo func (m *ProjectRole) Reset() { *m = ProjectRole{} } func (*ProjectRole) ProtoMessage() {} func (*ProjectRole) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{99} + return fileDescriptor_030104ce3b95bcac, []int{102} } func (m *ProjectRole) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2844,7 +2928,7 @@ var xxx_messageInfo_ProjectRole proto.InternalMessageInfo func (m *PullRequestGenerator) Reset() { *m = PullRequestGenerator{} } func (*PullRequestGenerator) ProtoMessage() {} func (*PullRequestGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{100} + return fileDescriptor_030104ce3b95bcac, []int{103} } func (m *PullRequestGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2872,7 +2956,7 @@ var xxx_messageInfo_PullRequestGenerator proto.InternalMessageInfo func (m *PullRequestGeneratorAzureDevOps) Reset() { *m = PullRequestGeneratorAzureDevOps{} } func (*PullRequestGeneratorAzureDevOps) ProtoMessage() {} func (*PullRequestGeneratorAzureDevOps) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{101} + return fileDescriptor_030104ce3b95bcac, []int{104} } func (m *PullRequestGeneratorAzureDevOps) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2900,7 +2984,7 @@ var xxx_messageInfo_PullRequestGeneratorAzureDevOps proto.InternalMessageInfo func (m *PullRequestGeneratorBitbucket) Reset() { *m = PullRequestGeneratorBitbucket{} } func (*PullRequestGeneratorBitbucket) ProtoMessage() {} func (*PullRequestGeneratorBitbucket) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{102} + return fileDescriptor_030104ce3b95bcac, []int{105} } func (m *PullRequestGeneratorBitbucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2928,7 +3012,7 @@ var xxx_messageInfo_PullRequestGeneratorBitbucket proto.InternalMessageInfo func (m *PullRequestGeneratorBitbucketServer) Reset() { *m = PullRequestGeneratorBitbucketServer{} } func (*PullRequestGeneratorBitbucketServer) ProtoMessage() {} func (*PullRequestGeneratorBitbucketServer) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{103} + return fileDescriptor_030104ce3b95bcac, []int{106} } func (m *PullRequestGeneratorBitbucketServer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2956,7 +3040,7 @@ var xxx_messageInfo_PullRequestGeneratorBitbucketServer proto.InternalMessageInf func (m *PullRequestGeneratorFilter) Reset() { *m = PullRequestGeneratorFilter{} } func (*PullRequestGeneratorFilter) ProtoMessage() {} func (*PullRequestGeneratorFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{104} + return fileDescriptor_030104ce3b95bcac, []int{107} } func (m *PullRequestGeneratorFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2984,7 +3068,7 @@ var xxx_messageInfo_PullRequestGeneratorFilter proto.InternalMessageInfo func (m *PullRequestGeneratorGitLab) Reset() { *m = PullRequestGeneratorGitLab{} } func (*PullRequestGeneratorGitLab) ProtoMessage() {} func (*PullRequestGeneratorGitLab) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{105} + return fileDescriptor_030104ce3b95bcac, []int{108} } func (m *PullRequestGeneratorGitLab) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3012,7 +3096,7 @@ var xxx_messageInfo_PullRequestGeneratorGitLab proto.InternalMessageInfo func (m *PullRequestGeneratorGitea) Reset() { *m = PullRequestGeneratorGitea{} } func (*PullRequestGeneratorGitea) ProtoMessage() {} func (*PullRequestGeneratorGitea) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{106} + return fileDescriptor_030104ce3b95bcac, []int{109} } func (m *PullRequestGeneratorGitea) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3040,7 +3124,7 @@ var xxx_messageInfo_PullRequestGeneratorGitea proto.InternalMessageInfo func (m *PullRequestGeneratorGithub) Reset() { *m = PullRequestGeneratorGithub{} } func (*PullRequestGeneratorGithub) ProtoMessage() {} func (*PullRequestGeneratorGithub) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{107} + return fileDescriptor_030104ce3b95bcac, []int{110} } func (m *PullRequestGeneratorGithub) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3068,7 +3152,7 @@ var xxx_messageInfo_PullRequestGeneratorGithub proto.InternalMessageInfo func (m *RefTarget) Reset() { *m = RefTarget{} } func (*RefTarget) ProtoMessage() {} func (*RefTarget) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{108} + return fileDescriptor_030104ce3b95bcac, []int{111} } func (m *RefTarget) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3096,7 +3180,7 @@ var xxx_messageInfo_RefTarget proto.InternalMessageInfo func (m *RepoCreds) Reset() { *m = RepoCreds{} } func (*RepoCreds) ProtoMessage() {} func (*RepoCreds) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{109} + return fileDescriptor_030104ce3b95bcac, []int{112} } func (m *RepoCreds) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3124,7 +3208,7 @@ var xxx_messageInfo_RepoCreds proto.InternalMessageInfo func (m *RepoCredsList) Reset() { *m = RepoCredsList{} } func (*RepoCredsList) ProtoMessage() {} func (*RepoCredsList) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{110} + return fileDescriptor_030104ce3b95bcac, []int{113} } func (m *RepoCredsList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3152,7 +3236,7 @@ var xxx_messageInfo_RepoCredsList proto.InternalMessageInfo func (m *Repository) Reset() { *m = Repository{} } func (*Repository) ProtoMessage() {} func (*Repository) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{111} + return fileDescriptor_030104ce3b95bcac, []int{114} } func (m *Repository) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3180,7 +3264,7 @@ var xxx_messageInfo_Repository proto.InternalMessageInfo func (m *RepositoryCertificate) Reset() { *m = RepositoryCertificate{} } func (*RepositoryCertificate) ProtoMessage() {} func (*RepositoryCertificate) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{112} + return fileDescriptor_030104ce3b95bcac, []int{115} } func (m *RepositoryCertificate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3208,7 +3292,7 @@ var xxx_messageInfo_RepositoryCertificate proto.InternalMessageInfo func (m *RepositoryCertificateList) Reset() { *m = RepositoryCertificateList{} } func (*RepositoryCertificateList) ProtoMessage() {} func (*RepositoryCertificateList) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{113} + return fileDescriptor_030104ce3b95bcac, []int{116} } func (m *RepositoryCertificateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3236,7 +3320,7 @@ var xxx_messageInfo_RepositoryCertificateList proto.InternalMessageInfo func (m *RepositoryList) Reset() { *m = RepositoryList{} } func (*RepositoryList) ProtoMessage() {} func (*RepositoryList) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{114} + return fileDescriptor_030104ce3b95bcac, []int{117} } func (m *RepositoryList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3264,7 +3348,7 @@ var xxx_messageInfo_RepositoryList proto.InternalMessageInfo func (m *ResourceAction) Reset() { *m = ResourceAction{} } func (*ResourceAction) ProtoMessage() {} func (*ResourceAction) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{115} + return fileDescriptor_030104ce3b95bcac, []int{118} } func (m *ResourceAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3292,7 +3376,7 @@ var xxx_messageInfo_ResourceAction proto.InternalMessageInfo func (m *ResourceActionDefinition) Reset() { *m = ResourceActionDefinition{} } func (*ResourceActionDefinition) ProtoMessage() {} func (*ResourceActionDefinition) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{116} + return fileDescriptor_030104ce3b95bcac, []int{119} } func (m *ResourceActionDefinition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3320,7 +3404,7 @@ var xxx_messageInfo_ResourceActionDefinition proto.InternalMessageInfo func (m *ResourceActionParam) Reset() { *m = ResourceActionParam{} } func (*ResourceActionParam) ProtoMessage() {} func (*ResourceActionParam) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{117} + return fileDescriptor_030104ce3b95bcac, []int{120} } func (m *ResourceActionParam) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3348,7 +3432,7 @@ var xxx_messageInfo_ResourceActionParam proto.InternalMessageInfo func (m *ResourceActions) Reset() { *m = ResourceActions{} } func (*ResourceActions) ProtoMessage() {} func (*ResourceActions) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{118} + return fileDescriptor_030104ce3b95bcac, []int{121} } func (m *ResourceActions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3376,7 +3460,7 @@ var xxx_messageInfo_ResourceActions proto.InternalMessageInfo func (m *ResourceDiff) Reset() { *m = ResourceDiff{} } func (*ResourceDiff) ProtoMessage() {} func (*ResourceDiff) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{119} + return fileDescriptor_030104ce3b95bcac, []int{122} } func (m *ResourceDiff) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3404,7 +3488,7 @@ var xxx_messageInfo_ResourceDiff proto.InternalMessageInfo func (m *ResourceIgnoreDifferences) Reset() { *m = ResourceIgnoreDifferences{} } func (*ResourceIgnoreDifferences) ProtoMessage() {} func (*ResourceIgnoreDifferences) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{120} + return fileDescriptor_030104ce3b95bcac, []int{123} } func (m *ResourceIgnoreDifferences) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3432,7 +3516,7 @@ var xxx_messageInfo_ResourceIgnoreDifferences proto.InternalMessageInfo func (m *ResourceNetworkingInfo) Reset() { *m = ResourceNetworkingInfo{} } func (*ResourceNetworkingInfo) ProtoMessage() {} func (*ResourceNetworkingInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{121} + return fileDescriptor_030104ce3b95bcac, []int{124} } func (m *ResourceNetworkingInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3460,7 +3544,7 @@ var xxx_messageInfo_ResourceNetworkingInfo proto.InternalMessageInfo func (m *ResourceNode) Reset() { *m = ResourceNode{} } func (*ResourceNode) ProtoMessage() {} func (*ResourceNode) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{122} + return fileDescriptor_030104ce3b95bcac, []int{125} } func (m *ResourceNode) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3488,7 +3572,7 @@ var xxx_messageInfo_ResourceNode proto.InternalMessageInfo func (m *ResourceOverride) Reset() { *m = ResourceOverride{} } func (*ResourceOverride) ProtoMessage() {} func (*ResourceOverride) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{123} + return fileDescriptor_030104ce3b95bcac, []int{126} } func (m *ResourceOverride) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3516,7 +3600,7 @@ var xxx_messageInfo_ResourceOverride proto.InternalMessageInfo func (m *ResourceRef) Reset() { *m = ResourceRef{} } func (*ResourceRef) ProtoMessage() {} func (*ResourceRef) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{124} + return fileDescriptor_030104ce3b95bcac, []int{127} } func (m *ResourceRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3544,7 +3628,7 @@ var xxx_messageInfo_ResourceRef proto.InternalMessageInfo func (m *ResourceResult) Reset() { *m = ResourceResult{} } func (*ResourceResult) ProtoMessage() {} func (*ResourceResult) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{125} + return fileDescriptor_030104ce3b95bcac, []int{128} } func (m *ResourceResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3572,7 +3656,7 @@ var xxx_messageInfo_ResourceResult proto.InternalMessageInfo func (m *ResourceStatus) Reset() { *m = ResourceStatus{} } func (*ResourceStatus) ProtoMessage() {} func (*ResourceStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{126} + return fileDescriptor_030104ce3b95bcac, []int{129} } func (m *ResourceStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3600,7 +3684,7 @@ var xxx_messageInfo_ResourceStatus proto.InternalMessageInfo func (m *RetryStrategy) Reset() { *m = RetryStrategy{} } func (*RetryStrategy) ProtoMessage() {} func (*RetryStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{127} + return fileDescriptor_030104ce3b95bcac, []int{130} } func (m *RetryStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3628,7 +3712,7 @@ var xxx_messageInfo_RetryStrategy proto.InternalMessageInfo func (m *RevisionHistory) Reset() { *m = RevisionHistory{} } func (*RevisionHistory) ProtoMessage() {} func (*RevisionHistory) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{128} + return fileDescriptor_030104ce3b95bcac, []int{131} } func (m *RevisionHistory) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3656,7 +3740,7 @@ var xxx_messageInfo_RevisionHistory proto.InternalMessageInfo func (m *RevisionMetadata) Reset() { *m = RevisionMetadata{} } func (*RevisionMetadata) ProtoMessage() {} func (*RevisionMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{129} + return fileDescriptor_030104ce3b95bcac, []int{132} } func (m *RevisionMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3684,7 +3768,7 @@ var xxx_messageInfo_RevisionMetadata proto.InternalMessageInfo func (m *SCMProviderGenerator) Reset() { *m = SCMProviderGenerator{} } func (*SCMProviderGenerator) ProtoMessage() {} func (*SCMProviderGenerator) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{130} + return fileDescriptor_030104ce3b95bcac, []int{133} } func (m *SCMProviderGenerator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3712,7 +3796,7 @@ var xxx_messageInfo_SCMProviderGenerator proto.InternalMessageInfo func (m *SCMProviderGeneratorAWSCodeCommit) Reset() { *m = SCMProviderGeneratorAWSCodeCommit{} } func (*SCMProviderGeneratorAWSCodeCommit) ProtoMessage() {} func (*SCMProviderGeneratorAWSCodeCommit) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{131} + return fileDescriptor_030104ce3b95bcac, []int{134} } func (m *SCMProviderGeneratorAWSCodeCommit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3740,7 +3824,7 @@ var xxx_messageInfo_SCMProviderGeneratorAWSCodeCommit proto.InternalMessageInfo func (m *SCMProviderGeneratorAzureDevOps) Reset() { *m = SCMProviderGeneratorAzureDevOps{} } func (*SCMProviderGeneratorAzureDevOps) ProtoMessage() {} func (*SCMProviderGeneratorAzureDevOps) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{132} + return fileDescriptor_030104ce3b95bcac, []int{135} } func (m *SCMProviderGeneratorAzureDevOps) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3768,7 +3852,7 @@ var xxx_messageInfo_SCMProviderGeneratorAzureDevOps proto.InternalMessageInfo func (m *SCMProviderGeneratorBitbucket) Reset() { *m = SCMProviderGeneratorBitbucket{} } func (*SCMProviderGeneratorBitbucket) ProtoMessage() {} func (*SCMProviderGeneratorBitbucket) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{133} + return fileDescriptor_030104ce3b95bcac, []int{136} } func (m *SCMProviderGeneratorBitbucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3796,7 +3880,7 @@ var xxx_messageInfo_SCMProviderGeneratorBitbucket proto.InternalMessageInfo func (m *SCMProviderGeneratorBitbucketServer) Reset() { *m = SCMProviderGeneratorBitbucketServer{} } func (*SCMProviderGeneratorBitbucketServer) ProtoMessage() {} func (*SCMProviderGeneratorBitbucketServer) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{134} + return fileDescriptor_030104ce3b95bcac, []int{137} } func (m *SCMProviderGeneratorBitbucketServer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3824,7 +3908,7 @@ var xxx_messageInfo_SCMProviderGeneratorBitbucketServer proto.InternalMessageInf func (m *SCMProviderGeneratorFilter) Reset() { *m = SCMProviderGeneratorFilter{} } func (*SCMProviderGeneratorFilter) ProtoMessage() {} func (*SCMProviderGeneratorFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{135} + return fileDescriptor_030104ce3b95bcac, []int{138} } func (m *SCMProviderGeneratorFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3852,7 +3936,7 @@ var xxx_messageInfo_SCMProviderGeneratorFilter proto.InternalMessageInfo func (m *SCMProviderGeneratorGitea) Reset() { *m = SCMProviderGeneratorGitea{} } func (*SCMProviderGeneratorGitea) ProtoMessage() {} func (*SCMProviderGeneratorGitea) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{136} + return fileDescriptor_030104ce3b95bcac, []int{139} } func (m *SCMProviderGeneratorGitea) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3880,7 +3964,7 @@ var xxx_messageInfo_SCMProviderGeneratorGitea proto.InternalMessageInfo func (m *SCMProviderGeneratorGithub) Reset() { *m = SCMProviderGeneratorGithub{} } func (*SCMProviderGeneratorGithub) ProtoMessage() {} func (*SCMProviderGeneratorGithub) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{137} + return fileDescriptor_030104ce3b95bcac, []int{140} } func (m *SCMProviderGeneratorGithub) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3908,7 +3992,7 @@ var xxx_messageInfo_SCMProviderGeneratorGithub proto.InternalMessageInfo func (m *SCMProviderGeneratorGitlab) Reset() { *m = SCMProviderGeneratorGitlab{} } func (*SCMProviderGeneratorGitlab) ProtoMessage() {} func (*SCMProviderGeneratorGitlab) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{138} + return fileDescriptor_030104ce3b95bcac, []int{141} } func (m *SCMProviderGeneratorGitlab) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3936,7 +4020,7 @@ var xxx_messageInfo_SCMProviderGeneratorGitlab proto.InternalMessageInfo func (m *SecretRef) Reset() { *m = SecretRef{} } func (*SecretRef) ProtoMessage() {} func (*SecretRef) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{139} + return fileDescriptor_030104ce3b95bcac, []int{142} } func (m *SecretRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3964,7 +4048,7 @@ var xxx_messageInfo_SecretRef proto.InternalMessageInfo func (m *SignatureKey) Reset() { *m = SignatureKey{} } func (*SignatureKey) ProtoMessage() {} func (*SignatureKey) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{140} + return fileDescriptor_030104ce3b95bcac, []int{143} } func (m *SignatureKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3992,7 +4076,7 @@ var xxx_messageInfo_SignatureKey proto.InternalMessageInfo func (m *SyncOperation) Reset() { *m = SyncOperation{} } func (*SyncOperation) ProtoMessage() {} func (*SyncOperation) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{141} + return fileDescriptor_030104ce3b95bcac, []int{144} } func (m *SyncOperation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4020,7 +4104,7 @@ var xxx_messageInfo_SyncOperation proto.InternalMessageInfo func (m *SyncOperationResource) Reset() { *m = SyncOperationResource{} } func (*SyncOperationResource) ProtoMessage() {} func (*SyncOperationResource) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{142} + return fileDescriptor_030104ce3b95bcac, []int{145} } func (m *SyncOperationResource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4048,7 +4132,7 @@ var xxx_messageInfo_SyncOperationResource proto.InternalMessageInfo func (m *SyncOperationResult) Reset() { *m = SyncOperationResult{} } func (*SyncOperationResult) ProtoMessage() {} func (*SyncOperationResult) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{143} + return fileDescriptor_030104ce3b95bcac, []int{146} } func (m *SyncOperationResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4076,7 +4160,7 @@ var xxx_messageInfo_SyncOperationResult proto.InternalMessageInfo func (m *SyncPolicy) Reset() { *m = SyncPolicy{} } func (*SyncPolicy) ProtoMessage() {} func (*SyncPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{144} + return fileDescriptor_030104ce3b95bcac, []int{147} } func (m *SyncPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4104,7 +4188,7 @@ var xxx_messageInfo_SyncPolicy proto.InternalMessageInfo func (m *SyncPolicyAutomated) Reset() { *m = SyncPolicyAutomated{} } func (*SyncPolicyAutomated) ProtoMessage() {} func (*SyncPolicyAutomated) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{145} + return fileDescriptor_030104ce3b95bcac, []int{148} } func (m *SyncPolicyAutomated) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4132,7 +4216,7 @@ var xxx_messageInfo_SyncPolicyAutomated proto.InternalMessageInfo func (m *SyncStatus) Reset() { *m = SyncStatus{} } func (*SyncStatus) ProtoMessage() {} func (*SyncStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{146} + return fileDescriptor_030104ce3b95bcac, []int{149} } func (m *SyncStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4160,7 +4244,7 @@ var xxx_messageInfo_SyncStatus proto.InternalMessageInfo func (m *SyncStrategy) Reset() { *m = SyncStrategy{} } func (*SyncStrategy) ProtoMessage() {} func (*SyncStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{147} + return fileDescriptor_030104ce3b95bcac, []int{150} } func (m *SyncStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4188,7 +4272,7 @@ var xxx_messageInfo_SyncStrategy proto.InternalMessageInfo func (m *SyncStrategyApply) Reset() { *m = SyncStrategyApply{} } func (*SyncStrategyApply) ProtoMessage() {} func (*SyncStrategyApply) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{148} + return fileDescriptor_030104ce3b95bcac, []int{151} } func (m *SyncStrategyApply) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4216,7 +4300,7 @@ var xxx_messageInfo_SyncStrategyApply proto.InternalMessageInfo func (m *SyncStrategyHook) Reset() { *m = SyncStrategyHook{} } func (*SyncStrategyHook) ProtoMessage() {} func (*SyncStrategyHook) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{149} + return fileDescriptor_030104ce3b95bcac, []int{152} } func (m *SyncStrategyHook) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4244,7 +4328,7 @@ var xxx_messageInfo_SyncStrategyHook proto.InternalMessageInfo func (m *SyncWindow) Reset() { *m = SyncWindow{} } func (*SyncWindow) ProtoMessage() {} func (*SyncWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{150} + return fileDescriptor_030104ce3b95bcac, []int{153} } func (m *SyncWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4272,7 +4356,7 @@ var xxx_messageInfo_SyncWindow proto.InternalMessageInfo func (m *TLSClientConfig) Reset() { *m = TLSClientConfig{} } func (*TLSClientConfig) ProtoMessage() {} func (*TLSClientConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{151} + return fileDescriptor_030104ce3b95bcac, []int{154} } func (m *TLSClientConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4300,7 +4384,7 @@ var xxx_messageInfo_TLSClientConfig proto.InternalMessageInfo func (m *TagFilter) Reset() { *m = TagFilter{} } func (*TagFilter) ProtoMessage() {} func (*TagFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_030104ce3b95bcac, []int{152} + return fileDescriptor_030104ce3b95bcac, []int{155} } func (m *TagFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4335,6 +4419,7 @@ func init() { 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") @@ -4373,6 +4458,7 @@ func init() { 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") @@ -4388,6 +4474,7 @@ func init() { 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((*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") @@ -4506,701 +4593,717 @@ func init() { } var fileDescriptor_030104ce3b95bcac = []byte{ - // 11095 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6f, 0x70, 0x24, 0xc7, - 0x75, 0x18, 0xae, 0xd9, 0xc5, 0x02, 0xbb, 0x0f, 0x7f, 0xee, 0xae, 0xef, 0x8e, 0x04, 0x4f, 0x24, - 0x71, 0x1e, 0xda, 0x14, 0xf5, 0x13, 0x09, 0x98, 0x27, 0x52, 0xe6, 0x4f, 0xb4, 0x24, 0x63, 0x81, - 0x3b, 0x1c, 0xee, 0x80, 0x03, 0xd8, 0xc0, 0xdd, 0x49, 0x94, 0x29, 0x6a, 0xb0, 0xdb, 0x58, 0xcc, - 0x61, 0x76, 0x66, 0x38, 0x33, 0x8b, 0x03, 0x68, 0x49, 0x96, 0x2c, 0xc9, 0x56, 0xa2, 0x3f, 0x54, - 0xa4, 0xa4, 0x4c, 0x27, 0x96, 0x22, 0x5b, 0x4e, 0x2a, 0xae, 0x44, 0x15, 0x27, 0xf9, 0x10, 0x27, - 0x4e, 0xca, 0x15, 0x3b, 0x95, 0x52, 0xe2, 0xa4, 0xec, 0x72, 0xb9, 0x2c, 0x27, 0xb1, 0x11, 0xe9, - 0x52, 0xa9, 0xa4, 0x52, 0x15, 0x57, 0x39, 0xf1, 0x87, 0xe4, 0x92, 0x0f, 0xa9, 0xfe, 0xdf, 0x33, - 0x3b, 0x0b, 0x2c, 0x80, 0xc1, 0xdd, 0x49, 0xe1, 0xb7, 0xdd, 0x7e, 0x6f, 0xde, 0xeb, 0xe9, 0xe9, - 0x7e, 0xef, 0xf5, 0xeb, 0xf7, 0x5e, 0xc3, 0x42, 0xcb, 0x4d, 0x36, 0x3a, 0x6b, 0x93, 0x8d, 0xa0, - 0x3d, 0xe5, 0x44, 0xad, 0x20, 0x8c, 0x82, 0x5b, 0xec, 0xc7, 0x33, 0x8d, 0xe6, 0xd4, 0xd6, 0x85, - 0xa9, 0x70, 0xb3, 0x35, 0xe5, 0x84, 0x6e, 0x3c, 0xe5, 0x84, 0xa1, 0xe7, 0x36, 0x9c, 0xc4, 0x0d, - 0xfc, 0xa9, 0xad, 0x67, 0x1d, 0x2f, 0xdc, 0x70, 0x9e, 0x9d, 0x6a, 0x11, 0x9f, 0x44, 0x4e, 0x42, - 0x9a, 0x93, 0x61, 0x14, 0x24, 0x01, 0xfa, 0x71, 0x4d, 0x6d, 0x52, 0x52, 0x63, 0x3f, 0x5e, 0x6d, - 0x34, 0x27, 0xb7, 0x2e, 0x4c, 0x86, 0x9b, 0xad, 0x49, 0x4a, 0x6d, 0xd2, 0xa0, 0x36, 0x29, 0xa9, - 0x9d, 0x7b, 0xc6, 0xe8, 0x4b, 0x2b, 0x68, 0x05, 0x53, 0x8c, 0xe8, 0x5a, 0x67, 0x9d, 0xfd, 0x63, - 0x7f, 0xd8, 0x2f, 0xce, 0xec, 0x9c, 0xbd, 0xf9, 0x42, 0x3c, 0xe9, 0x06, 0xb4, 0x7b, 0x53, 0x8d, - 0x20, 0x22, 0x53, 0x5b, 0x5d, 0x1d, 0x3a, 0x77, 0x59, 0xe3, 0x90, 0xed, 0x84, 0xf8, 0xb1, 0x1b, - 0xf8, 0xf1, 0x33, 0xb4, 0x0b, 0x24, 0xda, 0x22, 0x91, 0xf9, 0x7a, 0x06, 0x42, 0x1e, 0xa5, 0xe7, - 0x34, 0xa5, 0xb6, 0xd3, 0xd8, 0x70, 0x7d, 0x12, 0xed, 0xe8, 0xc7, 0xdb, 0x24, 0x71, 0xf2, 0x9e, - 0x9a, 0xea, 0xf5, 0x54, 0xd4, 0xf1, 0x13, 0xb7, 0x4d, 0xba, 0x1e, 0x78, 0xcf, 0x7e, 0x0f, 0xc4, - 0x8d, 0x0d, 0xd2, 0x76, 0xba, 0x9e, 0x7b, 0x77, 0xaf, 0xe7, 0x3a, 0x89, 0xeb, 0x4d, 0xb9, 0x7e, - 0x12, 0x27, 0x51, 0xf6, 0x21, 0xfb, 0x17, 0x2d, 0x18, 0x9d, 0xbe, 0xb9, 0x32, 0xdd, 0x49, 0x36, - 0x66, 0x02, 0x7f, 0xdd, 0x6d, 0xa1, 0xe7, 0x61, 0xb8, 0xe1, 0x75, 0xe2, 0x84, 0x44, 0xd7, 0x9c, - 0x36, 0x19, 0xb7, 0xce, 0x5b, 0x4f, 0xd5, 0xea, 0xa7, 0xbf, 0xbd, 0x3b, 0xf1, 0xb6, 0x3b, 0xbb, - 0x13, 0xc3, 0x33, 0x1a, 0x84, 0x4d, 0x3c, 0xf4, 0x4e, 0x18, 0x8a, 0x02, 0x8f, 0x4c, 0xe3, 0x6b, - 0xe3, 0x25, 0xf6, 0xc8, 0x09, 0xf1, 0xc8, 0x10, 0xe6, 0xcd, 0x58, 0xc2, 0x29, 0x6a, 0x18, 0x05, - 0xeb, 0xae, 0x47, 0xc6, 0xcb, 0x69, 0xd4, 0x65, 0xde, 0x8c, 0x25, 0xdc, 0xfe, 0xc3, 0x12, 0xc0, - 0x74, 0x18, 0x2e, 0x47, 0xc1, 0x2d, 0xd2, 0x48, 0xd0, 0x47, 0xa1, 0x4a, 0x87, 0xb9, 0xe9, 0x24, - 0x0e, 0xeb, 0xd8, 0xf0, 0x85, 0x1f, 0x9d, 0xe4, 0x6f, 0x3d, 0x69, 0xbe, 0xb5, 0x9e, 0x64, 0x14, - 0x7b, 0x72, 0xeb, 0xd9, 0xc9, 0xa5, 0x35, 0xfa, 0xfc, 0x22, 0x49, 0x9c, 0x3a, 0x12, 0xcc, 0x40, - 0xb7, 0x61, 0x45, 0x15, 0xf9, 0x30, 0x10, 0x87, 0xa4, 0xc1, 0xde, 0x61, 0xf8, 0xc2, 0xc2, 0xe4, - 0x51, 0x66, 0xf3, 0xa4, 0xee, 0xf9, 0x4a, 0x48, 0x1a, 0xf5, 0x11, 0xc1, 0x79, 0x80, 0xfe, 0xc3, - 0x8c, 0x0f, 0xda, 0x82, 0xc1, 0x38, 0x71, 0x92, 0x4e, 0xcc, 0x86, 0x62, 0xf8, 0xc2, 0xb5, 0xc2, - 0x38, 0x32, 0xaa, 0xf5, 0x31, 0xc1, 0x73, 0x90, 0xff, 0xc7, 0x82, 0x9b, 0xfd, 0x27, 0x16, 0x8c, - 0x69, 0xe4, 0x05, 0x37, 0x4e, 0xd0, 0x4f, 0x76, 0x0d, 0xee, 0x64, 0x7f, 0x83, 0x4b, 0x9f, 0x66, - 0x43, 0x7b, 0x52, 0x30, 0xab, 0xca, 0x16, 0x63, 0x60, 0xdb, 0x50, 0x71, 0x13, 0xd2, 0x8e, 0xc7, - 0x4b, 0xe7, 0xcb, 0x4f, 0x0d, 0x5f, 0xb8, 0x5c, 0xd4, 0x7b, 0xd6, 0x47, 0x05, 0xd3, 0xca, 0x3c, - 0x25, 0x8f, 0x39, 0x17, 0xfb, 0x57, 0x47, 0xcc, 0xf7, 0xa3, 0x03, 0x8e, 0x9e, 0x85, 0xe1, 0x38, - 0xe8, 0x44, 0x0d, 0x82, 0x49, 0x18, 0xc4, 0xe3, 0xd6, 0xf9, 0x32, 0x9d, 0x7a, 0x74, 0x52, 0xaf, - 0xe8, 0x66, 0x6c, 0xe2, 0xa0, 0x2f, 0x59, 0x30, 0xd2, 0x24, 0x71, 0xe2, 0xfa, 0x8c, 0xbf, 0xec, - 0xfc, 0xea, 0x91, 0x3b, 0x2f, 0x1b, 0x67, 0x35, 0xf1, 0xfa, 0x19, 0xf1, 0x22, 0x23, 0x46, 0x63, - 0x8c, 0x53, 0xfc, 0xe9, 0xe2, 0x6c, 0x92, 0xb8, 0x11, 0xb9, 0x21, 0xfd, 0x2f, 0x96, 0x8f, 0x5a, - 0x9c, 0xb3, 0x1a, 0x84, 0x4d, 0x3c, 0xe4, 0x43, 0x85, 0x2e, 0xbe, 0x78, 0x7c, 0x80, 0xf5, 0x7f, - 0xfe, 0x68, 0xfd, 0x17, 0x83, 0x4a, 0xd7, 0xb5, 0x1e, 0x7d, 0xfa, 0x2f, 0xc6, 0x9c, 0x0d, 0xfa, - 0xa2, 0x05, 0xe3, 0x42, 0x38, 0x60, 0xc2, 0x07, 0xf4, 0xe6, 0x86, 0x9b, 0x10, 0xcf, 0x8d, 0x93, - 0xf1, 0x0a, 0xeb, 0xc3, 0x54, 0x7f, 0x73, 0x6b, 0x2e, 0x0a, 0x3a, 0xe1, 0x55, 0xd7, 0x6f, 0xd6, - 0xcf, 0x0b, 0x4e, 0xe3, 0x33, 0x3d, 0x08, 0xe3, 0x9e, 0x2c, 0xd1, 0x57, 0x2d, 0x38, 0xe7, 0x3b, - 0x6d, 0x12, 0x87, 0x0e, 0xfd, 0xb4, 0x1c, 0x5c, 0xf7, 0x9c, 0xc6, 0x26, 0xeb, 0xd1, 0xe0, 0xe1, - 0x7a, 0x64, 0x8b, 0x1e, 0x9d, 0xbb, 0xd6, 0x93, 0x34, 0xde, 0x83, 0x2d, 0xfa, 0xa6, 0x05, 0xa7, - 0x82, 0x28, 0xdc, 0x70, 0x7c, 0xd2, 0x94, 0xd0, 0x78, 0x7c, 0x88, 0x2d, 0xbd, 0x8f, 0x1c, 0xed, - 0x13, 0x2d, 0x65, 0xc9, 0x2e, 0x06, 0xbe, 0x9b, 0x04, 0xd1, 0x0a, 0x49, 0x12, 0xd7, 0x6f, 0xc5, - 0xf5, 0xb3, 0x77, 0x76, 0x27, 0x4e, 0x75, 0x61, 0xe1, 0xee, 0xfe, 0xa0, 0x9f, 0x82, 0xe1, 0x78, - 0xc7, 0x6f, 0xdc, 0x74, 0xfd, 0x66, 0x70, 0x3b, 0x1e, 0xaf, 0x16, 0xb1, 0x7c, 0x57, 0x14, 0x41, - 0xb1, 0x00, 0x35, 0x03, 0x6c, 0x72, 0xcb, 0xff, 0x70, 0x7a, 0x2a, 0xd5, 0x8a, 0xfe, 0x70, 0x7a, - 0x32, 0xed, 0xc1, 0x16, 0xfd, 0x9c, 0x05, 0xa3, 0xb1, 0xdb, 0xf2, 0x9d, 0xa4, 0x13, 0x91, 0xab, - 0x64, 0x27, 0x1e, 0x07, 0xd6, 0x91, 0x2b, 0x47, 0x1c, 0x15, 0x83, 0x64, 0xfd, 0xac, 0xe8, 0xe3, - 0xa8, 0xd9, 0x1a, 0xe3, 0x34, 0xdf, 0xbc, 0x85, 0xa6, 0xa7, 0xf5, 0x70, 0xb1, 0x0b, 0x4d, 0x4f, - 0xea, 0x9e, 0x2c, 0xd1, 0x4f, 0xc0, 0x49, 0xde, 0xa4, 0x46, 0x36, 0x1e, 0x1f, 0x61, 0x82, 0xf6, - 0xcc, 0x9d, 0xdd, 0x89, 0x93, 0x2b, 0x19, 0x18, 0xee, 0xc2, 0x46, 0xaf, 0xc1, 0x44, 0x48, 0xa2, - 0xb6, 0x9b, 0x2c, 0xf9, 0xde, 0x8e, 0x14, 0xdf, 0x8d, 0x20, 0x24, 0x4d, 0xd1, 0x9d, 0x78, 0x7c, - 0xf4, 0xbc, 0xf5, 0x54, 0xb5, 0xfe, 0x0e, 0xd1, 0xcd, 0x89, 0xe5, 0xbd, 0xd1, 0xf1, 0x7e, 0xf4, - 0xec, 0x7f, 0x59, 0x82, 0x93, 0x59, 0xc5, 0x89, 0xfe, 0xa6, 0x05, 0x27, 0x6e, 0xdd, 0x4e, 0x56, - 0x83, 0x4d, 0xe2, 0xc7, 0xf5, 0x1d, 0x2a, 0xde, 0x98, 0xca, 0x18, 0xbe, 0xd0, 0x28, 0x56, 0x45, - 0x4f, 0x5e, 0x49, 0x73, 0xb9, 0xe8, 0x27, 0xd1, 0x4e, 0xfd, 0x61, 0xf1, 0x76, 0x27, 0xae, 0xdc, - 0x5c, 0x35, 0xa1, 0x38, 0xdb, 0xa9, 0x73, 0x9f, 0xb7, 0xe0, 0x4c, 0x1e, 0x09, 0x74, 0x12, 0xca, - 0x9b, 0x64, 0x87, 0x1b, 0x70, 0x98, 0xfe, 0x44, 0xaf, 0x40, 0x65, 0xcb, 0xf1, 0x3a, 0x44, 0x58, - 0x37, 0x73, 0x47, 0x7b, 0x11, 0xd5, 0x33, 0xcc, 0xa9, 0xbe, 0xb7, 0xf4, 0x82, 0x65, 0xff, 0x6e, - 0x19, 0x86, 0x0d, 0xfd, 0x76, 0x0f, 0x2c, 0xb6, 0x20, 0x65, 0xb1, 0x2d, 0x16, 0xa6, 0x9a, 0x7b, - 0x9a, 0x6c, 0xb7, 0x33, 0x26, 0xdb, 0x52, 0x71, 0x2c, 0xf7, 0xb4, 0xd9, 0x50, 0x02, 0xb5, 0x20, - 0xa4, 0xd6, 0x3b, 0x55, 0xfd, 0x03, 0x45, 0x7c, 0xc2, 0x25, 0x49, 0xae, 0x3e, 0x7a, 0x67, 0x77, - 0xa2, 0xa6, 0xfe, 0x62, 0xcd, 0xc8, 0xfe, 0x8e, 0x05, 0x67, 0x8c, 0x3e, 0xce, 0x04, 0x7e, 0xd3, - 0x65, 0x9f, 0xf6, 0x3c, 0x0c, 0x24, 0x3b, 0xa1, 0xdc, 0x21, 0xa8, 0x91, 0x5a, 0xdd, 0x09, 0x09, - 0x66, 0x10, 0x6a, 0xe8, 0xb7, 0x49, 0x1c, 0x3b, 0x2d, 0x92, 0xdd, 0x13, 0x2c, 0xf2, 0x66, 0x2c, - 0xe1, 0x28, 0x02, 0xe4, 0x39, 0x71, 0xb2, 0x1a, 0x39, 0x7e, 0xcc, 0xc8, 0xaf, 0xba, 0x6d, 0x22, - 0x06, 0xf8, 0xff, 0xeb, 0x6f, 0xc6, 0xd0, 0x27, 0xea, 0x0f, 0xdd, 0xd9, 0x9d, 0x40, 0x0b, 0x5d, - 0x94, 0x70, 0x0e, 0x75, 0xfb, 0xab, 0x16, 0x3c, 0x94, 0x6f, 0x8b, 0xa1, 0x27, 0x61, 0x90, 0x6f, - 0x0f, 0xc5, 0xdb, 0xe9, 0x4f, 0xc2, 0x5a, 0xb1, 0x80, 0xa2, 0x29, 0xa8, 0x29, 0x3d, 0x21, 0xde, - 0xf1, 0x94, 0x40, 0xad, 0x69, 0xe5, 0xa2, 0x71, 0xe8, 0xa0, 0xd1, 0x3f, 0xc2, 0x72, 0x53, 0x83, - 0xc6, 0xf6, 0x53, 0x0c, 0x62, 0xff, 0x07, 0x0b, 0x4e, 0x18, 0xbd, 0xba, 0x07, 0xa6, 0xb9, 0x9f, - 0x36, 0xcd, 0xe7, 0x0b, 0x9b, 0xcf, 0x3d, 0x6c, 0xf3, 0x2f, 0x5a, 0x70, 0xce, 0xc0, 0x5a, 0x74, - 0x92, 0xc6, 0xc6, 0xc5, 0xed, 0x30, 0x22, 0x31, 0xdd, 0x7a, 0xa3, 0xc7, 0x0c, 0xb9, 0x55, 0x1f, - 0x16, 0x14, 0xca, 0x57, 0xc9, 0x0e, 0x17, 0x62, 0x4f, 0x43, 0x95, 0x4f, 0xce, 0x20, 0x12, 0x23, - 0xae, 0xde, 0x6d, 0x49, 0xb4, 0x63, 0x85, 0x81, 0x6c, 0x18, 0x64, 0xc2, 0x89, 0x2e, 0x56, 0xaa, - 0x86, 0x80, 0x7e, 0xc4, 0x1b, 0xac, 0x05, 0x0b, 0x88, 0x1d, 0xa7, 0xba, 0xb3, 0x1c, 0x11, 0xf6, - 0x71, 0x9b, 0x97, 0x5c, 0xe2, 0x35, 0x63, 0xba, 0x6d, 0x70, 0x7c, 0x3f, 0x48, 0xc4, 0x0e, 0xc0, - 0xd8, 0x36, 0x4c, 0xeb, 0x66, 0x6c, 0xe2, 0x50, 0xa6, 0x9e, 0xb3, 0x46, 0x3c, 0x3e, 0xa2, 0x82, - 0xe9, 0x02, 0x6b, 0xc1, 0x02, 0x62, 0xdf, 0x29, 0xb1, 0x0d, 0x8a, 0x5a, 0xfa, 0xe4, 0x5e, 0xec, - 0x6e, 0xa3, 0x94, 0xac, 0x5c, 0x2e, 0x4e, 0x70, 0x91, 0xde, 0x3b, 0xdc, 0xd7, 0x33, 0xe2, 0x12, - 0x17, 0xca, 0x75, 0xef, 0x5d, 0xee, 0x27, 0xcb, 0x30, 0x91, 0x7e, 0xa0, 0x4b, 0xda, 0xd2, 0x2d, - 0x95, 0xc1, 0x28, 0xeb, 0xef, 0x30, 0xf0, 0xb1, 0x89, 0xd7, 0x43, 0x60, 0x95, 0x8e, 0x53, 0x60, - 0x99, 0xf2, 0xb4, 0xbc, 0x8f, 0x3c, 0x7d, 0x52, 0x8d, 0xfa, 0x40, 0x46, 0x80, 0xa5, 0x75, 0xca, - 0x79, 0x18, 0x88, 0x13, 0x12, 0x8e, 0x57, 0xd2, 0xf2, 0x68, 0x25, 0x21, 0x21, 0x66, 0x10, 0xf4, - 0x3e, 0x38, 0x91, 0x38, 0x51, 0x8b, 0x24, 0x11, 0xd9, 0x72, 0x99, 0x6f, 0x8c, 0xed, 0x97, 0x6a, - 0xf5, 0xd3, 0xd4, 0x3c, 0x59, 0x65, 0x20, 0x2c, 0x41, 0x38, 0x8b, 0x6b, 0xff, 0xd7, 0x12, 0x3c, - 0x9c, 0xfe, 0x04, 0x5a, 0x83, 0x7c, 0x20, 0xa5, 0x41, 0xde, 0x65, 0x6a, 0x90, 0xbb, 0xbb, 0x13, - 0x6f, 0xef, 0xf1, 0xd8, 0xf7, 0x8d, 0x82, 0x41, 0x73, 0x99, 0x8f, 0x30, 0x95, 0xfe, 0x08, 0x77, - 0x77, 0x27, 0x1e, 0xeb, 0xf1, 0x8e, 0x99, 0xaf, 0xf4, 0x24, 0x0c, 0x46, 0xc4, 0x89, 0x03, 0x5f, - 0x7c, 0x27, 0xf5, 0x35, 0x31, 0x6b, 0xc5, 0x02, 0x6a, 0xff, 0x7e, 0x2d, 0x3b, 0xd8, 0x73, 0xdc, - 0xdf, 0x17, 0x44, 0xc8, 0x85, 0x01, 0xb6, 0x2b, 0xe0, 0x92, 0xe5, 0xea, 0xd1, 0x56, 0x21, 0xd5, - 0x22, 0x8a, 0x74, 0xbd, 0x4a, 0xbf, 0x1a, 0x6d, 0xc2, 0x8c, 0x05, 0xda, 0x86, 0x6a, 0x43, 0x1a, - 0xeb, 0xa5, 0x22, 0xdc, 0x5a, 0xc2, 0x54, 0xd7, 0x1c, 0x47, 0xa8, 0xb8, 0x57, 0x16, 0xbe, 0xe2, - 0x86, 0x08, 0x94, 0x5b, 0x6e, 0x22, 0x3e, 0xeb, 0x11, 0xb7, 0x63, 0x73, 0xae, 0xf1, 0x8a, 0x43, - 0x54, 0x07, 0xcd, 0xb9, 0x09, 0xa6, 0xf4, 0xd1, 0x67, 0x2d, 0x18, 0x8e, 0x1b, 0xed, 0xe5, 0x28, - 0xd8, 0x72, 0x9b, 0x24, 0x12, 0xc6, 0xd8, 0x11, 0x25, 0xdb, 0xca, 0xcc, 0xa2, 0x24, 0xa8, 0xf9, - 0xf2, 0xed, 0xb1, 0x86, 0x60, 0x93, 0x2f, 0xdd, 0xa4, 0x3c, 0x2c, 0xde, 0x7d, 0x96, 0x34, 0xd8, - 0x8a, 0x93, 0x7b, 0x32, 0x36, 0x53, 0x8e, 0x6c, 0x9c, 0xce, 0x76, 0x1a, 0x9b, 0x74, 0xbd, 0xe9, - 0x0e, 0xbd, 0xfd, 0xce, 0xee, 0xc4, 0xc3, 0x33, 0xf9, 0x3c, 0x71, 0xaf, 0xce, 0xb0, 0x01, 0x0b, - 0x3b, 0x9e, 0x87, 0xc9, 0x6b, 0x1d, 0xc2, 0x3c, 0x2e, 0x05, 0x0c, 0xd8, 0xb2, 0x26, 0x98, 0x19, - 0x30, 0x03, 0x82, 0x4d, 0xbe, 0xe8, 0x35, 0x18, 0x6c, 0x3b, 0x49, 0xe4, 0x6e, 0x0b, 0x37, 0xcb, - 0x11, 0xb7, 0x0b, 0x8b, 0x8c, 0x96, 0x66, 0xce, 0x14, 0x3d, 0x6f, 0xc4, 0x82, 0x11, 0x6a, 0x43, - 0xa5, 0x4d, 0xa2, 0x16, 0x19, 0xaf, 0x16, 0xe1, 0x52, 0x5e, 0xa4, 0xa4, 0x34, 0xc3, 0x1a, 0x35, - 0xae, 0x58, 0x1b, 0xe6, 0x5c, 0xd0, 0x2b, 0x50, 0x8d, 0x89, 0x47, 0x1a, 0xd4, 0x3c, 0xaa, 0x31, - 0x8e, 0xef, 0xee, 0xd3, 0x54, 0xa4, 0x76, 0xc9, 0x8a, 0x78, 0x94, 0x2f, 0x30, 0xf9, 0x0f, 0x2b, - 0x92, 0x74, 0x00, 0x43, 0xaf, 0xd3, 0x72, 0xfd, 0x71, 0x28, 0x62, 0x00, 0x97, 0x19, 0xad, 0xcc, - 0x00, 0xf2, 0x46, 0x2c, 0x18, 0xd9, 0xff, 0xc9, 0x02, 0x94, 0x16, 0x6a, 0xf7, 0xc0, 0x26, 0x7e, - 0x2d, 0x6d, 0x13, 0x2f, 0x14, 0x69, 0xb4, 0xf4, 0x30, 0x8b, 0x7f, 0xa3, 0x06, 0x19, 0x75, 0x70, - 0x8d, 0xc4, 0x09, 0x69, 0xbe, 0x25, 0xc2, 0xdf, 0x12, 0xe1, 0x6f, 0x89, 0x70, 0x25, 0xc2, 0xd7, - 0x32, 0x22, 0xfc, 0xfd, 0xc6, 0xaa, 0xd7, 0xe7, 0xb7, 0xaf, 0xaa, 0x03, 0x5e, 0xb3, 0x07, 0x06, - 0x02, 0x95, 0x04, 0x57, 0x56, 0x96, 0xae, 0xe5, 0xca, 0xec, 0x57, 0xd3, 0x32, 0xfb, 0xa8, 0x2c, - 0xfe, 0x5f, 0x90, 0xd2, 0xff, 0xc2, 0x82, 0x77, 0xa4, 0xa5, 0x97, 0x9c, 0x39, 0xf3, 0x2d, 0x3f, - 0x88, 0xc8, 0xac, 0xbb, 0xbe, 0x4e, 0x22, 0xe2, 0x37, 0x48, 0xac, 0x9c, 0x20, 0x56, 0x2f, 0x27, - 0x08, 0x7a, 0x0e, 0x46, 0x6e, 0xc5, 0x81, 0xbf, 0x1c, 0xb8, 0xbe, 0x10, 0x41, 0x74, 0xc7, 0x71, - 0xf2, 0xce, 0xee, 0xc4, 0x08, 0x1d, 0x51, 0xd9, 0x8e, 0x53, 0x58, 0x68, 0x06, 0x4e, 0xdd, 0x7a, - 0x6d, 0xd9, 0x49, 0x0c, 0x6f, 0x82, 0xdc, 0xf7, 0xb3, 0xf3, 0x8e, 0x2b, 0x2f, 0x65, 0x80, 0xb8, - 0x1b, 0xdf, 0xfe, 0x6b, 0x25, 0x78, 0x24, 0xf3, 0x22, 0x81, 0xe7, 0x05, 0x9d, 0x84, 0xee, 0x89, - 0xd0, 0xd7, 0x2d, 0x38, 0xd9, 0x4e, 0x3b, 0x2c, 0x62, 0xe1, 0x17, 0xfe, 0x60, 0x61, 0x3a, 0x22, - 0xe3, 0x11, 0xa9, 0x8f, 0x8b, 0x11, 0x3a, 0x99, 0x01, 0xc4, 0xb8, 0xab, 0x2f, 0xe8, 0x15, 0xa8, - 0xb5, 0x9d, 0xed, 0xeb, 0x61, 0xd3, 0x49, 0xe4, 0x76, 0xb4, 0xb7, 0x17, 0xa1, 0x93, 0xb8, 0xde, - 0x24, 0x8f, 0x0c, 0x98, 0x9c, 0xf7, 0x93, 0xa5, 0x68, 0x25, 0x89, 0x5c, 0xbf, 0xc5, 0xbd, 0x81, - 0x8b, 0x92, 0x0c, 0xd6, 0x14, 0xed, 0xaf, 0x59, 0x59, 0x25, 0xa5, 0x46, 0x27, 0x72, 0x12, 0xd2, - 0xda, 0x41, 0x1f, 0x83, 0x0a, 0xdd, 0x37, 0xca, 0x51, 0xb9, 0x59, 0xa4, 0xe6, 0x34, 0xbe, 0x84, - 0x56, 0xa2, 0xf4, 0x5f, 0x8c, 0x39, 0x53, 0xfb, 0xeb, 0xb5, 0xac, 0xb1, 0xc0, 0xce, 0x7e, 0x2f, - 0x00, 0xb4, 0x82, 0x55, 0xd2, 0x0e, 0x3d, 0x3a, 0x2c, 0x16, 0x3b, 0x40, 0x50, 0xae, 0x92, 0x39, - 0x05, 0xc1, 0x06, 0x16, 0xfa, 0x0b, 0x16, 0x40, 0x4b, 0xce, 0x79, 0x69, 0x08, 0x5c, 0x2f, 0xf2, - 0x75, 0xf4, 0x8a, 0xd2, 0x7d, 0x51, 0x0c, 0xb1, 0xc1, 0x1c, 0xfd, 0x8c, 0x05, 0xd5, 0x44, 0x76, - 0x9f, 0xab, 0xc6, 0xd5, 0x22, 0x7b, 0x22, 0x5f, 0x5a, 0xdb, 0x44, 0x6a, 0x48, 0x14, 0x5f, 0xf4, - 0xb3, 0x16, 0x40, 0xbc, 0xe3, 0x37, 0x96, 0x03, 0xcf, 0x6d, 0xec, 0x08, 0x8d, 0x79, 0xa3, 0x50, - 0x77, 0x8e, 0xa2, 0x5e, 0x1f, 0xa3, 0xa3, 0xa1, 0xff, 0x63, 0x83, 0x33, 0xfa, 0x04, 0x54, 0x63, - 0x31, 0xdd, 0x84, 0x8e, 0x5c, 0x2d, 0xd6, 0xa9, 0xc4, 0x69, 0x0b, 0xf1, 0x2a, 0xfe, 0x61, 0xc5, - 0x13, 0xfd, 0xbc, 0x05, 0x27, 0xc2, 0xb4, 0x9b, 0x50, 0xa8, 0xc3, 0xe2, 0x64, 0x40, 0xc6, 0x0d, - 0xc9, 0xbd, 0x2d, 0x99, 0x46, 0x9c, 0xed, 0x05, 0x95, 0x80, 0x7a, 0x06, 0x2f, 0x85, 0xdc, 0x65, - 0x39, 0xa4, 0x25, 0xe0, 0x5c, 0x16, 0x88, 0xbb, 0xf1, 0xd1, 0x32, 0x9c, 0xa1, 0xbd, 0xdb, 0xe1, - 0xe6, 0xa7, 0x54, 0x2f, 0x31, 0x53, 0x86, 0xd5, 0xfa, 0xa3, 0x62, 0x86, 0xb0, 0x43, 0x81, 0x2c, - 0x0e, 0xce, 0x7d, 0x12, 0xfd, 0xae, 0x05, 0x8f, 0xba, 0x4c, 0x0d, 0x98, 0xfe, 0x76, 0xad, 0x11, - 0xc4, 0x41, 0x2e, 0x29, 0x54, 0x56, 0xf4, 0x52, 0x3f, 0xf5, 0x1f, 0x16, 0x6f, 0xf0, 0xe8, 0xfc, - 0x1e, 0x5d, 0xc2, 0x7b, 0x76, 0x18, 0xfd, 0x18, 0x8c, 0xca, 0x75, 0xb1, 0x4c, 0x45, 0x30, 0x53, - 0xb4, 0xb5, 0xfa, 0xa9, 0x3b, 0xbb, 0x13, 0xa3, 0xab, 0x26, 0x00, 0xa7, 0xf1, 0xec, 0x7f, 0x55, - 0x4e, 0x1d, 0xa7, 0x28, 0x1f, 0x26, 0x13, 0x37, 0x0d, 0xe9, 0xff, 0x91, 0xd2, 0xb3, 0x50, 0x71, - 0xa3, 0xbc, 0x4b, 0x5a, 0xdc, 0xa8, 0xa6, 0x18, 0x1b, 0xcc, 0xa9, 0x51, 0x7a, 0xca, 0xc9, 0x7a, - 0x4a, 0x85, 0x04, 0x7c, 0xa5, 0xc8, 0x2e, 0x75, 0x1f, 0x7e, 0x3d, 0x22, 0xba, 0x76, 0xaa, 0x0b, - 0x84, 0xbb, 0xbb, 0x84, 0x3e, 0x0e, 0xb5, 0x48, 0x45, 0x4e, 0x94, 0x8b, 0xd8, 0xaa, 0xc9, 0x69, - 0x23, 0xba, 0xa3, 0x4e, 0x73, 0x74, 0x8c, 0x84, 0xe6, 0x68, 0xff, 0x4e, 0xfa, 0x04, 0xc9, 0x90, - 0x1d, 0x7d, 0x9c, 0x8e, 0x7d, 0xc9, 0x82, 0xe1, 0x28, 0xf0, 0x3c, 0xd7, 0x6f, 0x51, 0x39, 0x27, - 0x94, 0xf5, 0x87, 0x8f, 0x45, 0x5f, 0x0a, 0x81, 0xc6, 0x2c, 0x6b, 0xac, 0x79, 0x62, 0xb3, 0x03, - 0xf6, 0x9f, 0x58, 0x30, 0xde, 0x4b, 0x1e, 0x23, 0x02, 0x6f, 0x97, 0xc2, 0x46, 0x0d, 0xc5, 0x92, - 0x3f, 0x4b, 0x3c, 0xa2, 0xdc, 0xe6, 0xd5, 0xfa, 0x13, 0xe2, 0x35, 0xdf, 0xbe, 0xdc, 0x1b, 0x15, - 0xef, 0x45, 0x07, 0xbd, 0x0c, 0x27, 0x8d, 0xf7, 0x8a, 0xd5, 0xc0, 0xd4, 0xea, 0x93, 0xd4, 0x00, - 0x9a, 0xce, 0xc0, 0xee, 0xee, 0x4e, 0x3c, 0x94, 0x6d, 0x13, 0x0a, 0xa3, 0x8b, 0x8e, 0xfd, 0x2b, - 0xa5, 0xec, 0xd7, 0x52, 0xba, 0xfe, 0x4d, 0xab, 0xcb, 0x9b, 0xf0, 0xc1, 0xe3, 0xd0, 0xaf, 0xcc, - 0xef, 0xa0, 0xc2, 0x4f, 0x7a, 0xe3, 0xdc, 0xc7, 0xf3, 0x6d, 0xfb, 0x5f, 0x0f, 0xc0, 0x1e, 0x3d, - 0xeb, 0xc3, 0x78, 0x3f, 0xf0, 0xa1, 0xe8, 0x17, 0x2c, 0x75, 0x60, 0xc6, 0xd7, 0x70, 0xf3, 0xb8, - 0xc6, 0x9e, 0xef, 0x9f, 0x62, 0x1e, 0x63, 0xa1, 0xbc, 0xe8, 0xe9, 0xa3, 0x39, 0xf4, 0x0d, 0x2b, - 0x7d, 0xe4, 0xc7, 0x83, 0xe6, 0xdc, 0x63, 0xeb, 0x93, 0x71, 0x8e, 0xc8, 0x3b, 0xa6, 0x4f, 0x9f, - 0x7a, 0x9d, 0x30, 0x4e, 0x02, 0xac, 0xbb, 0xbe, 0xe3, 0xb9, 0xaf, 0xd3, 0xdd, 0x51, 0x85, 0x29, - 0x78, 0x66, 0x31, 0x5d, 0x52, 0xad, 0xd8, 0xc0, 0x38, 0xf7, 0xff, 0xc3, 0xb0, 0xf1, 0xe6, 0x39, - 0xa1, 0x21, 0x67, 0xcc, 0xd0, 0x90, 0x9a, 0x11, 0xd1, 0x71, 0xee, 0xfd, 0x70, 0x32, 0xdb, 0xc1, - 0x83, 0x3c, 0x6f, 0xff, 0xcf, 0xa1, 0xec, 0x19, 0xdc, 0x2a, 0x89, 0xda, 0xb4, 0x6b, 0x6f, 0x39, - 0xb6, 0xde, 0x72, 0x6c, 0xbd, 0xe5, 0xd8, 0x32, 0xcf, 0x26, 0x84, 0xd3, 0x66, 0xe8, 0x1e, 0x39, - 0x6d, 0x52, 0x6e, 0xa8, 0x6a, 0xe1, 0x6e, 0x28, 0xfb, 0xb3, 0x5d, 0x9e, 0xfb, 0xd5, 0x88, 0x10, - 0x14, 0x40, 0xc5, 0x0f, 0x9a, 0x44, 0xda, 0xb8, 0x57, 0x8a, 0x31, 0xd8, 0xae, 0x05, 0x4d, 0x23, - 0x1c, 0x99, 0xfe, 0x8b, 0x31, 0xe7, 0x63, 0xdf, 0xa9, 0x40, 0xca, 0x9c, 0xe4, 0xdf, 0xfd, 0x9d, - 0x30, 0x14, 0x91, 0x30, 0xb8, 0x8e, 0x17, 0x84, 0x2e, 0xd3, 0x19, 0x0b, 0xbc, 0x19, 0x4b, 0x38, - 0xd5, 0x79, 0xa1, 0x93, 0x6c, 0x08, 0x65, 0xa6, 0x74, 0xde, 0xb2, 0x93, 0x6c, 0x60, 0x06, 0x41, - 0xef, 0x87, 0xb1, 0x24, 0x75, 0x14, 0x2e, 0x8e, 0x7c, 0x1f, 0x12, 0xb8, 0x63, 0xe9, 0x83, 0x72, - 0x9c, 0xc1, 0x46, 0xaf, 0xc1, 0xc0, 0x06, 0xf1, 0xda, 0xe2, 0xd3, 0xaf, 0x14, 0xa7, 0x6b, 0xd8, - 0xbb, 0x5e, 0x26, 0x5e, 0x9b, 0x4b, 0x42, 0xfa, 0x0b, 0x33, 0x56, 0x74, 0xde, 0xd7, 0x36, 0x3b, - 0x71, 0x12, 0xb4, 0xdd, 0xd7, 0xa5, 0xa7, 0xf3, 0x83, 0x05, 0x33, 0xbe, 0x2a, 0xe9, 0x73, 0x97, - 0x92, 0xfa, 0x8b, 0x35, 0x67, 0xd6, 0x8f, 0xa6, 0x1b, 0xb1, 0x29, 0xb3, 0x23, 0x1c, 0x96, 0x45, - 0xf7, 0x63, 0x56, 0xd2, 0xe7, 0xfd, 0x50, 0x7f, 0xb1, 0xe6, 0x8c, 0x76, 0xd4, 0xfa, 0x1b, 0x66, - 0x7d, 0xb8, 0x5e, 0x70, 0x1f, 0xf8, 0xda, 0xcb, 0x5d, 0x87, 0x4f, 0x40, 0xa5, 0xb1, 0xe1, 0x44, - 0xc9, 0xf8, 0x08, 0x9b, 0x34, 0x6a, 0x16, 0xcf, 0xd0, 0x46, 0xcc, 0x61, 0xe8, 0x31, 0x28, 0x47, - 0x64, 0x9d, 0x45, 0xbf, 0x1a, 0x71, 0x51, 0x98, 0xac, 0x63, 0xda, 0x6e, 0xff, 0x52, 0x29, 0x6d, - 0xb6, 0xa5, 0xdf, 0x9b, 0xcf, 0xf6, 0x46, 0x27, 0x8a, 0xa5, 0xfb, 0xcb, 0x98, 0xed, 0xac, 0x19, - 0x4b, 0x38, 0xfa, 0x94, 0x05, 0x43, 0xb7, 0xe2, 0xc0, 0xf7, 0x49, 0x22, 0x54, 0xe4, 0x8d, 0x82, - 0x87, 0xe2, 0x0a, 0xa7, 0xae, 0xfb, 0x20, 0x1a, 0xb0, 0xe4, 0x4b, 0xbb, 0x4b, 0xb6, 0x1b, 0x5e, - 0xa7, 0xd9, 0x15, 0xea, 0x72, 0x91, 0x37, 0x63, 0x09, 0xa7, 0xa8, 0xae, 0xcf, 0x51, 0x07, 0xd2, - 0xa8, 0xf3, 0xbe, 0x40, 0x15, 0x70, 0xfb, 0xaf, 0x0c, 0xc2, 0xd9, 0xdc, 0xc5, 0x41, 0x0d, 0x2a, - 0x66, 0xb2, 0x5c, 0x72, 0x3d, 0x22, 0x83, 0xbc, 0x98, 0x41, 0x75, 0x43, 0xb5, 0x62, 0x03, 0x03, - 0xfd, 0x34, 0x40, 0xe8, 0x44, 0x4e, 0x9b, 0x28, 0xf7, 0xf4, 0x91, 0xed, 0x16, 0xda, 0x8f, 0x65, - 0x49, 0x53, 0x6f, 0xd1, 0x55, 0x53, 0x8c, 0x0d, 0x96, 0xe8, 0x79, 0x18, 0x8e, 0x88, 0x47, 0x9c, - 0x98, 0x05, 0x4f, 0x67, 0x33, 0x41, 0xb0, 0x06, 0x61, 0x13, 0x0f, 0x3d, 0xa9, 0xe2, 0xe1, 0x32, - 0x71, 0x41, 0xe9, 0x98, 0x38, 0xf4, 0x86, 0x05, 0x63, 0xeb, 0xae, 0x47, 0x34, 0x77, 0x91, 0xb7, - 0xb1, 0x74, 0xf4, 0x97, 0xbc, 0x64, 0xd2, 0xd5, 0x12, 0x32, 0xd5, 0x1c, 0xe3, 0x0c, 0x7b, 0xfa, - 0x99, 0xb7, 0x48, 0xc4, 0x44, 0xeb, 0x60, 0xfa, 0x33, 0xdf, 0xe0, 0xcd, 0x58, 0xc2, 0xd1, 0x34, - 0x9c, 0x08, 0x9d, 0x38, 0x9e, 0x89, 0x48, 0x93, 0xf8, 0x89, 0xeb, 0x78, 0x3c, 0xab, 0xa2, 0xaa, - 0xa3, 0xaa, 0x97, 0xd3, 0x60, 0x9c, 0xc5, 0x47, 0x1f, 0x82, 0x87, 0xb9, 0xff, 0x67, 0xd1, 0x8d, - 0x63, 0xd7, 0x6f, 0xe9, 0x69, 0x20, 0xdc, 0x60, 0x13, 0x82, 0xd4, 0xc3, 0xf3, 0xf9, 0x68, 0xb8, - 0xd7, 0xf3, 0xe8, 0x69, 0xa8, 0xc6, 0x9b, 0x6e, 0x38, 0x13, 0x35, 0x63, 0x76, 0xf6, 0x53, 0xd5, - 0x4e, 0xd7, 0x15, 0xd1, 0x8e, 0x15, 0x06, 0x6a, 0xc0, 0x08, 0xff, 0x24, 0x3c, 0xa0, 0x4f, 0xc8, - 0xc7, 0x67, 0x7a, 0xaa, 0x69, 0x91, 0x24, 0x38, 0x89, 0x9d, 0xdb, 0x17, 0xe5, 0x49, 0x14, 0x3f, - 0x38, 0xb9, 0x61, 0x90, 0xc1, 0x29, 0xa2, 0xf6, 0x2f, 0x94, 0xd2, 0x3b, 0x7f, 0x73, 0x91, 0xa2, - 0x98, 0x2e, 0xc5, 0xe4, 0x86, 0x13, 0x49, 0x85, 0x7d, 0xc4, 0xe4, 0x0f, 0x41, 0xf7, 0x86, 0x13, - 0x99, 0x8b, 0x9a, 0x31, 0xc0, 0x92, 0x13, 0xba, 0x05, 0x03, 0x89, 0xe7, 0x14, 0x94, 0x2d, 0x66, - 0x70, 0xd4, 0x8e, 0x98, 0x85, 0xe9, 0x18, 0x33, 0x1e, 0xe8, 0x51, 0xba, 0xfb, 0x58, 0x93, 0x27, - 0x45, 0x62, 0xc3, 0xb0, 0x16, 0x63, 0xd6, 0x6a, 0xdf, 0x85, 0x1c, 0xb9, 0xaa, 0x14, 0x19, 0xba, - 0x00, 0x40, 0x37, 0xb2, 0xcb, 0x11, 0x59, 0x77, 0xb7, 0x85, 0x21, 0xa1, 0xd6, 0xee, 0x35, 0x05, - 0xc1, 0x06, 0x96, 0x7c, 0x66, 0xa5, 0xb3, 0x4e, 0x9f, 0x29, 0x75, 0x3f, 0xc3, 0x21, 0xd8, 0xc0, - 0x42, 0xcf, 0xc1, 0xa0, 0xdb, 0x76, 0x5a, 0x2a, 0x90, 0xf5, 0x51, 0xba, 0x68, 0xe7, 0x59, 0xcb, - 0xdd, 0xdd, 0x89, 0x31, 0xd5, 0x21, 0xd6, 0x84, 0x05, 0x2e, 0xfa, 0x15, 0x0b, 0x46, 0x1a, 0x41, - 0xbb, 0x1d, 0xf8, 0x7c, 0xfb, 0x27, 0xf6, 0xb2, 0xb7, 0x8e, 0x4b, 0xcd, 0x4f, 0xce, 0x18, 0xcc, - 0xf8, 0x66, 0x56, 0xa5, 0xb5, 0x99, 0x20, 0x9c, 0xea, 0x95, 0xb9, 0xb6, 0x2b, 0xfb, 0xac, 0xed, - 0x5f, 0xb7, 0xe0, 0x14, 0x7f, 0xd6, 0xd8, 0x95, 0x8a, 0x0c, 0xae, 0xe0, 0x98, 0x5f, 0xab, 0x6b, - 0xa3, 0xae, 0x9c, 0x95, 0x5d, 0x70, 0xdc, 0xdd, 0x49, 0x34, 0x07, 0xa7, 0xd6, 0x83, 0xa8, 0x41, - 0xcc, 0x81, 0x10, 0x82, 0x49, 0x11, 0xba, 0x94, 0x45, 0xc0, 0xdd, 0xcf, 0xa0, 0x1b, 0xf0, 0x90, - 0xd1, 0x68, 0x8e, 0x03, 0x97, 0x4d, 0x8f, 0x0b, 0x6a, 0x0f, 0x5d, 0xca, 0xc5, 0xc2, 0x3d, 0x9e, - 0x4e, 0x3b, 0x6e, 0x6a, 0x7d, 0x38, 0x6e, 0x5e, 0x85, 0x47, 0x1a, 0xdd, 0x23, 0xb3, 0x15, 0x77, - 0xd6, 0x62, 0x2e, 0xa9, 0xaa, 0xf5, 0x1f, 0x12, 0x04, 0x1e, 0x99, 0xe9, 0x85, 0x88, 0x7b, 0xd3, - 0x40, 0x1f, 0x83, 0x6a, 0x44, 0xd8, 0x57, 0x89, 0x45, 0x3a, 0xd3, 0x11, 0x77, 0xeb, 0xda, 0x02, - 0xe5, 0x64, 0xb5, 0xec, 0x15, 0x0d, 0x31, 0x56, 0x1c, 0xd1, 0x6d, 0x18, 0x0a, 0x9d, 0xa4, 0xb1, - 0x21, 0x92, 0x98, 0x8e, 0xec, 0x5b, 0x56, 0xcc, 0xd9, 0x51, 0x80, 0x91, 0xf6, 0xcc, 0x99, 0x60, - 0xc9, 0x8d, 0x5a, 0x23, 0x8d, 0xa0, 0x1d, 0x06, 0x3e, 0xf1, 0x93, 0x78, 0x7c, 0x54, 0x5b, 0x23, - 0x33, 0xaa, 0x15, 0x1b, 0x18, 0x68, 0x19, 0xce, 0x30, 0xdf, 0xd5, 0x4d, 0x37, 0xd9, 0x08, 0x3a, - 0x89, 0xdc, 0x8a, 0x8d, 0x8f, 0xa5, 0x4f, 0x6c, 0x16, 0x72, 0x70, 0x70, 0xee, 0x93, 0xe7, 0x3e, - 0x00, 0xa7, 0xba, 0x96, 0xf2, 0x81, 0xdc, 0x46, 0xb3, 0xf0, 0x50, 0xfe, 0xa2, 0x39, 0x90, 0xf3, - 0xe8, 0x1f, 0x64, 0xa2, 0x87, 0x0d, 0x43, 0xba, 0x0f, 0x47, 0xa4, 0x03, 0x65, 0xe2, 0x6f, 0x09, - 0x1d, 0x72, 0xe9, 0x68, 0xdf, 0xee, 0xa2, 0xbf, 0xc5, 0xd7, 0x3c, 0xf3, 0xb6, 0x5c, 0xf4, 0xb7, - 0x30, 0xa5, 0x8d, 0xbe, 0x62, 0xa5, 0x0c, 0x41, 0xee, 0xbe, 0xfc, 0xc8, 0xb1, 0xec, 0x1c, 0xfa, - 0xb6, 0x0d, 0xed, 0x7f, 0x53, 0x82, 0xf3, 0xfb, 0x11, 0xe9, 0x63, 0xf8, 0x9e, 0x80, 0xc1, 0x98, - 0xc5, 0x03, 0x08, 0xa1, 0x3c, 0x4c, 0xe7, 0x2a, 0x8f, 0x10, 0x78, 0x15, 0x0b, 0x10, 0xf2, 0xa0, - 0xdc, 0x76, 0x42, 0xe1, 0xd5, 0x9a, 0x3f, 0x6a, 0x3a, 0x12, 0xfd, 0xef, 0x78, 0x8b, 0x4e, 0xc8, - 0x7d, 0x25, 0x46, 0x03, 0xa6, 0x6c, 0x50, 0x02, 0x15, 0x27, 0x8a, 0x1c, 0x79, 0xf8, 0x7c, 0xb5, - 0x18, 0x7e, 0xd3, 0x94, 0x24, 0x3f, 0xbb, 0x4b, 0x35, 0x61, 0xce, 0xcc, 0xfe, 0xc2, 0x50, 0x2a, - 0x25, 0x87, 0x45, 0x14, 0xc4, 0x30, 0x28, 0x9c, 0x59, 0x56, 0xd1, 0x59, 0x60, 0x3c, 0xa7, 0x92, - 0xed, 0x13, 0x45, 0x66, 0xba, 0x60, 0x85, 0x3e, 0x6f, 0xb1, 0xfc, 0x6f, 0x99, 0xa6, 0x24, 0x76, - 0x67, 0xc7, 0x93, 0x8e, 0x6e, 0x66, 0x95, 0xcb, 0x46, 0x6c, 0x72, 0x17, 0x75, 0x1c, 0x98, 0x55, - 0xda, 0x5d, 0xc7, 0x81, 0x59, 0x99, 0x12, 0x8e, 0xb6, 0x73, 0x22, 0x07, 0x0a, 0xc8, 0x21, 0xee, - 0x23, 0x56, 0xe0, 0x1b, 0x16, 0x9c, 0x72, 0xb3, 0x47, 0xc0, 0x62, 0x2f, 0x73, 0xb3, 0x18, 0xcf, - 0x53, 0xf7, 0x09, 0xb3, 0x52, 0xe7, 0x5d, 0x20, 0xdc, 0xdd, 0x19, 0xd4, 0x84, 0x01, 0xd7, 0x5f, - 0x0f, 0x84, 0x11, 0x53, 0x3f, 0x5a, 0xa7, 0xe6, 0xfd, 0xf5, 0x40, 0xaf, 0x66, 0xfa, 0x0f, 0x33, - 0xea, 0x68, 0x01, 0xce, 0xc8, 0xac, 0x8c, 0xcb, 0x6e, 0x9c, 0x04, 0xd1, 0xce, 0x82, 0xdb, 0x76, - 0x13, 0x66, 0x80, 0x94, 0xeb, 0xe3, 0x54, 0x3f, 0xe0, 0x1c, 0x38, 0xce, 0x7d, 0x0a, 0xbd, 0x0e, - 0x43, 0xf2, 0xd8, 0xb5, 0x5a, 0xc4, 0xbe, 0xb0, 0x7b, 0xfe, 0xab, 0xc9, 0xb4, 0x22, 0xce, 0x5d, - 0x25, 0x43, 0xfb, 0x8d, 0x61, 0xe8, 0x3e, 0x1d, 0x4e, 0x1f, 0x05, 0x5b, 0xf7, 0xfa, 0x28, 0x98, - 0x6e, 0x58, 0x62, 0x7d, 0x8a, 0x5b, 0xc0, 0xdc, 0x16, 0x5c, 0xf5, 0x09, 0xdd, 0x8e, 0xdf, 0xc0, - 0x8c, 0x07, 0x8a, 0x60, 0x70, 0x83, 0x38, 0x5e, 0xb2, 0x51, 0xcc, 0x61, 0xc2, 0x65, 0x46, 0x2b, - 0x9b, 0x4a, 0xc5, 0x5b, 0xb1, 0xe0, 0x84, 0xb6, 0x61, 0x68, 0x83, 0x4f, 0x00, 0xb1, 0x87, 0x58, - 0x3c, 0xea, 0xe0, 0xa6, 0x66, 0x95, 0xfe, 0xdc, 0xa2, 0x01, 0x4b, 0x76, 0x2c, 0xec, 0xc8, 0x08, - 0x8c, 0xe0, 0x4b, 0xb7, 0xb8, 0x2c, 0xb2, 0xfe, 0xa3, 0x22, 0x3e, 0x0a, 0x23, 0x11, 0x69, 0x04, - 0x7e, 0xc3, 0xf5, 0x48, 0x73, 0x5a, 0x1e, 0x14, 0x1c, 0x24, 0x79, 0x88, 0xed, 0xc3, 0xb1, 0x41, - 0x03, 0xa7, 0x28, 0xa2, 0xcf, 0x59, 0x30, 0xa6, 0x32, 0x6f, 0xe9, 0x07, 0x21, 0xc2, 0x21, 0xbc, - 0x50, 0x50, 0x9e, 0x2f, 0xa3, 0x59, 0x47, 0x77, 0x76, 0x27, 0xc6, 0xd2, 0x6d, 0x38, 0xc3, 0x17, - 0xbd, 0x0c, 0x10, 0xac, 0xf1, 0xd8, 0xa2, 0xe9, 0x44, 0x78, 0x87, 0x0f, 0xf2, 0xaa, 0x63, 0x3c, - 0x09, 0x51, 0x52, 0xc0, 0x06, 0x35, 0x74, 0x15, 0x80, 0x2f, 0x9b, 0xd5, 0x9d, 0x50, 0x6e, 0x34, - 0x64, 0xf6, 0x17, 0xac, 0x28, 0xc8, 0xdd, 0xdd, 0x89, 0x6e, 0x6f, 0x1d, 0x0b, 0xa0, 0x30, 0x1e, - 0x47, 0x3f, 0x05, 0x43, 0x71, 0xa7, 0xdd, 0x76, 0x94, 0xef, 0xb8, 0xc0, 0xb4, 0x46, 0x4e, 0xd7, - 0x10, 0x45, 0xbc, 0x01, 0x4b, 0x8e, 0xe8, 0x16, 0x15, 0xaa, 0xb1, 0x70, 0x23, 0xb2, 0x55, 0xc4, - 0x6d, 0x82, 0x61, 0xf6, 0x4e, 0xef, 0x91, 0x86, 0x37, 0xce, 0xc1, 0xb9, 0xbb, 0x3b, 0xf1, 0x50, - 0xba, 0x7d, 0x21, 0x10, 0x89, 0x86, 0xb9, 0x34, 0xd1, 0x15, 0x59, 0xbf, 0x86, 0xbe, 0xb6, 0x2c, - 0xab, 0xf0, 0x94, 0xae, 0x5f, 0xc3, 0x9a, 0x7b, 0x8f, 0x99, 0xf9, 0x30, 0x5a, 0x84, 0xd3, 0x8d, - 0xc0, 0x4f, 0xa2, 0xc0, 0xf3, 0x78, 0xfd, 0x26, 0xbe, 0xe7, 0xe3, 0xbe, 0xe5, 0xb7, 0x8b, 0x6e, - 0x9f, 0x9e, 0xe9, 0x46, 0xc1, 0x79, 0xcf, 0xd9, 0x7e, 0xfa, 0x9c, 0x47, 0x0c, 0xce, 0x73, 0x30, - 0x42, 0xb6, 0x13, 0x12, 0xf9, 0x8e, 0x77, 0x1d, 0x2f, 0x48, 0xaf, 0x2a, 0x5b, 0x03, 0x17, 0x8d, - 0x76, 0x9c, 0xc2, 0x42, 0xb6, 0x72, 0x74, 0x18, 0xc9, 0xb3, 0xdc, 0xd1, 0x21, 0xdd, 0x1a, 0xf6, - 0xff, 0x2a, 0xa5, 0x0c, 0xb2, 0xfb, 0x72, 0xaa, 0xc4, 0xaa, 0x80, 0xc8, 0x72, 0x29, 0x0c, 0x20, - 0x36, 0x1a, 0x45, 0x72, 0x56, 0x55, 0x40, 0x96, 0x4c, 0x46, 0x38, 0xcd, 0x17, 0x6d, 0x42, 0x65, - 0x23, 0x88, 0x13, 0xb9, 0xfd, 0x38, 0xe2, 0x4e, 0xe7, 0x72, 0x10, 0x27, 0xcc, 0x8a, 0x50, 0xaf, - 0x4d, 0x5b, 0x62, 0xcc, 0x79, 0xd8, 0xff, 0xd9, 0x4a, 0xf9, 0xd0, 0x6f, 0xb2, 0x00, 0xe4, 0x2d, - 0xe2, 0xd3, 0x65, 0x6d, 0x86, 0x3c, 0xfd, 0x58, 0x26, 0x9d, 0xf3, 0x1d, 0xbd, 0xca, 0x93, 0xdd, - 0xa6, 0x14, 0x26, 0x19, 0x09, 0x23, 0x3a, 0xea, 0x93, 0x56, 0x3a, 0x2f, 0xb7, 0x54, 0xc4, 0x06, - 0xc3, 0xcc, 0x4d, 0xdf, 0x37, 0xc5, 0xd7, 0xfe, 0x8a, 0x05, 0x43, 0x75, 0xa7, 0xb1, 0x19, 0xac, - 0xaf, 0xa3, 0xa7, 0xa1, 0xda, 0xec, 0x44, 0x66, 0x8a, 0xb0, 0x72, 0x1c, 0xcc, 0x8a, 0x76, 0xac, - 0x30, 0xe8, 0x1c, 0x5e, 0x77, 0x1a, 0x32, 0x43, 0xbd, 0xcc, 0xe7, 0xf0, 0x25, 0xd6, 0x82, 0x05, - 0x04, 0x3d, 0x0f, 0xc3, 0x6d, 0x67, 0x5b, 0x3e, 0x9c, 0x75, 0xe0, 0x2f, 0x6a, 0x10, 0x36, 0xf1, - 0xec, 0x7f, 0x6e, 0xc1, 0x78, 0xdd, 0x89, 0xdd, 0xc6, 0x74, 0x27, 0xd9, 0xa8, 0xbb, 0xc9, 0x5a, - 0xa7, 0xb1, 0x49, 0x12, 0x5e, 0x96, 0x80, 0xf6, 0xb2, 0x13, 0xd3, 0xa5, 0xa4, 0xf6, 0x75, 0xaa, - 0x97, 0xd7, 0x45, 0x3b, 0x56, 0x18, 0xe8, 0x75, 0x18, 0x0e, 0x9d, 0x38, 0xbe, 0x1d, 0x44, 0x4d, - 0x4c, 0xd6, 0x8b, 0x29, 0x0a, 0xb2, 0x42, 0x1a, 0x11, 0x49, 0x30, 0x59, 0x17, 0x87, 0xdd, 0x9a, - 0x3e, 0x36, 0x99, 0xd9, 0x5f, 0xb2, 0xe0, 0x91, 0x3a, 0x71, 0x22, 0x12, 0xb1, 0x1a, 0x22, 0xea, - 0x45, 0x66, 0xbc, 0xa0, 0xd3, 0x44, 0xaf, 0x41, 0x35, 0xa1, 0xcd, 0xb4, 0x5b, 0x56, 0xb1, 0xdd, - 0x62, 0x67, 0xd5, 0xab, 0x82, 0x38, 0x56, 0x6c, 0xec, 0xbf, 0x6a, 0xc1, 0x08, 0x3b, 0x6e, 0x9b, - 0x25, 0x89, 0xe3, 0x7a, 0x5d, 0xa5, 0xb6, 0xac, 0x3e, 0x4b, 0x6d, 0x9d, 0x87, 0x81, 0x8d, 0xa0, - 0x4d, 0xb2, 0x47, 0xc5, 0x97, 0x03, 0xba, 0xad, 0xa6, 0x10, 0xf4, 0x2c, 0xfd, 0xf0, 0xae, 0x9f, - 0x38, 0x74, 0x09, 0x48, 0x77, 0xee, 0x09, 0xfe, 0xd1, 0x55, 0x33, 0x36, 0x71, 0xec, 0x7f, 0x56, - 0x83, 0x21, 0x11, 0xd7, 0xd0, 0x77, 0x69, 0x0a, 0xb9, 0xbf, 0x2f, 0xf5, 0xdc, 0xdf, 0xc7, 0x30, - 0xd8, 0x60, 0x35, 0xff, 0x84, 0x19, 0x79, 0xb5, 0x90, 0x40, 0x18, 0x5e, 0x46, 0x50, 0x77, 0x8b, - 0xff, 0xc7, 0x82, 0x15, 0xfa, 0xb2, 0x05, 0x27, 0x1a, 0x81, 0xef, 0x93, 0x86, 0xb6, 0x71, 0x06, - 0x8a, 0x88, 0x77, 0x98, 0x49, 0x13, 0xd5, 0x67, 0x3d, 0x19, 0x00, 0xce, 0xb2, 0x47, 0x2f, 0xc2, - 0x28, 0x1f, 0xb3, 0x1b, 0x29, 0x1f, 0xb4, 0xae, 0xc0, 0x64, 0x02, 0x71, 0x1a, 0x17, 0x4d, 0x72, - 0x5f, 0xbe, 0xa8, 0x75, 0x34, 0xa8, 0x5d, 0x75, 0x46, 0x95, 0x23, 0x03, 0x03, 0x45, 0x80, 0x22, - 0xb2, 0x1e, 0x91, 0x78, 0x43, 0xc4, 0x7d, 0x30, 0xfb, 0x6a, 0xe8, 0x70, 0x79, 0xe8, 0xb8, 0x8b, - 0x12, 0xce, 0xa1, 0x8e, 0x36, 0xc5, 0x06, 0xb3, 0x5a, 0x84, 0x0c, 0x15, 0x9f, 0xb9, 0xe7, 0x3e, - 0x73, 0x02, 0x2a, 0xf1, 0x86, 0x13, 0x35, 0x99, 0x5d, 0x57, 0xe6, 0xb9, 0x4f, 0x2b, 0xb4, 0x01, - 0xf3, 0x76, 0x34, 0x0b, 0x27, 0x33, 0xf5, 0xa3, 0x62, 0xe1, 0x2b, 0x56, 0x79, 0x2e, 0x99, 0xca, - 0x53, 0x31, 0xee, 0x7a, 0xc2, 0x74, 0x3e, 0x0c, 0xef, 0xe3, 0x7c, 0xd8, 0x51, 0xd1, 0x85, 0xdc, - 0x8b, 0xfb, 0x52, 0x21, 0x03, 0xd0, 0x57, 0x28, 0xe1, 0x17, 0x33, 0xa1, 0x84, 0xa3, 0xac, 0x03, - 0x37, 0x8a, 0xe9, 0xc0, 0xc1, 0xe3, 0x06, 0xef, 0x67, 0x1c, 0xe0, 0x9f, 0x5b, 0x20, 0xbf, 0xeb, - 0x8c, 0xd3, 0xd8, 0x20, 0x74, 0xca, 0xa0, 0xf7, 0xc3, 0x98, 0xda, 0x42, 0xcf, 0x04, 0x1d, 0x9f, - 0x87, 0x00, 0x96, 0xf5, 0xa1, 0x30, 0x4e, 0x41, 0x71, 0x06, 0x1b, 0x4d, 0x41, 0x8d, 0x8e, 0x13, - 0x7f, 0x94, 0xeb, 0x5a, 0xb5, 0x4d, 0x9f, 0x5e, 0x9e, 0x17, 0x4f, 0x69, 0x1c, 0x14, 0xc0, 0x29, - 0xcf, 0x89, 0x13, 0xd6, 0x03, 0xba, 0xa3, 0x3e, 0x64, 0x15, 0x08, 0x96, 0x4c, 0xb1, 0x90, 0x25, - 0x84, 0xbb, 0x69, 0xdb, 0xdf, 0x19, 0x80, 0xd1, 0x94, 0x64, 0x3c, 0xa0, 0x92, 0x7e, 0x1a, 0xaa, - 0x52, 0x6f, 0x66, 0xcb, 0xdd, 0x28, 0xe5, 0xaa, 0x30, 0xa8, 0xd2, 0x5a, 0xd3, 0x5a, 0x35, 0x6b, - 0x54, 0x18, 0x0a, 0x17, 0x9b, 0x78, 0x4c, 0x28, 0x27, 0x5e, 0x3c, 0xe3, 0xb9, 0xc4, 0x4f, 0x78, - 0x37, 0x8b, 0x11, 0xca, 0xab, 0x0b, 0x2b, 0x26, 0x51, 0x2d, 0x94, 0x33, 0x00, 0x9c, 0x65, 0x8f, - 0x3e, 0x63, 0xc1, 0xa8, 0x73, 0x3b, 0xd6, 0x85, 0x69, 0x45, 0xd0, 0xe0, 0x11, 0x95, 0x54, 0xaa, - 0xd6, 0x2d, 0x77, 0xf9, 0xa6, 0x9a, 0x70, 0x9a, 0x29, 0x7a, 0xd3, 0x02, 0x44, 0xb6, 0x49, 0x43, - 0x86, 0x35, 0x8a, 0xbe, 0x0c, 0x16, 0xb1, 0xd3, 0xbc, 0xd8, 0x45, 0x97, 0x4b, 0xf5, 0xee, 0x76, - 0x9c, 0xd3, 0x07, 0xfb, 0x1f, 0x97, 0xd5, 0x82, 0xd2, 0x91, 0xb4, 0x8e, 0x11, 0xd1, 0x67, 0x1d, - 0x3e, 0xa2, 0x4f, 0x47, 0x24, 0x74, 0x27, 0x97, 0xa6, 0x72, 0xd1, 0x4a, 0xf7, 0x29, 0x17, 0xed, - 0x67, 0xac, 0x54, 0x61, 0xa7, 0xe1, 0x0b, 0x2f, 0x17, 0x1b, 0xc5, 0x3b, 0xc9, 0xa3, 0x25, 0x32, - 0xd2, 0x3d, 0x1d, 0x24, 0x43, 0xa5, 0xa9, 0x81, 0x76, 0x20, 0x69, 0xf8, 0xef, 0xca, 0x30, 0x6c, - 0x68, 0xd2, 0x5c, 0xb3, 0xc8, 0x7a, 0xc0, 0xcc, 0xa2, 0xd2, 0x01, 0xcc, 0xa2, 0x9f, 0x86, 0x5a, - 0x43, 0x4a, 0xf9, 0x62, 0x4a, 0x1b, 0x67, 0x75, 0x87, 0x16, 0xf4, 0xaa, 0x09, 0x6b, 0x9e, 0x68, - 0x2e, 0x95, 0xc1, 0x24, 0x34, 0xc4, 0x00, 0xd3, 0x10, 0x79, 0x29, 0x46, 0x42, 0x53, 0x74, 0x3f, - 0xc3, 0xea, 0x7f, 0x85, 0xae, 0x78, 0x2f, 0x19, 0x6b, 0xcf, 0xeb, 0x7f, 0x2d, 0xcf, 0xcb, 0x66, - 0x6c, 0xe2, 0xd8, 0xdf, 0xb1, 0xd4, 0xc7, 0xbd, 0x07, 0xa5, 0x2a, 0x6e, 0xa5, 0x4b, 0x55, 0x5c, - 0x2c, 0x64, 0x98, 0x7b, 0xd4, 0xa8, 0xb8, 0x06, 0x43, 0x33, 0x41, 0xbb, 0xed, 0xf8, 0x4d, 0xf4, - 0x23, 0x30, 0xd4, 0xe0, 0x3f, 0x85, 0x63, 0x87, 0x1d, 0x0f, 0x0a, 0x28, 0x96, 0x30, 0xf4, 0x28, - 0x0c, 0x38, 0x51, 0x4b, 0x3a, 0x73, 0x58, 0x70, 0xcd, 0x74, 0xd4, 0x8a, 0x31, 0x6b, 0xb5, 0xff, - 0xfe, 0x00, 0xb0, 0x33, 0x6d, 0x27, 0x22, 0xcd, 0xd5, 0x80, 0x95, 0x56, 0x3c, 0xd6, 0x43, 0x35, - 0xbd, 0x59, 0x7a, 0x90, 0x0f, 0xd6, 0x8c, 0xc3, 0x95, 0xf2, 0x3d, 0x3e, 0x5c, 0xe9, 0x71, 0x5e, - 0x36, 0xf0, 0x00, 0x9d, 0x97, 0xd9, 0x5f, 0xb0, 0x00, 0xa9, 0x40, 0x08, 0x7d, 0xa0, 0x3d, 0x05, - 0x35, 0x15, 0x12, 0x21, 0x0c, 0x2b, 0x2d, 0x22, 0x24, 0x00, 0x6b, 0x9c, 0x3e, 0x76, 0xc8, 0x4f, - 0x48, 0xf9, 0x5d, 0x4e, 0xc7, 0xe5, 0x32, 0xa9, 0x2f, 0xc4, 0xb9, 0xfd, 0x5b, 0x25, 0x78, 0x88, - 0xab, 0xe4, 0x45, 0xc7, 0x77, 0x5a, 0xa4, 0x4d, 0x7b, 0xd5, 0x6f, 0x88, 0x42, 0x83, 0x6e, 0xcd, - 0x5c, 0x19, 0x67, 0x7b, 0xd4, 0xb5, 0xcb, 0xd7, 0x1c, 0x5f, 0x65, 0xf3, 0xbe, 0x9b, 0x60, 0x46, - 0x1c, 0xc5, 0x50, 0x95, 0x75, 0xff, 0x85, 0x2c, 0x2e, 0x88, 0x91, 0x12, 0x4b, 0x42, 0x6f, 0x12, - 0xac, 0x18, 0x51, 0xc3, 0xd5, 0x0b, 0x1a, 0x9b, 0x98, 0x84, 0x01, 0x93, 0xbb, 0x46, 0x98, 0xe3, - 0x82, 0x68, 0xc7, 0x0a, 0xc3, 0xfe, 0x2d, 0x0b, 0xb2, 0x1a, 0xc9, 0xa8, 0x61, 0x67, 0xed, 0x59, - 0xc3, 0xee, 0x00, 0x55, 0xe0, 0x7e, 0x12, 0x86, 0x9d, 0x84, 0x1a, 0x11, 0x7c, 0xdb, 0x5d, 0x3e, - 0xdc, 0xb1, 0xc6, 0x62, 0xd0, 0x74, 0xd7, 0x5d, 0xb6, 0xdd, 0x36, 0xc9, 0xd9, 0xff, 0x7d, 0x00, - 0x4e, 0x75, 0x65, 0xa5, 0xa0, 0x17, 0x60, 0xa4, 0x21, 0xa6, 0x47, 0x28, 0x1d, 0x5a, 0x35, 0x33, - 0x2c, 0x4e, 0xc3, 0x70, 0x0a, 0xb3, 0x8f, 0x09, 0x3a, 0x0f, 0xa7, 0x23, 0xba, 0xd1, 0xef, 0x90, - 0xe9, 0xf5, 0x84, 0x44, 0x2b, 0xa4, 0x11, 0xf8, 0x4d, 0x5e, 0x69, 0xb1, 0x5c, 0x7f, 0xf8, 0xce, - 0xee, 0xc4, 0x69, 0xdc, 0x0d, 0xc6, 0x79, 0xcf, 0xa0, 0x10, 0x46, 0x3d, 0xd3, 0x06, 0x14, 0x1b, - 0x80, 0x43, 0x99, 0x8f, 0xca, 0x46, 0x48, 0x35, 0xe3, 0x34, 0x83, 0xb4, 0x21, 0x59, 0xb9, 0x4f, - 0x86, 0xe4, 0xa7, 0xb5, 0x21, 0xc9, 0xcf, 0xdf, 0x3f, 0x5c, 0x70, 0x56, 0xd2, 0x71, 0x5b, 0x92, - 0x2f, 0x41, 0x55, 0xc6, 0x26, 0xf5, 0x15, 0xd3, 0x63, 0xd2, 0xe9, 0x21, 0xd1, 0x9e, 0x84, 0x1f, - 0xbe, 0x18, 0x45, 0xc6, 0x60, 0x5e, 0x0b, 0x92, 0x69, 0xcf, 0x0b, 0x6e, 0x53, 0x25, 0x7d, 0x3d, - 0x26, 0xc2, 0xc3, 0x62, 0xdf, 0x2d, 0x41, 0xce, 0x66, 0x85, 0xae, 0x47, 0x6d, 0x19, 0xa4, 0xd6, - 0xe3, 0xc1, 0xac, 0x03, 0xb4, 0xcd, 0xe3, 0xb7, 0xb8, 0x0e, 0xfc, 0x50, 0xd1, 0x9b, 0x2d, 0x1d, - 0xd2, 0xa5, 0x92, 0x29, 0x54, 0x58, 0xd7, 0x05, 0x00, 0x6d, 0xd0, 0x89, 0x50, 0x79, 0x75, 0x3c, - 0xac, 0xed, 0x3e, 0x6c, 0x60, 0xd1, 0xbd, 0xb7, 0xeb, 0xc7, 0x89, 0xe3, 0x79, 0x97, 0x5d, 0x3f, - 0x11, 0x4e, 0x44, 0xa5, 0xec, 0xe7, 0x35, 0x08, 0x9b, 0x78, 0xe7, 0xde, 0x63, 0x7c, 0xbf, 0x83, - 0x7c, 0xf7, 0x0d, 0x78, 0x64, 0xce, 0x4d, 0x54, 0x82, 0x87, 0x9a, 0x6f, 0xd4, 0x5e, 0x53, 0x09, - 0x4b, 0x56, 0xcf, 0x84, 0x25, 0x23, 0xc1, 0xa2, 0x94, 0xce, 0x07, 0xc9, 0x26, 0x58, 0xd8, 0x2f, - 0xc0, 0x99, 0x39, 0x37, 0xb9, 0xe4, 0x7a, 0xe4, 0x80, 0x4c, 0xec, 0xdf, 0x1c, 0x84, 0x11, 0x33, - 0x55, 0xf1, 0x20, 0x39, 0x57, 0x5f, 0xa2, 0x26, 0x99, 0x78, 0x3b, 0x57, 0x1d, 0xae, 0xdd, 0x3c, - 0x72, 0xde, 0x64, 0xfe, 0x88, 0x19, 0x56, 0x99, 0xe6, 0x89, 0xcd, 0x0e, 0xa0, 0xdb, 0x50, 0x59, - 0x67, 0x09, 0x00, 0xe5, 0x22, 0x22, 0x10, 0xf2, 0x46, 0x54, 0x2f, 0x47, 0x9e, 0x42, 0xc0, 0xf9, - 0x51, 0x4d, 0x1a, 0xa5, 0xb3, 0xca, 0x8c, 0xa0, 0x55, 0x91, 0x4f, 0xa6, 0x30, 0x7a, 0xa9, 0x84, - 0xca, 0x21, 0x54, 0x42, 0x4a, 0x40, 0x0f, 0xde, 0x27, 0x01, 0xcd, 0x92, 0x39, 0x92, 0x0d, 0x66, - 0xe7, 0x89, 0x28, 0xfb, 0x21, 0x36, 0x08, 0x46, 0x32, 0x47, 0x0a, 0x8c, 0xb3, 0xf8, 0xe8, 0x13, - 0x4a, 0xc4, 0x57, 0x8b, 0xf0, 0xbf, 0x9a, 0x33, 0xfa, 0xb8, 0xa5, 0xfb, 0x17, 0x4a, 0x30, 0x36, - 0xe7, 0x77, 0x96, 0xe7, 0x96, 0x3b, 0x6b, 0x9e, 0xdb, 0xb8, 0x4a, 0x76, 0xa8, 0x08, 0xdf, 0x24, - 0x3b, 0xf3, 0xb3, 0x62, 0x05, 0xa9, 0x39, 0x73, 0x95, 0x36, 0x62, 0x0e, 0xa3, 0xc2, 0x68, 0xdd, - 0xf5, 0x5b, 0x24, 0x0a, 0x23, 0x57, 0xb8, 0x46, 0x0d, 0x61, 0x74, 0x49, 0x83, 0xb0, 0x89, 0x47, - 0x69, 0x07, 0xb7, 0x7d, 0x12, 0x65, 0x0d, 0xde, 0x25, 0xda, 0x88, 0x39, 0x8c, 0x22, 0x25, 0x51, - 0x27, 0x4e, 0xc4, 0x64, 0x54, 0x48, 0xab, 0xb4, 0x11, 0x73, 0x18, 0x5d, 0xe9, 0x71, 0x67, 0x8d, - 0x05, 0x78, 0x64, 0x42, 0xfa, 0x57, 0x78, 0x33, 0x96, 0x70, 0x8a, 0xba, 0x49, 0x76, 0x66, 0xe9, - 0xee, 0x38, 0x93, 0xd9, 0x73, 0x95, 0x37, 0x63, 0x09, 0x67, 0xb5, 0x20, 0xd3, 0xc3, 0xf1, 0x7d, - 0x57, 0x0b, 0x32, 0xdd, 0xfd, 0x1e, 0xfb, 0xec, 0x5f, 0xb6, 0x60, 0xc4, 0x0c, 0xcb, 0x42, 0xad, - 0x8c, 0x2d, 0xbc, 0xd4, 0x55, 0x4a, 0xf8, 0x7d, 0x79, 0xd7, 0xb8, 0xb5, 0xdc, 0x24, 0x08, 0xe3, - 0x67, 0x88, 0xdf, 0x72, 0x7d, 0xc2, 0x4e, 0xdb, 0x79, 0x38, 0x57, 0x2a, 0xe6, 0x6b, 0x26, 0x68, - 0x92, 0x43, 0x18, 0xd3, 0xf6, 0x4d, 0x38, 0xd5, 0x95, 0xce, 0xd5, 0x87, 0x09, 0xb2, 0x6f, 0x32, - 0xad, 0x8d, 0x61, 0x98, 0x12, 0x96, 0xf5, 0x88, 0x66, 0xe0, 0x14, 0x5f, 0x48, 0x94, 0xd3, 0x4a, - 0x63, 0x83, 0xb4, 0x55, 0x8a, 0x1e, 0xf3, 0xc3, 0xdf, 0xc8, 0x02, 0x71, 0x37, 0xbe, 0xfd, 0x45, - 0x0b, 0x46, 0x53, 0x19, 0x76, 0x05, 0x19, 0x4b, 0x6c, 0xa5, 0x05, 0x2c, 0x4a, 0x90, 0x85, 0x4a, - 0x97, 0x99, 0x32, 0xd5, 0x2b, 0x4d, 0x83, 0xb0, 0x89, 0x67, 0x7f, 0xa5, 0x04, 0x55, 0x19, 0x69, - 0xd1, 0x47, 0x57, 0x3e, 0x6f, 0xc1, 0xa8, 0x3a, 0xfb, 0x60, 0x4e, 0xb5, 0x52, 0x11, 0xe9, 0x10, - 0xb4, 0x07, 0x6a, 0x5b, 0xee, 0xaf, 0x07, 0xda, 0x72, 0xc7, 0x26, 0x33, 0x9c, 0xe6, 0x8d, 0x6e, - 0x00, 0xc4, 0x3b, 0x71, 0x42, 0xda, 0x86, 0x7b, 0xcf, 0x36, 0x56, 0xdc, 0x64, 0x23, 0x88, 0x08, - 0x5d, 0x5f, 0xd7, 0x82, 0x26, 0x59, 0x51, 0x98, 0xda, 0x84, 0xd2, 0x6d, 0xd8, 0xa0, 0x64, 0xff, - 0xdd, 0x12, 0x9c, 0xcc, 0x76, 0x09, 0x7d, 0x18, 0x46, 0x24, 0x77, 0xe3, 0x46, 0x3a, 0x19, 0x5e, - 0x32, 0x82, 0x0d, 0xd8, 0xdd, 0xdd, 0x89, 0x89, 0xee, 0x2b, 0x01, 0x27, 0x4d, 0x14, 0x9c, 0x22, - 0xc6, 0x0f, 0xa0, 0xc4, 0x49, 0x69, 0x7d, 0x67, 0x3a, 0x0c, 0xc5, 0x29, 0x92, 0x71, 0x00, 0x65, - 0x42, 0x71, 0x06, 0x1b, 0x2d, 0xc3, 0x19, 0xa3, 0xe5, 0x1a, 0x71, 0x5b, 0x1b, 0x6b, 0x41, 0x24, - 0x77, 0x60, 0x8f, 0xea, 0x00, 0xb0, 0x6e, 0x1c, 0x9c, 0xfb, 0x24, 0xd5, 0xf6, 0x0d, 0x27, 0x74, - 0x1a, 0x6e, 0xb2, 0x23, 0xfc, 0x95, 0x4a, 0x36, 0xcd, 0x88, 0x76, 0xac, 0x30, 0xec, 0x45, 0x18, - 0xe8, 0x73, 0x06, 0xf5, 0x65, 0xf9, 0xbf, 0x04, 0x55, 0x4a, 0x4e, 0x9a, 0x77, 0x45, 0x90, 0x0c, - 0xa0, 0x2a, 0x6f, 0x8a, 0x41, 0x36, 0x94, 0x5d, 0x47, 0x9e, 0xf1, 0xa9, 0xd7, 0x9a, 0x8f, 0xe3, - 0x0e, 0xdb, 0x4c, 0x53, 0x20, 0x7a, 0x02, 0xca, 0x64, 0x3b, 0xcc, 0x1e, 0xe6, 0x5d, 0xdc, 0x0e, - 0xdd, 0x88, 0xc4, 0x14, 0x89, 0x6c, 0x87, 0xe8, 0x1c, 0x94, 0xdc, 0xa6, 0x50, 0x52, 0x20, 0x70, - 0x4a, 0xf3, 0xb3, 0xb8, 0xe4, 0x36, 0xed, 0x6d, 0xa8, 0xa9, 0xab, 0x69, 0xd0, 0xa6, 0x94, 0xdd, - 0x56, 0x11, 0xa1, 0x51, 0x92, 0x6e, 0x0f, 0xa9, 0xdd, 0x01, 0xd0, 0xa9, 0x86, 0x45, 0xc9, 0x97, - 0xf3, 0x30, 0xd0, 0x08, 0x44, 0x1a, 0x74, 0x55, 0x93, 0x61, 0x42, 0x9b, 0x41, 0xec, 0x9b, 0x30, - 0x76, 0xd5, 0x0f, 0x6e, 0xb3, 0xc2, 0xf8, 0xac, 0x0e, 0x1c, 0x25, 0xbc, 0x4e, 0x7f, 0x64, 0x4d, - 0x04, 0x06, 0xc5, 0x1c, 0xa6, 0x2a, 0x54, 0x95, 0x7a, 0x55, 0xa8, 0xb2, 0x3f, 0x69, 0xc1, 0x88, - 0xca, 0x59, 0x9a, 0xdb, 0xda, 0xa4, 0x74, 0x5b, 0x51, 0xd0, 0x09, 0xb3, 0x74, 0xd9, 0xe5, 0x51, - 0x98, 0xc3, 0xcc, 0x64, 0xbe, 0xd2, 0x3e, 0xc9, 0x7c, 0xe7, 0x61, 0x60, 0xd3, 0xf5, 0x9b, 0xd9, - 0xdb, 0x50, 0xae, 0xba, 0x7e, 0x13, 0x33, 0x08, 0xed, 0xc2, 0x49, 0xd5, 0x05, 0xa9, 0x10, 0x5e, - 0x80, 0x91, 0xb5, 0x8e, 0xeb, 0x35, 0x65, 0x81, 0xbb, 0x8c, 0x47, 0xa5, 0x6e, 0xc0, 0x70, 0x0a, - 0x93, 0xee, 0xeb, 0xd6, 0x5c, 0xdf, 0x89, 0x76, 0x96, 0xb5, 0x06, 0x52, 0x42, 0xa9, 0xae, 0x20, - 0xd8, 0xc0, 0xb2, 0xdf, 0x28, 0xc3, 0x58, 0x3a, 0x73, 0xab, 0x8f, 0xed, 0xd5, 0x13, 0x50, 0x61, - 0xc9, 0x5c, 0xd9, 0x4f, 0xcb, 0x6b, 0xc2, 0x71, 0x18, 0x8a, 0x61, 0x90, 0x97, 0x81, 0x28, 0xe6, - 0x26, 0x21, 0xd5, 0x49, 0xe5, 0x87, 0x61, 0x71, 0x67, 0xa2, 0xf2, 0x84, 0x60, 0x85, 0x3e, 0x63, - 0xc1, 0x50, 0x10, 0x9a, 0x95, 0x8d, 0x3e, 0x54, 0x64, 0x56, 0x9b, 0x48, 0xaa, 0x11, 0x16, 0xb1, - 0xfa, 0xf4, 0xf2, 0x73, 0x48, 0xd6, 0xe7, 0xde, 0x0b, 0x23, 0x26, 0xe6, 0x7e, 0x46, 0x71, 0xd5, - 0x34, 0x8a, 0x3f, 0x6f, 0x4e, 0x0a, 0x91, 0xb7, 0xd7, 0xc7, 0x72, 0xbb, 0x0e, 0x95, 0x86, 0x0a, - 0x14, 0x38, 0x54, 0x59, 0x54, 0x55, 0x97, 0x81, 0x1d, 0x16, 0x71, 0x6a, 0xf6, 0x77, 0x2c, 0x63, - 0x7e, 0x60, 0x12, 0xcf, 0x37, 0x51, 0x04, 0xe5, 0xd6, 0xd6, 0xa6, 0x30, 0x45, 0xaf, 0x14, 0x34, - 0xbc, 0x73, 0x5b, 0x9b, 0x7a, 0x8e, 0x9b, 0xad, 0x98, 0x32, 0xeb, 0xc3, 0x59, 0x98, 0x4a, 0xef, - 0x2c, 0xef, 0x9f, 0xde, 0x69, 0xbf, 0x59, 0x82, 0x53, 0x5d, 0x93, 0x0a, 0xbd, 0x0e, 0x95, 0x88, - 0xbe, 0xa5, 0x78, 0xbd, 0x85, 0xc2, 0x12, 0x32, 0xe3, 0xf9, 0xa6, 0xd6, 0xbb, 0xe9, 0x76, 0xcc, - 0x59, 0xa2, 0x2b, 0x80, 0x74, 0x38, 0x8b, 0xf2, 0x54, 0xf2, 0x57, 0x3e, 0x27, 0x1e, 0x45, 0xd3, - 0x5d, 0x18, 0x38, 0xe7, 0x29, 0xf4, 0x62, 0xd6, 0xe1, 0x59, 0x4e, 0x9f, 0x6f, 0xee, 0xe5, 0xbb, - 0xb4, 0xff, 0x49, 0x09, 0x46, 0x53, 0x85, 0xa6, 0x90, 0x07, 0x55, 0xe2, 0x31, 0xe7, 0xbf, 0x54, - 0x36, 0x47, 0x2d, 0x1b, 0xad, 0x14, 0xe4, 0x45, 0x41, 0x17, 0x2b, 0x0e, 0x0f, 0xc6, 0x21, 0xfc, - 0x0b, 0x30, 0x22, 0x3b, 0xf4, 0x21, 0xa7, 0xed, 0x89, 0x01, 0x54, 0x73, 0xf4, 0xa2, 0x01, 0xc3, - 0x29, 0x4c, 0xfb, 0xb7, 0xcb, 0x30, 0xce, 0x4f, 0x4b, 0x9a, 0x6a, 0xe6, 0x2d, 0xca, 0xfd, 0xd6, - 0x5f, 0xd4, 0xe5, 0xe0, 0xf8, 0x40, 0xae, 0x1d, 0xf5, 0x96, 0x86, 0x7c, 0x46, 0x7d, 0x45, 0x70, - 0x7d, 0x3d, 0x13, 0xc1, 0xc5, 0xcd, 0xee, 0xd6, 0x31, 0xf5, 0xe8, 0xfb, 0x2b, 0xa4, 0xeb, 0x6f, - 0x95, 0xe0, 0x44, 0xe6, 0x0a, 0x0c, 0xf4, 0x46, 0xba, 0x6a, 0xb2, 0x55, 0x84, 0x4f, 0x7d, 0xcf, - 0x5b, 0x11, 0x0e, 0x56, 0x3b, 0xf9, 0x3e, 0x2d, 0x15, 0xfb, 0x0f, 0x4a, 0x30, 0x96, 0xbe, 0xbb, - 0xe3, 0x01, 0x1c, 0xa9, 0x77, 0x41, 0x8d, 0x95, 0xa7, 0x67, 0x57, 0x9a, 0x72, 0x97, 0x3c, 0xaf, - 0x04, 0x2e, 0x1b, 0xb1, 0x86, 0x3f, 0x10, 0x25, 0xa9, 0xed, 0xbf, 0x6d, 0xc1, 0x59, 0xfe, 0x96, - 0xd9, 0x79, 0xf8, 0x97, 0xf2, 0x46, 0xf7, 0x95, 0x62, 0x3b, 0x98, 0x29, 0x63, 0xb8, 0xdf, 0xf8, - 0xb2, 0xab, 0x14, 0x45, 0x6f, 0xd3, 0x53, 0xe1, 0x01, 0xec, 0xec, 0x81, 0x26, 0x83, 0xfd, 0x07, - 0x65, 0xd0, 0xb7, 0x47, 0x22, 0x57, 0xe4, 0x42, 0x16, 0x52, 0xce, 0x71, 0x65, 0xc7, 0x6f, 0xe8, - 0x7b, 0x2a, 0xab, 0x99, 0x54, 0xc8, 0x9f, 0xb3, 0x60, 0xd8, 0xf5, 0xdd, 0xc4, 0x75, 0xd8, 0x36, - 0xba, 0x98, 0x9b, 0xed, 0x14, 0xbb, 0x79, 0x4e, 0x39, 0x88, 0xcc, 0x73, 0x1c, 0xc5, 0x0c, 0x9b, - 0x9c, 0xd1, 0x47, 0x45, 0x90, 0x75, 0xb9, 0xb0, 0x2c, 0xde, 0x6a, 0x26, 0xb2, 0x3a, 0xa4, 0x86, - 0x57, 0x12, 0x15, 0x94, 0xfc, 0x8e, 0x29, 0x29, 0x55, 0x19, 0x58, 0xdf, 0xe3, 0x4d, 0x9b, 0x31, - 0x67, 0x64, 0xc7, 0x80, 0xba, 0xc7, 0xe2, 0x80, 0x01, 0xac, 0x53, 0x50, 0x73, 0x3a, 0x49, 0xd0, - 0xa6, 0xc3, 0x24, 0x8e, 0x9a, 0x74, 0x88, 0xae, 0x04, 0x60, 0x8d, 0x63, 0xbf, 0x51, 0x81, 0x4c, - 0x72, 0x22, 0xda, 0x36, 0x6f, 0x3e, 0xb5, 0x8a, 0xbd, 0xf9, 0x54, 0x75, 0x26, 0xef, 0xf6, 0x53, - 0xd4, 0x82, 0x4a, 0xb8, 0xe1, 0xc4, 0xd2, 0xac, 0x7e, 0x49, 0xed, 0xe3, 0x68, 0xe3, 0xdd, 0xdd, - 0x89, 0x9f, 0xe8, 0xcf, 0xeb, 0x4a, 0xe7, 0xea, 0x14, 0x2f, 0x73, 0xa2, 0x59, 0x33, 0x1a, 0x98, - 0xd3, 0x3f, 0xc8, 0xdd, 0x7e, 0x9f, 0x12, 0x75, 0xf8, 0x31, 0x89, 0x3b, 0x5e, 0x22, 0x66, 0xc3, - 0x4b, 0x05, 0xae, 0x32, 0x4e, 0x58, 0xa7, 0xd5, 0xf3, 0xff, 0xd8, 0x60, 0x8a, 0x3e, 0x0c, 0xb5, - 0x38, 0x71, 0xa2, 0xe4, 0x90, 0x89, 0xb0, 0x6a, 0xd0, 0x57, 0x24, 0x11, 0xac, 0xe9, 0xa1, 0x97, - 0x59, 0x75, 0x5b, 0x37, 0xde, 0x38, 0x64, 0x6e, 0x84, 0xac, 0x84, 0x2b, 0x28, 0x60, 0x83, 0x1a, - 0xba, 0x00, 0xc0, 0xe6, 0x36, 0x0f, 0x08, 0xac, 0x32, 0x2f, 0x93, 0x12, 0x85, 0x58, 0x41, 0xb0, - 0x81, 0x65, 0xff, 0x28, 0xa4, 0xeb, 0x42, 0xa0, 0x09, 0x59, 0x86, 0x82, 0x7b, 0xa1, 0x59, 0x8e, - 0x43, 0xaa, 0x62, 0xc4, 0xaf, 0x5b, 0x60, 0x16, 0xaf, 0x40, 0xaf, 0xf1, 0x2a, 0x19, 0x56, 0x11, - 0x27, 0x87, 0x06, 0xdd, 0xc9, 0x45, 0x27, 0xcc, 0x1c, 0x61, 0xcb, 0x52, 0x19, 0xe7, 0xde, 0x03, - 0x55, 0x09, 0x3d, 0x90, 0x51, 0xf7, 0x09, 0x38, 0x9d, 0xbd, 0x17, 0x5e, 0x9c, 0x3a, 0xed, 0xef, - 0xfa, 0x91, 0xfe, 0x9c, 0x52, 0x2f, 0x7f, 0x4e, 0x1f, 0xf7, 0xdf, 0xfe, 0x86, 0x05, 0xe7, 0xf7, - 0xbb, 0xbe, 0x1e, 0x3d, 0x0a, 0x03, 0xb7, 0x9d, 0x48, 0x96, 0x1d, 0x67, 0x82, 0xf2, 0xa6, 0x13, - 0xf9, 0x98, 0xb5, 0xa2, 0x1d, 0x18, 0xe4, 0x51, 0x63, 0xc2, 0x5a, 0x7f, 0xa9, 0xd8, 0xcb, 0xf4, - 0xaf, 0x12, 0x63, 0xbb, 0xc0, 0x23, 0xd6, 0xb0, 0x60, 0x68, 0x7f, 0xd7, 0x02, 0xb4, 0xb4, 0x45, - 0xa2, 0xc8, 0x6d, 0x1a, 0x71, 0x6e, 0xec, 0x3e, 0x1b, 0xe3, 0xde, 0x1a, 0x33, 0x15, 0x36, 0x73, - 0x9f, 0x8d, 0xf1, 0x2f, 0xff, 0x3e, 0x9b, 0xd2, 0xc1, 0xee, 0xb3, 0x41, 0x4b, 0x70, 0xb6, 0xcd, - 0xb7, 0x1b, 0xfc, 0x8e, 0x08, 0xbe, 0xf7, 0x50, 0x89, 0x67, 0x8f, 0xdc, 0xd9, 0x9d, 0x38, 0xbb, - 0x98, 0x87, 0x80, 0xf3, 0x9f, 0xb3, 0xdf, 0x03, 0x88, 0x87, 0xb7, 0xcd, 0xe4, 0xc5, 0x2a, 0xf5, - 0x74, 0xbf, 0xd8, 0x5f, 0xab, 0xc0, 0x89, 0x4c, 0x51, 0x5a, 0xba, 0xd5, 0xeb, 0x0e, 0x8e, 0x3a, - 0xb2, 0xfe, 0xee, 0xee, 0x5e, 0x5f, 0xe1, 0x56, 0x3e, 0x54, 0x5c, 0x3f, 0xec, 0x24, 0xc5, 0xe4, - 0x9a, 0xf2, 0x4e, 0xcc, 0x53, 0x82, 0x86, 0xbb, 0x98, 0xfe, 0xc5, 0x9c, 0x4d, 0x91, 0xc1, 0x5b, - 0x29, 0x63, 0x7c, 0xe0, 0x3e, 0xb9, 0x03, 0x3e, 0xa5, 0x43, 0xa9, 0x2a, 0x45, 0x38, 0x16, 0x33, - 0x93, 0xe5, 0xb8, 0x8f, 0xda, 0x7f, 0xad, 0x04, 0xc3, 0xc6, 0x47, 0x43, 0xbf, 0x94, 0x2e, 0xed, - 0x64, 0x15, 0xf7, 0x4a, 0x8c, 0xfe, 0xa4, 0x2e, 0xde, 0xc4, 0x5f, 0xe9, 0xc9, 0xee, 0xaa, 0x4e, - 0x77, 0x77, 0x27, 0x4e, 0x66, 0xea, 0x36, 0xa5, 0x2a, 0x3d, 0x9d, 0xfb, 0x38, 0x9c, 0xc8, 0x90, - 0xc9, 0x79, 0xe5, 0xd5, 0xf4, 0xb5, 0xff, 0x47, 0x74, 0x4b, 0x99, 0x43, 0xf6, 0x2d, 0x3a, 0x64, - 0x22, 0xdd, 0x2e, 0xf0, 0x48, 0x1f, 0x3e, 0xd8, 0x4c, 0x56, 0x6d, 0xa9, 0xcf, 0xac, 0xda, 0xa7, - 0xa0, 0x1a, 0x06, 0x9e, 0xdb, 0x70, 0x55, 0xfd, 0x43, 0x96, 0xc7, 0xbb, 0x2c, 0xda, 0xb0, 0x82, - 0xa2, 0xdb, 0x50, 0xbb, 0x75, 0x3b, 0xe1, 0xa7, 0x3f, 0xc2, 0xbf, 0x5d, 0xd4, 0xa1, 0x8f, 0x32, - 0x5a, 0xd4, 0xf1, 0x12, 0xd6, 0xbc, 0x90, 0x0d, 0x83, 0x4c, 0x09, 0xca, 0x14, 0x01, 0xe6, 0x7b, - 0x67, 0xda, 0x31, 0xc6, 0x02, 0x62, 0x7f, 0xb3, 0x06, 0x67, 0xf2, 0x2a, 0x83, 0xa3, 0x8f, 0xc1, - 0x20, 0xef, 0x63, 0x31, 0x97, 0x4f, 0xe4, 0xf1, 0x98, 0x63, 0x04, 0x45, 0xb7, 0xd8, 0x6f, 0x2c, - 0x78, 0x0a, 0xee, 0x9e, 0xb3, 0x26, 0x66, 0xc8, 0xf1, 0x70, 0x5f, 0x70, 0x34, 0xf7, 0x05, 0x87, - 0x73, 0xf7, 0x9c, 0x35, 0xb4, 0x0d, 0x95, 0x96, 0x9b, 0x10, 0x47, 0x38, 0x11, 0x6e, 0x1e, 0x0b, - 0x73, 0xe2, 0x70, 0x2b, 0x8d, 0xfd, 0xc4, 0x9c, 0x21, 0xfa, 0x86, 0x05, 0x27, 0xd6, 0xd2, 0x29, - 0xf4, 0x42, 0x78, 0x3a, 0xc7, 0x50, 0xfd, 0x3d, 0xcd, 0x88, 0x5f, 0xe8, 0x94, 0x69, 0xc4, 0xd9, - 0xee, 0xa0, 0x4f, 0x5b, 0x30, 0xb4, 0xee, 0x7a, 0x46, 0x01, 0xde, 0x63, 0xf8, 0x38, 0x97, 0x18, - 0x03, 0xbd, 0xe3, 0xe0, 0xff, 0x63, 0x2c, 0x39, 0xf7, 0xd2, 0x54, 0x83, 0x47, 0xd5, 0x54, 0x43, - 0xf7, 0x49, 0x53, 0x7d, 0xce, 0x82, 0x9a, 0x1a, 0x69, 0x91, 0x16, 0xfd, 0xe1, 0x63, 0xfc, 0xe4, - 0xdc, 0x73, 0xa2, 0xfe, 0x62, 0xcd, 0x1c, 0x7d, 0xd9, 0x82, 0x61, 0xe7, 0xf5, 0x4e, 0x44, 0x9a, - 0x64, 0x2b, 0x08, 0x63, 0x71, 0x1b, 0xe4, 0x2b, 0xc5, 0x77, 0x66, 0x9a, 0x32, 0x99, 0x25, 0x5b, - 0x4b, 0x61, 0x2c, 0xd2, 0x97, 0x74, 0x03, 0x36, 0xbb, 0x60, 0xef, 0x96, 0x60, 0x62, 0x1f, 0x0a, - 0xe8, 0x05, 0x18, 0x09, 0xa2, 0x96, 0xe3, 0xbb, 0xaf, 0x9b, 0x35, 0x31, 0x94, 0x95, 0xb5, 0x64, - 0xc0, 0x70, 0x0a, 0xd3, 0x4c, 0xdc, 0x2e, 0xed, 0x93, 0xb8, 0x7d, 0x1e, 0x06, 0x22, 0x12, 0x06, - 0xd9, 0xcd, 0x02, 0x4b, 0x1d, 0x60, 0x10, 0xf4, 0x18, 0x94, 0x9d, 0xd0, 0x15, 0x81, 0x68, 0x6a, - 0x0f, 0x34, 0xbd, 0x3c, 0x8f, 0x69, 0x7b, 0xaa, 0x8e, 0x44, 0xe5, 0x9e, 0xd4, 0x91, 0xa0, 0x6a, - 0x40, 0x9c, 0x5d, 0x0c, 0x6a, 0x35, 0x90, 0x3e, 0x53, 0xb0, 0xdf, 0x2c, 0xc3, 0x63, 0x7b, 0xce, - 0x17, 0x1d, 0x87, 0x67, 0xed, 0x11, 0x87, 0x27, 0x87, 0xa7, 0xb4, 0xdf, 0xf0, 0x94, 0x7b, 0x0c, - 0xcf, 0xa7, 0xe9, 0x32, 0x90, 0xb5, 0x44, 0x8a, 0xb9, 0xcf, 0xaf, 0x57, 0x69, 0x12, 0xb1, 0x02, - 0x24, 0x14, 0x6b, 0xbe, 0x74, 0x0f, 0x90, 0x4a, 0x5a, 0xae, 0x14, 0xa1, 0x06, 0x7a, 0xd6, 0x16, - 0xe1, 0x73, 0xbf, 0x57, 0x26, 0xb4, 0xfd, 0xf3, 0x25, 0x78, 0xa2, 0x0f, 0xe9, 0x6d, 0xce, 0x62, - 0xab, 0xcf, 0x59, 0xfc, 0xfd, 0xfd, 0x99, 0xec, 0xbf, 0x6c, 0xc1, 0xb9, 0xde, 0xca, 0x03, 0x3d, - 0x0b, 0xc3, 0x6b, 0x91, 0xe3, 0x37, 0x36, 0xd8, 0x1d, 0xa5, 0x72, 0x50, 0xd8, 0x58, 0xeb, 0x66, - 0x6c, 0xe2, 0xd0, 0xed, 0x2d, 0x8f, 0x49, 0x30, 0x30, 0x64, 0x92, 0x29, 0xdd, 0xde, 0xae, 0x66, - 0x81, 0xb8, 0x1b, 0xdf, 0xfe, 0xb3, 0x52, 0x7e, 0xb7, 0xb8, 0x91, 0x71, 0x90, 0xef, 0x24, 0xbe, - 0x42, 0xa9, 0x0f, 0x59, 0x52, 0xbe, 0xd7, 0xb2, 0x64, 0xa0, 0x97, 0x2c, 0x41, 0xb3, 0x70, 0xd2, - 0xb8, 0x44, 0x86, 0x27, 0x0e, 0xf3, 0x80, 0x5b, 0x55, 0x4d, 0x63, 0x39, 0x03, 0xc7, 0x5d, 0x4f, - 0xa0, 0xa7, 0xa1, 0xea, 0xfa, 0x31, 0x69, 0x74, 0x22, 0x1e, 0xe8, 0x6d, 0x24, 0x6b, 0xcd, 0x8b, - 0x76, 0xac, 0x30, 0xec, 0x5f, 0x2e, 0xc1, 0x23, 0x3d, 0xed, 0xac, 0x7b, 0x24, 0xbb, 0xcc, 0xcf, - 0x31, 0x70, 0x6f, 0x3e, 0x87, 0x39, 0x48, 0x95, 0x7d, 0x07, 0xe9, 0x0f, 0x7b, 0x4f, 0x4c, 0x6a, - 0x73, 0xff, 0xc0, 0x8e, 0xd2, 0x8b, 0x30, 0xea, 0x84, 0x21, 0xc7, 0x63, 0xf1, 0x9a, 0x99, 0x6a, - 0x3a, 0xd3, 0x26, 0x10, 0xa7, 0x71, 0xfb, 0xd2, 0x9e, 0x7f, 0x6c, 0x41, 0x0d, 0x93, 0x75, 0x2e, - 0x1d, 0xd0, 0x2d, 0x31, 0x44, 0x56, 0x11, 0x75, 0x37, 0xe9, 0xc0, 0xc6, 0x2e, 0xab, 0x47, 0x99, - 0x37, 0xd8, 0xdd, 0x97, 0xfc, 0x94, 0x0e, 0x74, 0xc9, 0x8f, 0xba, 0xe6, 0xa5, 0xdc, 0xfb, 0x9a, - 0x17, 0xfb, 0x5b, 0x43, 0xf4, 0xf5, 0xc2, 0x60, 0x26, 0x22, 0xcd, 0x98, 0x7e, 0xdf, 0x4e, 0xe4, - 0x89, 0x49, 0xa2, 0xbe, 0xef, 0x75, 0xbc, 0x80, 0x69, 0x7b, 0xea, 0x28, 0xa6, 0x74, 0xa0, 0x5a, - 0x22, 0xe5, 0x7d, 0x6b, 0x89, 0xbc, 0x08, 0xa3, 0x71, 0xbc, 0xb1, 0x1c, 0xb9, 0x5b, 0x4e, 0x42, - 0xae, 0x92, 0x1d, 0x61, 0x65, 0xe9, 0xfc, 0xff, 0x95, 0xcb, 0x1a, 0x88, 0xd3, 0xb8, 0x68, 0x0e, - 0x4e, 0xe9, 0x8a, 0x1e, 0x24, 0x4a, 0x58, 0x74, 0x3f, 0x9f, 0x09, 0x2a, 0xd9, 0x57, 0xd7, 0x00, - 0x11, 0x08, 0xb8, 0xfb, 0x19, 0x2a, 0xdf, 0x52, 0x8d, 0xb4, 0x23, 0x83, 0x69, 0xf9, 0x96, 0xa2, - 0x43, 0xfb, 0xd2, 0xf5, 0x04, 0x5a, 0x84, 0xd3, 0x7c, 0x62, 0x4c, 0x87, 0xa1, 0xf1, 0x46, 0x43, - 0xe9, 0x7a, 0x87, 0x73, 0xdd, 0x28, 0x38, 0xef, 0x39, 0xf4, 0x3c, 0x0c, 0xab, 0xe6, 0xf9, 0x59, - 0x71, 0x8a, 0xa0, 0xbc, 0x18, 0x8a, 0xcc, 0x7c, 0x13, 0x9b, 0x78, 0xe8, 0x43, 0xf0, 0xb0, 0xfe, - 0xcb, 0x53, 0xc0, 0xf8, 0xd1, 0xda, 0xac, 0x28, 0x96, 0xa4, 0x2e, 0x15, 0x99, 0xcb, 0x45, 0x6b, - 0xe2, 0x5e, 0xcf, 0xa3, 0x35, 0x38, 0xa7, 0x40, 0x17, 0xfd, 0x84, 0xe5, 0x73, 0xc4, 0xa4, 0xee, - 0xc4, 0xe4, 0x7a, 0xe4, 0x89, 0xcb, 0x69, 0xd5, 0xbd, 0x93, 0x73, 0x6e, 0x72, 0x39, 0x0f, 0x13, - 0x2f, 0xe0, 0x3d, 0xa8, 0xa0, 0x29, 0xa8, 0x11, 0xdf, 0x59, 0xf3, 0xc8, 0xd2, 0xcc, 0x3c, 0x2b, - 0xba, 0x64, 0x9c, 0xe4, 0x5d, 0x94, 0x00, 0xac, 0x71, 0x54, 0x84, 0xe9, 0x48, 0xcf, 0x3b, 0x50, - 0x97, 0xe1, 0x4c, 0xab, 0x11, 0x52, 0xdb, 0xc3, 0x6d, 0x90, 0xe9, 0x06, 0x0b, 0xa8, 0xa3, 0x1f, - 0x86, 0x17, 0xa2, 0x54, 0xe1, 0xd3, 0x73, 0x33, 0xcb, 0x5d, 0x38, 0x38, 0xf7, 0x49, 0x16, 0x78, - 0x19, 0x05, 0xdb, 0x3b, 0xe3, 0xa7, 0x33, 0x81, 0x97, 0xb4, 0x11, 0x73, 0x18, 0xba, 0x02, 0x88, - 0xc5, 0xe2, 0x5f, 0x4e, 0x92, 0x50, 0x19, 0x3b, 0xe3, 0x67, 0xd8, 0x2b, 0xa9, 0x30, 0xb2, 0x4b, - 0x5d, 0x18, 0x38, 0xe7, 0x29, 0xfb, 0xdf, 0x5b, 0x30, 0xaa, 0xd6, 0xeb, 0x3d, 0xc8, 0x46, 0xf1, - 0xd2, 0xd9, 0x28, 0x73, 0x47, 0x97, 0x78, 0xac, 0xe7, 0x3d, 0x42, 0x9a, 0x3f, 0x3b, 0x0c, 0xa0, - 0xa5, 0xa2, 0x52, 0x48, 0x56, 0x4f, 0x85, 0xf4, 0xc0, 0x4a, 0xa4, 0xbc, 0x0a, 0x2b, 0x95, 0xfb, - 0x5b, 0x61, 0x65, 0x05, 0xce, 0x4a, 0x73, 0x81, 0x9f, 0x15, 0x5d, 0x0e, 0x62, 0x25, 0xe0, 0xaa, - 0xf5, 0xc7, 0x04, 0xa1, 0xb3, 0xf3, 0x79, 0x48, 0x38, 0xff, 0xd9, 0x94, 0x95, 0x32, 0xb4, 0x9f, - 0x95, 0xa2, 0xd7, 0xf4, 0xc2, 0xba, 0xbc, 0x3d, 0x24, 0xb3, 0xa6, 0x17, 0x2e, 0xad, 0x60, 0x8d, - 0x93, 0x2f, 0xd8, 0x6b, 0x05, 0x09, 0x76, 0x38, 0xb0, 0x60, 0x97, 0x22, 0x66, 0xb8, 0xa7, 0x88, - 0x91, 0x3e, 0xe9, 0x91, 0x9e, 0x3e, 0xe9, 0xf7, 0xc3, 0x98, 0xeb, 0x6f, 0x90, 0xc8, 0x4d, 0x48, - 0x93, 0xad, 0x05, 0x26, 0x7e, 0xaa, 0x5a, 0xad, 0xcf, 0xa7, 0xa0, 0x38, 0x83, 0x9d, 0x96, 0x8b, - 0x63, 0x7d, 0xc8, 0xc5, 0x1e, 0xda, 0xe8, 0x44, 0x31, 0xda, 0xe8, 0xe4, 0xd1, 0xb5, 0xd1, 0xa9, - 0x63, 0xd5, 0x46, 0xa8, 0x10, 0x6d, 0xd4, 0x97, 0xa0, 0x37, 0xb6, 0x7f, 0x67, 0xf6, 0xd9, 0xfe, - 0xf5, 0x52, 0x45, 0x67, 0x0f, 0xad, 0x8a, 0xf2, 0xb5, 0xcc, 0x43, 0x87, 0xd2, 0x32, 0x9f, 0x2b, - 0xc1, 0x59, 0x2d, 0x87, 0xe9, 0xec, 0x77, 0xd7, 0xa9, 0x24, 0x62, 0x17, 0x50, 0xf1, 0x73, 0x1b, - 0x23, 0x39, 0x4a, 0xe7, 0x59, 0x29, 0x08, 0x36, 0xb0, 0x58, 0x8e, 0x11, 0x89, 0x58, 0xb9, 0xdd, - 0xac, 0x90, 0x9e, 0x11, 0xed, 0x58, 0x61, 0xd0, 0xf9, 0x45, 0x7f, 0x8b, 0xbc, 0xcd, 0x6c, 0x51, - 0xb9, 0x19, 0x0d, 0xc2, 0x26, 0x1e, 0x7a, 0x8a, 0x33, 0x61, 0x02, 0x82, 0x0a, 0xea, 0x11, 0x71, - 0x33, 0xae, 0x94, 0x09, 0x0a, 0x2a, 0xbb, 0xc3, 0x92, 0xc9, 0x2a, 0xdd, 0xdd, 0x61, 0x21, 0x50, - 0x0a, 0xc3, 0xfe, 0x1f, 0x16, 0x3c, 0x92, 0x3b, 0x14, 0xf7, 0x40, 0xf9, 0x6e, 0xa7, 0x95, 0xef, - 0x4a, 0x51, 0xdb, 0x0d, 0xe3, 0x2d, 0x7a, 0x28, 0xe2, 0x7f, 0x6b, 0xc1, 0x98, 0xc6, 0xbf, 0x07, - 0xaf, 0xea, 0xa6, 0x5f, 0xb5, 0xb8, 0x9d, 0x55, 0xad, 0xeb, 0xdd, 0x7e, 0xbb, 0x04, 0xaa, 0xd0, - 0xe3, 0x74, 0x43, 0x96, 0xd1, 0xdd, 0xe7, 0x24, 0x71, 0x07, 0x06, 0xd9, 0x41, 0x68, 0x5c, 0x4c, - 0x90, 0x47, 0x9a, 0x3f, 0x3b, 0x54, 0xd5, 0x87, 0xcc, 0xec, 0x6f, 0x8c, 0x05, 0x43, 0x56, 0x0c, - 0xda, 0x8d, 0xa9, 0x34, 0x6f, 0x8a, 0xb4, 0x2c, 0x5d, 0x0c, 0x5a, 0xb4, 0x63, 0x85, 0x41, 0xd5, - 0x83, 0xdb, 0x08, 0xfc, 0x19, 0xcf, 0x89, 0xe5, 0xad, 0x8b, 0x4a, 0x3d, 0xcc, 0x4b, 0x00, 0xd6, - 0x38, 0xec, 0x8c, 0xd4, 0x8d, 0x43, 0xcf, 0xd9, 0x31, 0xf6, 0xcf, 0x46, 0x7d, 0x02, 0x05, 0xc2, - 0x26, 0x9e, 0xdd, 0x86, 0xf1, 0xf4, 0x4b, 0xcc, 0x92, 0x75, 0x16, 0xa0, 0xd8, 0xd7, 0x70, 0x4e, - 0x41, 0xcd, 0x61, 0x4f, 0x2d, 0x74, 0x9c, 0xec, 0xa5, 0xed, 0xd3, 0x12, 0x80, 0x35, 0x8e, 0xfd, - 0xab, 0x16, 0x9c, 0xce, 0x19, 0xb4, 0x02, 0xd3, 0xde, 0x12, 0x2d, 0x6d, 0xf2, 0x14, 0xfb, 0x3b, - 0x61, 0xa8, 0x49, 0xd6, 0x1d, 0x19, 0x02, 0x67, 0xc8, 0xf6, 0x59, 0xde, 0x8c, 0x25, 0xdc, 0xfe, - 0x6f, 0x16, 0x9c, 0x48, 0xf7, 0x35, 0x66, 0xa9, 0x24, 0x7c, 0x98, 0xdc, 0xb8, 0x11, 0x6c, 0x91, - 0x68, 0x87, 0xbe, 0xb9, 0x95, 0x49, 0x25, 0xe9, 0xc2, 0xc0, 0x39, 0x4f, 0xb1, 0x32, 0xaf, 0x4d, - 0x35, 0xda, 0x72, 0x46, 0xde, 0x28, 0x72, 0x46, 0xea, 0x8f, 0x69, 0x1e, 0x97, 0x2b, 0x96, 0xd8, - 0xe4, 0x6f, 0x7f, 0x77, 0x00, 0x54, 0x5e, 0x2c, 0x8b, 0x3f, 0x2a, 0x28, 0x7a, 0xeb, 0xa0, 0x19, - 0x44, 0x6a, 0x32, 0x0c, 0xec, 0x15, 0x10, 0xc0, 0xbd, 0x24, 0xa6, 0xeb, 0x52, 0xbd, 0xe1, 0xaa, - 0x06, 0x61, 0x13, 0x8f, 0xf6, 0xc4, 0x73, 0xb7, 0x08, 0x7f, 0x68, 0x30, 0xdd, 0x93, 0x05, 0x09, - 0xc0, 0x1a, 0x87, 0xf6, 0xa4, 0xe9, 0xae, 0xaf, 0x8b, 0x2d, 0xbf, 0xea, 0x09, 0x1d, 0x1d, 0xcc, - 0x20, 0xbc, 0x72, 0x77, 0xb0, 0x29, 0xac, 0x60, 0xa3, 0x72, 0x77, 0xb0, 0x89, 0x19, 0x84, 0xda, - 0x6d, 0x7e, 0x10, 0xb5, 0xd9, 0xa5, 0xfa, 0x4d, 0xc5, 0x45, 0x58, 0xbf, 0xca, 0x6e, 0xbb, 0xd6, - 0x8d, 0x82, 0xf3, 0x9e, 0xa3, 0x33, 0x30, 0x8c, 0x48, 0xd3, 0x6d, 0x24, 0x26, 0x35, 0x48, 0xcf, - 0xc0, 0xe5, 0x2e, 0x0c, 0x9c, 0xf3, 0x14, 0x9a, 0x86, 0x13, 0x32, 0xaf, 0x59, 0x56, 0xad, 0x19, - 0x4e, 0x57, 0xc9, 0xc0, 0x69, 0x30, 0xce, 0xe2, 0x53, 0xa9, 0xd6, 0x16, 0x85, 0xad, 0x98, 0xb1, - 0x6c, 0x48, 0x35, 0x59, 0xf0, 0x0a, 0x2b, 0x0c, 0xfb, 0x53, 0x65, 0xaa, 0x85, 0x7b, 0x14, 0x74, - 0xbb, 0x67, 0xd1, 0x82, 0xe9, 0x19, 0x39, 0xd0, 0xc7, 0x8c, 0x7c, 0x0e, 0x46, 0x6e, 0xc5, 0x81, - 0xaf, 0x22, 0xf1, 0x2a, 0x3d, 0x23, 0xf1, 0x0c, 0xac, 0xfc, 0x48, 0xbc, 0xc1, 0xa2, 0x22, 0xf1, - 0x86, 0x0e, 0x19, 0x89, 0xf7, 0x3b, 0x15, 0x50, 0x57, 0x88, 0x5c, 0x23, 0xc9, 0xed, 0x20, 0xda, - 0x74, 0xfd, 0x16, 0xcb, 0x07, 0xff, 0x86, 0x05, 0x23, 0x7c, 0xbd, 0x2c, 0x98, 0x99, 0x54, 0xeb, - 0x05, 0xdd, 0x4d, 0x91, 0x62, 0x36, 0xb9, 0x6a, 0x30, 0xca, 0x5c, 0xfa, 0x69, 0x82, 0x70, 0xaa, - 0x47, 0xe8, 0xe3, 0x00, 0xd2, 0x3f, 0xba, 0x2e, 0x45, 0xe6, 0x7c, 0x31, 0xfd, 0xc3, 0x64, 0x5d, - 0xdb, 0xc0, 0xab, 0x8a, 0x09, 0x36, 0x18, 0xa2, 0xcf, 0xe9, 0x2c, 0x33, 0x1e, 0xb2, 0xff, 0xd1, - 0x63, 0x19, 0x9b, 0x7e, 0x72, 0xcc, 0x30, 0x0c, 0xb9, 0x7e, 0x8b, 0xce, 0x13, 0x11, 0xb1, 0xf4, - 0x8e, 0xbc, 0x5a, 0x0a, 0x0b, 0x81, 0xd3, 0xac, 0x3b, 0x9e, 0xe3, 0x37, 0x48, 0x34, 0xcf, 0xd1, - 0xcd, 0xab, 0xae, 0x59, 0x03, 0x96, 0x84, 0xba, 0x2e, 0x5f, 0xa9, 0xf4, 0x73, 0xf9, 0xca, 0xb9, - 0x0f, 0xc0, 0xa9, 0xae, 0x8f, 0x79, 0xa0, 0x94, 0xb2, 0xc3, 0x67, 0xa3, 0xd9, 0xff, 0x74, 0x50, - 0x2b, 0xad, 0x6b, 0x41, 0x93, 0x5f, 0x01, 0x12, 0xe9, 0x2f, 0x2a, 0x6c, 0xdc, 0x02, 0xa7, 0x88, - 0x71, 0x5d, 0xb6, 0x6a, 0xc4, 0x26, 0x4b, 0x3a, 0x47, 0x43, 0x27, 0x22, 0xfe, 0x71, 0xcf, 0xd1, - 0x65, 0xc5, 0x04, 0x1b, 0x0c, 0xd1, 0x46, 0x2a, 0xa7, 0xe4, 0xd2, 0xd1, 0x73, 0x4a, 0x58, 0x95, - 0xa9, 0xbc, 0xaa, 0xfd, 0x5f, 0xb6, 0x60, 0xcc, 0x4f, 0xcd, 0xdc, 0x62, 0xc2, 0x48, 0xf3, 0x57, - 0x05, 0xbf, 0x81, 0x2a, 0xdd, 0x86, 0x33, 0xfc, 0xf3, 0x54, 0x5a, 0xe5, 0x80, 0x2a, 0x4d, 0xdf, - 0x25, 0x34, 0xd8, 0xeb, 0x2e, 0x21, 0xe4, 0xab, 0xcb, 0xd4, 0x86, 0x0a, 0xbf, 0x4c, 0x0d, 0x72, - 0x2e, 0x52, 0xbb, 0x09, 0xb5, 0x46, 0x44, 0x9c, 0xe4, 0x90, 0xf7, 0x6a, 0xb1, 0x03, 0xfa, 0x19, - 0x49, 0x00, 0x6b, 0x5a, 0xf6, 0xff, 0x1e, 0x80, 0x93, 0x72, 0x44, 0x64, 0x08, 0x3a, 0xd5, 0x8f, - 0x9c, 0xaf, 0x36, 0x6e, 0x95, 0x7e, 0xbc, 0x2c, 0x01, 0x58, 0xe3, 0x50, 0x7b, 0xac, 0x13, 0x93, - 0xa5, 0x90, 0xf8, 0x0b, 0xee, 0x5a, 0x2c, 0xce, 0x39, 0xd5, 0x42, 0xb9, 0xae, 0x41, 0xd8, 0xc4, - 0xa3, 0xc6, 0x38, 0xb7, 0x8b, 0xe3, 0x6c, 0xfa, 0x8a, 0xb0, 0xb7, 0xb1, 0x84, 0xa3, 0x5f, 0xc8, - 0xad, 0x30, 0x5b, 0x4c, 0xe2, 0x56, 0x57, 0xe4, 0xfd, 0x01, 0xaf, 0x62, 0xfc, 0x1b, 0x16, 0x9c, - 0xe5, 0xad, 0x72, 0x24, 0xaf, 0x87, 0x4d, 0x27, 0x21, 0x71, 0x31, 0x15, 0xdf, 0x73, 0xfa, 0xa7, - 0x9d, 0xbc, 0x79, 0x6c, 0x71, 0x7e, 0x6f, 0xd0, 0x1b, 0x16, 0x9c, 0xd8, 0x4c, 0xd5, 0xfc, 0x90, - 0xaa, 0xe3, 0xa8, 0xe9, 0xf8, 0x29, 0xa2, 0x7a, 0xa9, 0xa5, 0xdb, 0x63, 0x9c, 0xe5, 0x6e, 0xff, - 0x99, 0x05, 0xa6, 0x18, 0xbd, 0xf7, 0xa5, 0x42, 0x0e, 0x6e, 0x0a, 0x4a, 0xeb, 0xb2, 0xd2, 0xd3, - 0xba, 0x7c, 0x0c, 0xca, 0x1d, 0xb7, 0x29, 0xf6, 0x17, 0xfa, 0xf4, 0x75, 0x7e, 0x16, 0xd3, 0x76, - 0xfb, 0x1f, 0x55, 0xb4, 0xdf, 0x42, 0xe4, 0x45, 0xfd, 0x40, 0xbc, 0xf6, 0xba, 0x2a, 0x36, 0xc6, - 0xdf, 0xfc, 0x5a, 0x57, 0xb1, 0xb1, 0x1f, 0x3f, 0x78, 0xda, 0x1b, 0x1f, 0xa0, 0x5e, 0xb5, 0xc6, - 0x86, 0xf6, 0xc9, 0x79, 0xbb, 0x05, 0x55, 0xba, 0x05, 0x63, 0x0e, 0xc8, 0x6a, 0xaa, 0x53, 0xd5, - 0xcb, 0xa2, 0xfd, 0xee, 0xee, 0xc4, 0x7b, 0x0f, 0xde, 0x2d, 0xf9, 0x34, 0x56, 0xf4, 0x51, 0x0c, - 0x35, 0xfa, 0x9b, 0xa5, 0xe7, 0x89, 0xcd, 0xdd, 0x75, 0x25, 0x33, 0x25, 0xa0, 0x90, 0xdc, 0x3f, - 0xcd, 0x07, 0xf9, 0x50, 0x63, 0xb7, 0xd6, 0x32, 0xa6, 0x7c, 0x0f, 0xb8, 0xac, 0x92, 0xe4, 0x24, - 0xe0, 0xee, 0xee, 0xc4, 0x8b, 0x07, 0x67, 0xaa, 0x1e, 0xc7, 0x9a, 0x85, 0xfd, 0x95, 0x01, 0x3d, - 0x77, 0x45, 0x8d, 0xb9, 0x1f, 0x88, 0xb9, 0xfb, 0x42, 0x66, 0xee, 0x9e, 0xef, 0x9a, 0xbb, 0x63, - 0xfa, 0x76, 0xd5, 0xd4, 0x6c, 0xbc, 0xd7, 0x86, 0xc0, 0xfe, 0xfe, 0x06, 0x66, 0x01, 0xbd, 0xd6, - 0x71, 0x23, 0x12, 0x2f, 0x47, 0x1d, 0xdf, 0xf5, 0x5b, 0x6c, 0x3a, 0x56, 0x4d, 0x0b, 0x28, 0x05, - 0xc6, 0x59, 0x7c, 0xba, 0xa9, 0xa7, 0xdf, 0xfc, 0xa6, 0xb3, 0xc5, 0x67, 0x95, 0x51, 0x76, 0x6b, - 0x45, 0xb4, 0x63, 0x85, 0x61, 0x7f, 0x8b, 0x9d, 0x65, 0x1b, 0x79, 0xc1, 0x74, 0x4e, 0x78, 0xec, - 0x9a, 0x60, 0x5e, 0xb3, 0x4b, 0xcd, 0x09, 0x7e, 0x37, 0x30, 0x87, 0xa1, 0xdb, 0x30, 0xb4, 0xc6, - 0xef, 0xc9, 0x2b, 0xa6, 0x8e, 0xb9, 0xb8, 0x74, 0x8f, 0xdd, 0x86, 0x22, 0x6f, 0xe0, 0xbb, 0xab, - 0x7f, 0x62, 0xc9, 0xcd, 0xfe, 0xfd, 0x0a, 0x9c, 0xc8, 0x5c, 0x24, 0x9b, 0xaa, 0x96, 0x5a, 0xda, - 0xb7, 0x5a, 0xea, 0x47, 0x00, 0x9a, 0x24, 0xf4, 0x82, 0x1d, 0x66, 0x8e, 0x0d, 0x1c, 0xd8, 0x1c, - 0x53, 0x16, 0xfc, 0xac, 0xa2, 0x82, 0x0d, 0x8a, 0xa2, 0x50, 0x19, 0x2f, 0xbe, 0x9a, 0x29, 0x54, - 0x66, 0xdc, 0x76, 0x30, 0x78, 0x6f, 0x6f, 0x3b, 0x70, 0xe1, 0x04, 0xef, 0xa2, 0xca, 0xbe, 0x3d, - 0x44, 0x92, 0x2d, 0xcb, 0x5f, 0x98, 0x4d, 0x93, 0xc1, 0x59, 0xba, 0xf7, 0xf3, 0x9e, 0x68, 0xf4, - 0x2e, 0xa8, 0xc9, 0xef, 0x1c, 0x8f, 0xd7, 0x74, 0x05, 0x03, 0x39, 0x0d, 0xd8, 0xfd, 0xcd, 0xe2, - 0x67, 0x57, 0x21, 0x01, 0xb8, 0x5f, 0x85, 0x04, 0xec, 0x2f, 0x95, 0xa8, 0x1d, 0xcf, 0xfb, 0xa5, - 0x6a, 0xe2, 0x3c, 0x09, 0x83, 0x4e, 0x27, 0xd9, 0x08, 0xba, 0x6e, 0xfd, 0x9b, 0x66, 0xad, 0x58, - 0x40, 0xd1, 0x02, 0x0c, 0x34, 0x75, 0x9d, 0x93, 0x83, 0x7c, 0x4f, 0xed, 0x12, 0x75, 0x12, 0x82, - 0x19, 0x15, 0xf4, 0x28, 0x0c, 0x24, 0x4e, 0x4b, 0xa6, 0x5c, 0xb1, 0x34, 0xdb, 0x55, 0xa7, 0x15, - 0x63, 0xd6, 0x6a, 0xaa, 0xef, 0x81, 0x7d, 0xd4, 0xf7, 0x8b, 0x30, 0x1a, 0xbb, 0x2d, 0xdf, 0x49, - 0x3a, 0x11, 0x31, 0x8e, 0xf9, 0x74, 0xe4, 0x86, 0x09, 0xc4, 0x69, 0x5c, 0xfb, 0x37, 0x47, 0xe0, - 0xcc, 0xca, 0xcc, 0xa2, 0xac, 0xde, 0x7d, 0x6c, 0x59, 0x53, 0x79, 0x3c, 0xee, 0x5d, 0xd6, 0x54, - 0x0f, 0xee, 0x9e, 0x91, 0x35, 0xe5, 0x19, 0x59, 0x53, 0xe9, 0x14, 0x96, 0x72, 0x11, 0x29, 0x2c, - 0x79, 0x3d, 0xe8, 0x27, 0x85, 0xe5, 0xd8, 0xd2, 0xa8, 0xf6, 0xec, 0xd0, 0x81, 0xd2, 0xa8, 0x54, - 0x8e, 0x59, 0x21, 0xc9, 0x05, 0x3d, 0x3e, 0x55, 0x6e, 0x8e, 0x99, 0xca, 0xef, 0xe1, 0x89, 0x33, - 0x42, 0xd4, 0xbf, 0x52, 0x7c, 0x07, 0xfa, 0xc8, 0xef, 0x11, 0xb9, 0x3b, 0x66, 0x4e, 0xd9, 0x50, - 0x11, 0x39, 0x65, 0x79, 0xdd, 0xd9, 0x37, 0xa7, 0xec, 0x45, 0x18, 0x6d, 0x78, 0x81, 0x4f, 0x96, - 0xa3, 0x20, 0x09, 0x1a, 0x81, 0x27, 0xcc, 0x7a, 0x25, 0x12, 0x66, 0x4c, 0x20, 0x4e, 0xe3, 0xf6, - 0x4a, 0x48, 0xab, 0x1d, 0x35, 0x21, 0x0d, 0xee, 0x53, 0x42, 0xda, 0xcf, 0xea, 0xd4, 0xe9, 0x61, - 0xf6, 0x45, 0x3e, 0x52, 0xfc, 0x17, 0xe9, 0x27, 0x7f, 0x1a, 0xbd, 0xc9, 0xaf, 0xdd, 0xa3, 0x86, - 0xf1, 0x4c, 0xd0, 0xa6, 0x86, 0xdf, 0x08, 0x1b, 0x92, 0x57, 0x8f, 0x61, 0xc2, 0xde, 0x5c, 0xd1, - 0x6c, 0xd4, 0x55, 0x7c, 0xba, 0x09, 0xa7, 0x3b, 0x72, 0x94, 0xd4, 0xee, 0xaf, 0x95, 0xe0, 0x87, - 0xf6, 0xed, 0x02, 0xba, 0x0d, 0x90, 0x38, 0x2d, 0x31, 0x51, 0xc5, 0x81, 0xc9, 0x11, 0xc3, 0x2b, - 0x57, 0x25, 0x3d, 0x5e, 0x93, 0x44, 0xfd, 0x65, 0x47, 0x11, 0xf2, 0x37, 0x8b, 0xaa, 0x0c, 0xbc, - 0xae, 0xd2, 0x8d, 0x38, 0xf0, 0x08, 0x66, 0x10, 0xaa, 0xfe, 0x23, 0xd2, 0xd2, 0xf7, 0x44, 0xab, - 0xcf, 0x87, 0x59, 0x2b, 0x16, 0x50, 0xf4, 0x3c, 0x0c, 0x3b, 0x9e, 0xc7, 0xf3, 0x63, 0x48, 0x2c, - 0xee, 0xdd, 0xd1, 0x35, 0xe4, 0x34, 0x08, 0x9b, 0x78, 0xf6, 0x9f, 0x96, 0x60, 0x62, 0x1f, 0x99, - 0xd2, 0x95, 0xf1, 0x57, 0xe9, 0x3b, 0xe3, 0x4f, 0xe4, 0x28, 0x0c, 0xf6, 0xc8, 0x51, 0x78, 0x1e, - 0x86, 0x13, 0xe2, 0xb4, 0x45, 0x40, 0x96, 0xf0, 0x04, 0xe8, 0x13, 0x60, 0x0d, 0xc2, 0x26, 0x1e, - 0x95, 0x62, 0x63, 0x4e, 0xa3, 0x41, 0xe2, 0x58, 0x26, 0x21, 0x08, 0x6f, 0x6a, 0x61, 0x19, 0x0e, - 0xcc, 0x49, 0x3d, 0x9d, 0x62, 0x81, 0x33, 0x2c, 0xb3, 0x03, 0x5e, 0xeb, 0x73, 0xc0, 0xbf, 0x59, - 0x82, 0xc7, 0xf6, 0xd4, 0x6e, 0x7d, 0xe7, 0x87, 0x74, 0x62, 0x12, 0x65, 0x27, 0xce, 0xf5, 0x98, - 0x44, 0x98, 0x41, 0xf8, 0x28, 0x85, 0xa1, 0x71, 0x0f, 0x77, 0xd1, 0xc9, 0x4b, 0x7c, 0x94, 0x52, - 0x2c, 0x70, 0x86, 0xe5, 0x61, 0xa7, 0xe5, 0xdf, 0x29, 0xc1, 0x13, 0x7d, 0xd8, 0x00, 0x05, 0x26, - 0x79, 0xa5, 0x53, 0xed, 0xca, 0xf7, 0x29, 0x23, 0xf2, 0x90, 0xc3, 0xf5, 0xad, 0x12, 0x9c, 0xeb, - 0xad, 0x8a, 0xd1, 0xfb, 0xe0, 0x44, 0xa4, 0xa2, 0xb0, 0xcc, 0x2c, 0xbd, 0xd3, 0xdc, 0x93, 0x90, - 0x02, 0xe1, 0x2c, 0x2e, 0x9a, 0x04, 0x08, 0x9d, 0x64, 0x23, 0xbe, 0xb8, 0xed, 0xc6, 0x89, 0xa8, - 0x42, 0x33, 0xc6, 0xcf, 0xae, 0x64, 0x2b, 0x36, 0x30, 0x28, 0x3b, 0xf6, 0x6f, 0x36, 0xb8, 0x16, - 0x24, 0xfc, 0x21, 0xbe, 0x8d, 0x38, 0x2d, 0xef, 0xec, 0x30, 0x40, 0x38, 0x8b, 0x4b, 0xd9, 0xb1, - 0xd3, 0x51, 0xde, 0x51, 0xbe, 0xbf, 0x60, 0xec, 0x16, 0x54, 0x2b, 0x36, 0x30, 0xb2, 0xf9, 0x87, - 0x95, 0xfd, 0xf3, 0x0f, 0xed, 0x7f, 0x58, 0x82, 0x47, 0x7a, 0x9a, 0x72, 0xfd, 0x2d, 0xc0, 0x07, - 0x2f, 0x67, 0xf0, 0x70, 0x73, 0xe7, 0x80, 0xb9, 0x6d, 0x7f, 0xdc, 0x63, 0xa6, 0x89, 0xdc, 0xb6, - 0xc3, 0x27, 0x87, 0x3f, 0x78, 0xe3, 0xd9, 0x95, 0xce, 0x36, 0x70, 0x80, 0x74, 0xb6, 0xcc, 0xc7, - 0xa8, 0xf4, 0xb9, 0x90, 0xff, 0xbc, 0xdc, 0x73, 0x78, 0xe9, 0xd6, 0xaf, 0x2f, 0x3f, 0xed, 0x2c, - 0x9c, 0x74, 0x7d, 0x76, 0x7f, 0xd3, 0x4a, 0x67, 0x4d, 0x14, 0x26, 0x29, 0xa5, 0x6f, 0x59, 0x9f, - 0xcf, 0xc0, 0x71, 0xd7, 0x13, 0x0f, 0x60, 0x7a, 0xe1, 0xe1, 0x86, 0xf4, 0x60, 0x09, 0xae, 0x68, - 0x09, 0xce, 0xca, 0xa1, 0xd8, 0x70, 0x22, 0xd2, 0x14, 0x6a, 0x24, 0x16, 0x09, 0x15, 0x8f, 0xf0, - 0xa4, 0x8c, 0x1c, 0x04, 0x9c, 0xff, 0x1c, 0xbb, 0x32, 0x27, 0x08, 0xdd, 0x86, 0xd8, 0xe4, 0xe8, - 0x2b, 0x73, 0x68, 0x23, 0xe6, 0x30, 0xfb, 0x23, 0x50, 0x53, 0xef, 0xcf, 0xc3, 0xba, 0xd5, 0xa4, - 0xeb, 0x0a, 0xeb, 0x56, 0x33, 0xce, 0xc0, 0xa2, 0x5f, 0x8b, 0x9a, 0xc4, 0x99, 0xd5, 0x73, 0x95, - 0xec, 0x30, 0xfb, 0xd8, 0x7e, 0x37, 0x8c, 0x28, 0x3f, 0x4b, 0xbf, 0x17, 0x09, 0xd9, 0x5f, 0x19, - 0x84, 0xd1, 0x54, 0x71, 0xc0, 0x94, 0x83, 0xd5, 0xda, 0xd7, 0xc1, 0xca, 0xc2, 0xf4, 0x3b, 0xbe, - 0xbc, 0x65, 0xcc, 0x08, 0xd3, 0xef, 0xf8, 0x04, 0x73, 0x18, 0x35, 0x6f, 0x9b, 0xd1, 0x0e, 0xee, - 0xf8, 0x22, 0x9c, 0x56, 0x99, 0xb7, 0xb3, 0xac, 0x15, 0x0b, 0x28, 0xfa, 0xa4, 0x05, 0x23, 0x31, - 0xf3, 0xde, 0x73, 0xf7, 0xb4, 0x98, 0x74, 0x57, 0x8e, 0x5e, 0xfb, 0x50, 0x15, 0xc2, 0x64, 0x11, - 0x32, 0x66, 0x0b, 0x4e, 0x71, 0x44, 0x9f, 0xb1, 0xa0, 0xa6, 0x2e, 0x43, 0x11, 0x57, 0x06, 0xae, - 0x14, 0x5b, 0x7b, 0x91, 0xfb, 0x35, 0xd5, 0x41, 0x88, 0x2a, 0x82, 0x87, 0x35, 0x63, 0x14, 0x2b, - 0xdf, 0xf1, 0xd0, 0xf1, 0xf8, 0x8e, 0x21, 0xc7, 0x6f, 0xfc, 0x2e, 0xa8, 0xb5, 0x1d, 0xdf, 0x5d, - 0x27, 0x71, 0xc2, 0xdd, 0xb9, 0xb2, 0x24, 0xac, 0x6c, 0xc4, 0x1a, 0x4e, 0x15, 0x72, 0xcc, 0x5e, - 0x2c, 0x31, 0xfc, 0xaf, 0x4c, 0x21, 0xaf, 0xe8, 0x66, 0x6c, 0xe2, 0x98, 0xce, 0x62, 0xb8, 0xaf, - 0xce, 0xe2, 0xe1, 0xbd, 0x9d, 0xc5, 0xf6, 0xdf, 0xb3, 0xe0, 0x6c, 0xee, 0x57, 0x7b, 0x70, 0x03, - 0x1f, 0xed, 0xaf, 0x56, 0xe0, 0x74, 0x4e, 0x95, 0x4f, 0xb4, 0x63, 0xce, 0x67, 0xab, 0x88, 0x18, - 0x82, 0xf4, 0x91, 0xb8, 0x1c, 0xc6, 0x9c, 0x49, 0x7c, 0xb0, 0xa3, 0x1a, 0x7d, 0x5c, 0x52, 0xbe, - 0xb7, 0xc7, 0x25, 0xc6, 0xb4, 0x1c, 0xb8, 0xaf, 0xd3, 0xb2, 0xb2, 0xcf, 0x19, 0xc6, 0xaf, 0x59, - 0x30, 0xde, 0xee, 0x51, 0x5a, 0x5e, 0x38, 0x1e, 0x6f, 0x1c, 0x4f, 0xe1, 0xfa, 0xfa, 0xa3, 0x77, - 0x76, 0x27, 0x7a, 0x56, 0xf4, 0xc7, 0x3d, 0x7b, 0x65, 0x7f, 0xb7, 0x0c, 0xac, 0xc4, 0x2c, 0xab, - 0xe4, 0xb6, 0x83, 0x3e, 0x61, 0x16, 0x0b, 0xb6, 0x8a, 0x2a, 0x6c, 0xcb, 0x89, 0xab, 0x62, 0xc3, - 0x7c, 0x04, 0xf3, 0x6a, 0x0f, 0x67, 0x85, 0x56, 0xa9, 0x0f, 0xa1, 0xe5, 0xc9, 0xaa, 0xcc, 0xe5, - 0xe2, 0xab, 0x32, 0xd7, 0xb2, 0x15, 0x99, 0xf7, 0xfe, 0xc4, 0x03, 0x0f, 0xe4, 0x27, 0xfe, 0x45, - 0x8b, 0x0b, 0x9e, 0xcc, 0x57, 0xd0, 0x96, 0x81, 0xb5, 0x87, 0x65, 0xf0, 0x34, 0x54, 0x63, 0xe2, - 0xad, 0x5f, 0x26, 0x8e, 0x27, 0x2c, 0x08, 0x7d, 0x7e, 0x2d, 0xda, 0xb1, 0xc2, 0x60, 0xd7, 0xb6, - 0x7a, 0x5e, 0x70, 0xfb, 0x62, 0x3b, 0x4c, 0x76, 0x84, 0x2d, 0xa1, 0xaf, 0x6d, 0x55, 0x10, 0x6c, - 0x60, 0xd9, 0x7f, 0xbd, 0xc4, 0x67, 0xa0, 0x08, 0x82, 0x78, 0x21, 0x73, 0xd1, 0x5e, 0xff, 0xf1, - 0x03, 0x1f, 0x03, 0x68, 0xa8, 0xab, 0xec, 0xc5, 0x99, 0xd0, 0xe5, 0x23, 0xdf, 0xb3, 0x2d, 0xe8, - 0xe9, 0xd7, 0xd0, 0x6d, 0xd8, 0xe0, 0x97, 0x92, 0xa5, 0xe5, 0x7d, 0x65, 0x69, 0x4a, 0xac, 0x0c, - 0xec, 0xa3, 0xed, 0xfe, 0xd4, 0x82, 0x94, 0x45, 0x84, 0x42, 0xa8, 0xd0, 0xee, 0xee, 0x14, 0x73, - 0x4b, 0xbf, 0x49, 0x9a, 0x8a, 0x46, 0x31, 0xed, 0xd9, 0x4f, 0xcc, 0x19, 0x21, 0x4f, 0xc4, 0x4a, - 0xf0, 0x51, 0xbd, 0x56, 0x1c, 0xc3, 0xcb, 0x41, 0xb0, 0xc9, 0x0f, 0x36, 0x75, 0xdc, 0x85, 0xfd, - 0x02, 0x9c, 0xea, 0xea, 0x14, 0xbb, 0x53, 0x2b, 0xa0, 0xda, 0x27, 0x33, 0x5d, 0x59, 0x02, 0x27, - 0xe6, 0x30, 0xfb, 0x5b, 0x16, 0x9c, 0xcc, 0x92, 0x47, 0x6f, 0x5a, 0x70, 0x2a, 0xce, 0xd2, 0x3b, - 0xae, 0xb1, 0x53, 0xf1, 0x8e, 0x5d, 0x20, 0xdc, 0xdd, 0x09, 0xfb, 0xff, 0x88, 0xc9, 0x7f, 0xd3, - 0xf5, 0x9b, 0xc1, 0x6d, 0x65, 0x98, 0x58, 0x3d, 0x0d, 0x13, 0xba, 0x1e, 0x1b, 0x1b, 0xa4, 0xd9, - 0xf1, 0xba, 0x32, 0x47, 0x57, 0x44, 0x3b, 0x56, 0x18, 0x2c, 0x51, 0xae, 0x23, 0xca, 0xb6, 0x67, - 0x26, 0xe5, 0xac, 0x68, 0xc7, 0x0a, 0x03, 0x3d, 0x07, 0x23, 0xc6, 0x4b, 0xca, 0x79, 0xc9, 0x0c, - 0x72, 0x43, 0x65, 0xc6, 0x38, 0x85, 0x85, 0x26, 0x01, 0x94, 0x91, 0x23, 0x55, 0x24, 0x73, 0x14, - 0x29, 0x49, 0x14, 0x63, 0x03, 0x83, 0xa5, 0xa5, 0x7a, 0x9d, 0x98, 0xf9, 0xf8, 0x07, 0x75, 0x29, - 0xd1, 0x19, 0xd1, 0x86, 0x15, 0x94, 0x4a, 0x93, 0xb6, 0xe3, 0x77, 0x1c, 0x8f, 0x8e, 0x90, 0xd8, - 0xfa, 0xa9, 0x65, 0xb8, 0xa8, 0x20, 0xd8, 0xc0, 0xa2, 0x6f, 0x9c, 0xb8, 0x6d, 0xf2, 0x72, 0xe0, - 0xcb, 0x38, 0x35, 0x7d, 0xec, 0x23, 0xda, 0xb1, 0xc2, 0xb0, 0xff, 0x8b, 0x05, 0x27, 0x74, 0x92, - 0x3b, 0xbf, 0x3d, 0xdb, 0xdc, 0xa9, 0x5a, 0xfb, 0xee, 0x54, 0xd3, 0xd9, 0xbf, 0xa5, 0xbe, 0xb2, - 0x7f, 0xcd, 0xc4, 0xdc, 0xf2, 0x9e, 0x89, 0xb9, 0x3f, 0xa2, 0x6f, 0x66, 0xe5, 0x19, 0xbc, 0xc3, - 0x79, 0xb7, 0xb2, 0x22, 0x1b, 0x06, 0x1b, 0x8e, 0xaa, 0xf0, 0x32, 0xc2, 0xf7, 0x0e, 0x33, 0xd3, - 0x0c, 0x49, 0x40, 0xec, 0x25, 0xa8, 0xa9, 0xd3, 0x0f, 0xb9, 0x51, 0xb5, 0xf2, 0x37, 0xaa, 0x7d, - 0x25, 0x08, 0xd6, 0xd7, 0xbe, 0xfd, 0xbd, 0xc7, 0xdf, 0xf6, 0x7b, 0xdf, 0x7b, 0xfc, 0x6d, 0x7f, - 0xf4, 0xbd, 0xc7, 0xdf, 0xf6, 0xc9, 0x3b, 0x8f, 0x5b, 0xdf, 0xbe, 0xf3, 0xb8, 0xf5, 0x7b, 0x77, - 0x1e, 0xb7, 0xfe, 0xe8, 0xce, 0xe3, 0xd6, 0x77, 0xef, 0x3c, 0x6e, 0x7d, 0xf9, 0x3f, 0x3e, 0xfe, - 0xb6, 0x97, 0x73, 0x03, 0x15, 0xe9, 0x8f, 0x67, 0x1a, 0xcd, 0xa9, 0xad, 0x0b, 0x2c, 0x56, 0x8e, - 0x2e, 0xaf, 0x29, 0x63, 0x4e, 0x4d, 0xc9, 0xe5, 0xf5, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x9f, - 0x9a, 0x22, 0xa4, 0x1b, 0xe3, 0x00, 0x00, + // 11357 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x70, 0x1c, 0xc9, + 0x75, 0x98, 0x66, 0x17, 0x0b, 0xec, 0x3e, 0x7c, 0x11, 0x4d, 0xf2, 0x0e, 0xa4, 0xee, 0x0e, 0xf4, + 0x9c, 0x7d, 0x3a, 0x45, 0x77, 0x80, 0x8f, 0xba, 0x93, 0x2f, 0x3a, 0x4b, 0x32, 0x3e, 0x48, 0x10, + 0x24, 0x40, 0xe0, 0x1a, 0x20, 0x29, 0x9d, 0x7c, 0x3a, 0x0d, 0x66, 0x1b, 0x8b, 0x21, 0x66, 0x67, + 0xf6, 0x66, 0x66, 0x41, 0xe2, 0x2c, 0xc9, 0x92, 0x25, 0xd9, 0x72, 0xf4, 0x71, 0x8a, 0x94, 0xaa, + 0x9c, 0x13, 0x4b, 0x91, 0x2d, 0x27, 0x95, 0x54, 0x4a, 0x15, 0x25, 0xf9, 0x11, 0x27, 0xb6, 0xcb, + 0x15, 0x3b, 0xe5, 0x52, 0xe2, 0xa4, 0xec, 0x52, 0xa9, 0x2c, 0x25, 0xb1, 0x11, 0x89, 0x71, 0x2a, + 0xa9, 0xfc, 0x70, 0x55, 0x9c, 0xfc, 0x48, 0x31, 0xf9, 0x91, 0xea, 0xef, 0x9e, 0xd9, 0x59, 0x60, + 0x41, 0x0c, 0x40, 0x4a, 0xb9, 0x7f, 0xbb, 0xfd, 0x5e, 0xf7, 0xeb, 0xe9, 0x8f, 0xf7, 0x5e, 0xbf, + 0x7e, 0xef, 0x35, 0x2c, 0x36, 0xbc, 0x64, 0xb3, 0xbd, 0x3e, 0xe9, 0x86, 0xcd, 0x29, 0x27, 0x6a, + 0x84, 0xad, 0x28, 0xbc, 0xc9, 0x7e, 0x3c, 0xed, 0xd6, 0xa7, 0xb6, 0xcf, 0x4f, 0xb5, 0xb6, 0x1a, + 0x53, 0x4e, 0xcb, 0x8b, 0xa7, 0x9c, 0x56, 0xcb, 0xf7, 0x5c, 0x27, 0xf1, 0xc2, 0x60, 0x6a, 0xfb, + 0x19, 0xc7, 0x6f, 0x6d, 0x3a, 0xcf, 0x4c, 0x35, 0x48, 0x40, 0x22, 0x27, 0x21, 0xf5, 0xc9, 0x56, + 0x14, 0x26, 0x21, 0xfa, 0x69, 0xdd, 0xda, 0xa4, 0x6c, 0x8d, 0xfd, 0x78, 0xc5, 0xad, 0x4f, 0x6e, + 0x9f, 0x9f, 0x6c, 0x6d, 0x35, 0x26, 0x69, 0x6b, 0x93, 0x46, 0x6b, 0x93, 0xb2, 0xb5, 0xb3, 0x4f, + 0x1b, 0x7d, 0x69, 0x84, 0x8d, 0x70, 0x8a, 0x35, 0xba, 0xde, 0xde, 0x60, 0xff, 0xd8, 0x1f, 0xf6, + 0x8b, 0x13, 0x3b, 0x6b, 0x6f, 0x3d, 0x1f, 0x4f, 0x7a, 0x21, 0xed, 0xde, 0x94, 0x1b, 0x46, 0x64, + 0x6a, 0xbb, 0xa3, 0x43, 0x67, 0x2f, 0x69, 0x1c, 0x72, 0x3b, 0x21, 0x41, 0xec, 0x85, 0x41, 0xfc, + 0x34, 0xed, 0x02, 0x89, 0xb6, 0x49, 0x64, 0x7e, 0x9e, 0x81, 0x90, 0xd7, 0xd2, 0xb3, 0xba, 0xa5, + 0xa6, 0xe3, 0x6e, 0x7a, 0x01, 0x89, 0x76, 0x74, 0xf5, 0x26, 0x49, 0x9c, 0xbc, 0x5a, 0x53, 0xdd, + 0x6a, 0x45, 0xed, 0x20, 0xf1, 0x9a, 0xa4, 0xa3, 0xc2, 0xbb, 0xf6, 0xab, 0x10, 0xbb, 0x9b, 0xa4, + 0xe9, 0x74, 0xd4, 0x7b, 0x67, 0xb7, 0x7a, 0xed, 0xc4, 0xf3, 0xa7, 0xbc, 0x20, 0x89, 0x93, 0x28, + 0x5b, 0xc9, 0xfe, 0x55, 0x0b, 0x86, 0xa7, 0x6f, 0xac, 0x4e, 0xb7, 0x93, 0xcd, 0xd9, 0x30, 0xd8, + 0xf0, 0x1a, 0xe8, 0x39, 0x18, 0x74, 0xfd, 0x76, 0x9c, 0x90, 0xe8, 0xaa, 0xd3, 0x24, 0xe3, 0xd6, + 0x39, 0xeb, 0xc9, 0xda, 0xcc, 0xc9, 0x6f, 0xed, 0x4e, 0xbc, 0xe5, 0xce, 0xee, 0xc4, 0xe0, 0xac, + 0x06, 0x61, 0x13, 0x0f, 0xbd, 0x1d, 0x06, 0xa2, 0xd0, 0x27, 0xd3, 0xf8, 0xea, 0x78, 0x89, 0x55, + 0x19, 0x15, 0x55, 0x06, 0x30, 0x2f, 0xc6, 0x12, 0x4e, 0x51, 0x5b, 0x51, 0xb8, 0xe1, 0xf9, 0x64, + 0xbc, 0x9c, 0x46, 0x5d, 0xe1, 0xc5, 0x58, 0xc2, 0xed, 0x3f, 0x29, 0x01, 0x4c, 0xb7, 0x5a, 0x2b, + 0x51, 0x78, 0x93, 0xb8, 0x09, 0xfa, 0x30, 0x54, 0xe9, 0x30, 0xd7, 0x9d, 0xc4, 0x61, 0x1d, 0x1b, + 0x3c, 0xff, 0x93, 0x93, 0xfc, 0xab, 0x27, 0xcd, 0xaf, 0xd6, 0x8b, 0x8c, 0x62, 0x4f, 0x6e, 0x3f, + 0x33, 0xb9, 0xbc, 0x4e, 0xeb, 0x2f, 0x91, 0xc4, 0x99, 0x41, 0x82, 0x18, 0xe8, 0x32, 0xac, 0x5a, + 0x45, 0x01, 0xf4, 0xc5, 0x2d, 0xe2, 0xb2, 0x6f, 0x18, 0x3c, 0xbf, 0x38, 0x79, 0x98, 0xd5, 0x3c, + 0xa9, 0x7b, 0xbe, 0xda, 0x22, 0xee, 0xcc, 0x90, 0xa0, 0xdc, 0x47, 0xff, 0x61, 0x46, 0x07, 0x6d, + 0x43, 0x7f, 0x9c, 0x38, 0x49, 0x3b, 0x66, 0x43, 0x31, 0x78, 0xfe, 0x6a, 0x61, 0x14, 0x59, 0xab, + 0x33, 0x23, 0x82, 0x66, 0x3f, 0xff, 0x8f, 0x05, 0x35, 0xfb, 0xcf, 0x2c, 0x18, 0xd1, 0xc8, 0x8b, + 0x5e, 0x9c, 0xa0, 0x9f, 0xed, 0x18, 0xdc, 0xc9, 0xde, 0x06, 0x97, 0xd6, 0x66, 0x43, 0x7b, 0x42, + 0x10, 0xab, 0xca, 0x12, 0x63, 0x60, 0x9b, 0x50, 0xf1, 0x12, 0xd2, 0x8c, 0xc7, 0x4b, 0xe7, 0xca, + 0x4f, 0x0e, 0x9e, 0xbf, 0x54, 0xd4, 0x77, 0xce, 0x0c, 0x0b, 0xa2, 0x95, 0x05, 0xda, 0x3c, 0xe6, + 0x54, 0xec, 0xbf, 0x1c, 0x36, 0xbf, 0x8f, 0x0e, 0x38, 0x7a, 0x06, 0x06, 0xe3, 0xb0, 0x1d, 0xb9, + 0x04, 0x93, 0x56, 0x18, 0x8f, 0x5b, 0xe7, 0xca, 0x74, 0xe9, 0xd1, 0x45, 0xbd, 0xaa, 0x8b, 0xb1, + 0x89, 0x83, 0xbe, 0x60, 0xc1, 0x50, 0x9d, 0xc4, 0x89, 0x17, 0x30, 0xfa, 0xb2, 0xf3, 0x6b, 0x87, + 0xee, 0xbc, 0x2c, 0x9c, 0xd3, 0x8d, 0xcf, 0x9c, 0x12, 0x1f, 0x32, 0x64, 0x14, 0xc6, 0x38, 0x45, + 0x9f, 0x6e, 0xce, 0x3a, 0x89, 0xdd, 0xc8, 0x6b, 0xd1, 0xff, 0x62, 0xfb, 0xa8, 0xcd, 0x39, 0xa7, + 0x41, 0xd8, 0xc4, 0x43, 0x01, 0x54, 0xe8, 0xe6, 0x8b, 0xc7, 0xfb, 0x58, 0xff, 0x17, 0x0e, 0xd7, + 0x7f, 0x31, 0xa8, 0x74, 0x5f, 0xeb, 0xd1, 0xa7, 0xff, 0x62, 0xcc, 0xc9, 0xa0, 0xcf, 0x5b, 0x30, + 0x2e, 0x98, 0x03, 0x26, 0x7c, 0x40, 0x6f, 0x6c, 0x7a, 0x09, 0xf1, 0xbd, 0x38, 0x19, 0xaf, 0xb0, + 0x3e, 0x4c, 0xf5, 0xb6, 0xb6, 0xe6, 0xa3, 0xb0, 0xdd, 0xba, 0xe2, 0x05, 0xf5, 0x99, 0x73, 0x82, + 0xd2, 0xf8, 0x6c, 0x97, 0x86, 0x71, 0x57, 0x92, 0xe8, 0xcb, 0x16, 0x9c, 0x0d, 0x9c, 0x26, 0x89, + 0x5b, 0x0e, 0x9d, 0x5a, 0x0e, 0x9e, 0xf1, 0x1d, 0x77, 0x8b, 0xf5, 0xa8, 0xff, 0xde, 0x7a, 0x64, + 0x8b, 0x1e, 0x9d, 0xbd, 0xda, 0xb5, 0x69, 0xbc, 0x07, 0x59, 0xf4, 0x75, 0x0b, 0xc6, 0xc2, 0xa8, + 0xb5, 0xe9, 0x04, 0xa4, 0x2e, 0xa1, 0xf1, 0xf8, 0x00, 0xdb, 0x7a, 0x1f, 0x3a, 0xdc, 0x14, 0x2d, + 0x67, 0x9b, 0x5d, 0x0a, 0x03, 0x2f, 0x09, 0xa3, 0x55, 0x92, 0x24, 0x5e, 0xd0, 0x88, 0x67, 0x4e, + 0xdf, 0xd9, 0x9d, 0x18, 0xeb, 0xc0, 0xc2, 0x9d, 0xfd, 0x41, 0x3f, 0x07, 0x83, 0xf1, 0x4e, 0xe0, + 0xde, 0xf0, 0x82, 0x7a, 0x78, 0x2b, 0x1e, 0xaf, 0x16, 0xb1, 0x7d, 0x57, 0x55, 0x83, 0x62, 0x03, + 0x6a, 0x02, 0xd8, 0xa4, 0x96, 0x3f, 0x71, 0x7a, 0x29, 0xd5, 0x8a, 0x9e, 0x38, 0xbd, 0x98, 0xf6, + 0x20, 0x8b, 0x7e, 0xc9, 0x82, 0xe1, 0xd8, 0x6b, 0x04, 0x4e, 0xd2, 0x8e, 0xc8, 0x15, 0xb2, 0x13, + 0x8f, 0x03, 0xeb, 0xc8, 0xe5, 0x43, 0x8e, 0x8a, 0xd1, 0xe4, 0xcc, 0x69, 0xd1, 0xc7, 0x61, 0xb3, + 0x34, 0xc6, 0x69, 0xba, 0x79, 0x1b, 0x4d, 0x2f, 0xeb, 0xc1, 0x62, 0x37, 0x9a, 0x5e, 0xd4, 0x5d, + 0x49, 0xa2, 0x9f, 0x81, 0x13, 0xbc, 0x48, 0x8d, 0x6c, 0x3c, 0x3e, 0xc4, 0x18, 0xed, 0xa9, 0x3b, + 0xbb, 0x13, 0x27, 0x56, 0x33, 0x30, 0xdc, 0x81, 0x8d, 0x5e, 0x85, 0x89, 0x16, 0x89, 0x9a, 0x5e, + 0xb2, 0x1c, 0xf8, 0x3b, 0x92, 0x7d, 0xbb, 0x61, 0x8b, 0xd4, 0x45, 0x77, 0xe2, 0xf1, 0xe1, 0x73, + 0xd6, 0x93, 0xd5, 0x99, 0xb7, 0x89, 0x6e, 0x4e, 0xac, 0xec, 0x8d, 0x8e, 0xf7, 0x6b, 0x0f, 0xfd, + 0x81, 0x05, 0x67, 0x0d, 0x2e, 0xbb, 0x4a, 0xa2, 0x6d, 0xcf, 0x25, 0xd3, 0xae, 0x1b, 0xb6, 0x83, + 0x24, 0x1e, 0x1f, 0x61, 0xc3, 0xb8, 0x7e, 0x14, 0x3c, 0x3f, 0x4d, 0x4a, 0xaf, 0xcb, 0xae, 0x28, + 0x31, 0xde, 0xa3, 0xa7, 0xf6, 0xbf, 0x2e, 0xc1, 0x89, 0xac, 0x06, 0x80, 0xfe, 0x9e, 0x05, 0xa3, + 0x37, 0x6f, 0x25, 0x6b, 0xe1, 0x16, 0x09, 0xe2, 0x99, 0x1d, 0xca, 0xa7, 0x99, 0xec, 0x1b, 0x3c, + 0xef, 0x16, 0xab, 0x6b, 0x4c, 0x5e, 0x4e, 0x53, 0xb9, 0x10, 0x24, 0xd1, 0xce, 0xcc, 0xc3, 0xe2, + 0x9b, 0x46, 0x2f, 0xdf, 0x58, 0x33, 0xa1, 0x38, 0xdb, 0xa9, 0xb3, 0x9f, 0xb5, 0xe0, 0x54, 0x5e, + 0x13, 0xe8, 0x04, 0x94, 0xb7, 0xc8, 0x0e, 0xd7, 0x44, 0x31, 0xfd, 0x89, 0x5e, 0x86, 0xca, 0xb6, + 0xe3, 0xb7, 0x89, 0x50, 0xd3, 0xe6, 0x0f, 0xf7, 0x21, 0xaa, 0x67, 0x98, 0xb7, 0xfa, 0xee, 0xd2, + 0xf3, 0x96, 0xfd, 0x47, 0x65, 0x18, 0x34, 0x26, 0xed, 0x18, 0x54, 0xcf, 0x30, 0xa5, 0x7a, 0x2e, + 0x15, 0xb6, 0xde, 0xba, 0xea, 0x9e, 0xb7, 0x32, 0xba, 0xe7, 0x72, 0x71, 0x24, 0xf7, 0x54, 0x3e, + 0x51, 0x02, 0xb5, 0xb0, 0x45, 0x8f, 0x21, 0x54, 0x87, 0xe9, 0x2b, 0x62, 0x0a, 0x97, 0x65, 0x73, + 0x33, 0xc3, 0x77, 0x76, 0x27, 0x6a, 0xea, 0x2f, 0xd6, 0x84, 0xec, 0xef, 0x5a, 0x70, 0xca, 0xe8, + 0xe3, 0x6c, 0x18, 0xd4, 0x3d, 0x36, 0xb5, 0xe7, 0xa0, 0x2f, 0xd9, 0x69, 0xc9, 0xa3, 0x8e, 0x1a, + 0xa9, 0xb5, 0x9d, 0x16, 0xc1, 0x0c, 0x42, 0x4f, 0x2c, 0x4d, 0x12, 0xc7, 0x4e, 0x83, 0x64, 0x0f, + 0x37, 0x4b, 0xbc, 0x18, 0x4b, 0x38, 0x8a, 0x00, 0xf9, 0x4e, 0x9c, 0xac, 0x45, 0x4e, 0x10, 0xb3, + 0xe6, 0xd7, 0xbc, 0x26, 0x11, 0x03, 0xfc, 0x57, 0x7a, 0x5b, 0x31, 0xb4, 0xc6, 0xcc, 0x43, 0x77, + 0x76, 0x27, 0xd0, 0x62, 0x47, 0x4b, 0x38, 0xa7, 0x75, 0xfb, 0xcb, 0x16, 0x3c, 0x94, 0xcf, 0x60, + 0xd0, 0x13, 0xd0, 0xcf, 0xcf, 0xb9, 0xe2, 0xeb, 0xf4, 0x94, 0xb0, 0x52, 0x2c, 0xa0, 0x68, 0x0a, + 0x6a, 0x4a, 0xe0, 0x89, 0x6f, 0x1c, 0x13, 0xa8, 0x35, 0x2d, 0x25, 0x35, 0x0e, 0x1d, 0x34, 0xfa, + 0x47, 0xa8, 0xa0, 0x6a, 0xd0, 0xd8, 0xc1, 0x90, 0x41, 0xec, 0xef, 0x58, 0xf0, 0xe3, 0xbd, 0xb0, + 0xbd, 0xa3, 0xeb, 0xe3, 0x2a, 0x9c, 0xae, 0x93, 0x0d, 0xa7, 0xed, 0x27, 0x69, 0x8a, 0xa2, 0xd3, + 0x8f, 0x8a, 0xca, 0xa7, 0xe7, 0xf2, 0x90, 0x70, 0x7e, 0x5d, 0xfb, 0x3f, 0x59, 0x30, 0x6a, 0x7c, + 0xd6, 0x31, 0x1c, 0x9d, 0x82, 0xf4, 0xd1, 0x69, 0xa1, 0xb0, 0x6d, 0xda, 0xe5, 0xec, 0xf4, 0x79, + 0x0b, 0xce, 0x1a, 0x58, 0x4b, 0x4e, 0xe2, 0x6e, 0x5e, 0xb8, 0xdd, 0x8a, 0x48, 0x1c, 0xd3, 0x25, + 0xf5, 0xa8, 0xc1, 0x8e, 0x67, 0x06, 0x45, 0x0b, 0xe5, 0x2b, 0x64, 0x87, 0xf3, 0xe6, 0xa7, 0xa0, + 0xca, 0xf7, 0x5c, 0x18, 0x89, 0x49, 0x52, 0xdf, 0xb6, 0x2c, 0xca, 0xb1, 0xc2, 0x40, 0x36, 0xf4, + 0x33, 0x9e, 0x4b, 0x79, 0x10, 0x55, 0x13, 0x80, 0xce, 0xfb, 0x75, 0x56, 0x82, 0x05, 0xc4, 0x8e, + 0x53, 0xdd, 0x59, 0x89, 0x08, 0x5b, 0x0f, 0xf5, 0x8b, 0x1e, 0xf1, 0xeb, 0x31, 0x3d, 0xd6, 0x39, + 0x41, 0x10, 0x26, 0xe2, 0x84, 0x66, 0x1c, 0xeb, 0xa6, 0x75, 0x31, 0x36, 0x71, 0x28, 0x51, 0xdf, + 0x59, 0x27, 0x3e, 0x1f, 0x51, 0x41, 0x74, 0x91, 0x95, 0x60, 0x01, 0xb1, 0xef, 0x94, 0xd8, 0x01, + 0x52, 0x71, 0x34, 0x72, 0x1c, 0xd6, 0x87, 0x28, 0x25, 0x02, 0x56, 0x8a, 0xe3, 0xc7, 0xa4, 0xbb, + 0x05, 0xe2, 0xb5, 0x8c, 0x14, 0xc0, 0x85, 0x52, 0xdd, 0xdb, 0x0a, 0xf1, 0xf1, 0x32, 0x4c, 0xa4, + 0x2b, 0x74, 0x08, 0x11, 0x7a, 0xe4, 0x35, 0x08, 0x65, 0xed, 0x51, 0x06, 0x3e, 0x36, 0xf1, 0xba, + 0xf0, 0xe1, 0xd2, 0x51, 0xf2, 0x61, 0x53, 0x4c, 0x94, 0xf7, 0x11, 0x13, 0x4f, 0xa8, 0x51, 0xef, + 0xcb, 0xf0, 0xbc, 0xb4, 0xa8, 0x3c, 0x07, 0x7d, 0x71, 0x42, 0x5a, 0xe3, 0x95, 0x34, 0x9b, 0x5d, + 0x4d, 0x48, 0x0b, 0x33, 0x08, 0x7a, 0x0f, 0x8c, 0x26, 0x4e, 0xd4, 0x20, 0x49, 0x44, 0xb6, 0x3d, + 0x66, 0xbb, 0x64, 0xe7, 0xd9, 0xda, 0xcc, 0x49, 0xaa, 0x75, 0xad, 0x31, 0x10, 0x96, 0x20, 0x9c, + 0xc5, 0xb5, 0xff, 0x7b, 0x09, 0x1e, 0x4e, 0x4f, 0x81, 0x16, 0x8c, 0xef, 0x4b, 0x09, 0xc6, 0x77, + 0x98, 0x82, 0xf1, 0xee, 0xee, 0xc4, 0x5b, 0xbb, 0x54, 0xfb, 0xa1, 0x91, 0x9b, 0x68, 0x3e, 0x33, + 0x09, 0x53, 0xe9, 0x49, 0xb8, 0xbb, 0x3b, 0xf1, 0x68, 0x97, 0x6f, 0xcc, 0xcc, 0xd2, 0x13, 0xd0, + 0x1f, 0x11, 0x27, 0x0e, 0x03, 0x31, 0x4f, 0x6a, 0x36, 0x31, 0x2b, 0xc5, 0x02, 0x6a, 0x7f, 0xbb, + 0x96, 0x1d, 0xec, 0x79, 0x6e, 0x8f, 0x0d, 0x23, 0xe4, 0x41, 0x1f, 0x3b, 0xb5, 0x71, 0xce, 0x72, + 0xe5, 0x70, 0xbb, 0x90, 0x4a, 0x11, 0xd5, 0xf4, 0x4c, 0x95, 0xce, 0x1a, 0x2d, 0xc2, 0x8c, 0x04, + 0xba, 0x0d, 0x55, 0x57, 0x1e, 0xa6, 0x4a, 0x45, 0x98, 0x1d, 0xc5, 0x51, 0x4a, 0x53, 0x1c, 0xa2, + 0xec, 0x5e, 0x9d, 0xc0, 0x14, 0x35, 0x44, 0xa0, 0xdc, 0xf0, 0x12, 0x31, 0xad, 0x87, 0x3c, 0x2e, + 0xcf, 0x7b, 0xc6, 0x27, 0x0e, 0x50, 0x19, 0x34, 0xef, 0x25, 0x98, 0xb6, 0x8f, 0x3e, 0x6d, 0xc1, + 0x60, 0xec, 0x36, 0x57, 0xa2, 0x70, 0xdb, 0xab, 0x93, 0x48, 0xe8, 0x98, 0x87, 0xe4, 0x6c, 0xab, + 0xb3, 0x4b, 0xb2, 0x41, 0x4d, 0x97, 0x9b, 0x2f, 0x34, 0x04, 0x9b, 0x74, 0xe9, 0xd9, 0xeb, 0x61, + 0xf1, 0xed, 0x73, 0xc4, 0x65, 0x3b, 0x4e, 0x9e, 0x99, 0xd9, 0x4a, 0x39, 0xb4, 0xce, 0x3d, 0xd7, + 0x76, 0xb7, 0xe8, 0x7e, 0xd3, 0x1d, 0x7a, 0xeb, 0x9d, 0xdd, 0x89, 0x87, 0x67, 0xf3, 0x69, 0xe2, + 0x6e, 0x9d, 0x61, 0x03, 0xd6, 0x6a, 0xfb, 0x3e, 0x26, 0xaf, 0xb6, 0x09, 0xb3, 0x88, 0x15, 0x30, + 0x60, 0x2b, 0xba, 0xc1, 0xcc, 0x80, 0x19, 0x10, 0x6c, 0xd2, 0x45, 0xaf, 0x42, 0x7f, 0xd3, 0x49, + 0x22, 0xef, 0xb6, 0x30, 0x83, 0x1d, 0xf2, 0x14, 0xb4, 0xc4, 0xda, 0xd2, 0xc4, 0x99, 0xa0, 0xe7, + 0x85, 0x58, 0x10, 0x42, 0x4d, 0xa8, 0x34, 0x49, 0xd4, 0x20, 0xe3, 0xd5, 0x22, 0x4c, 0xfe, 0x4b, + 0xb4, 0x29, 0x4d, 0xb0, 0x46, 0x95, 0x2b, 0x56, 0x86, 0x39, 0x15, 0xf4, 0x32, 0x54, 0x63, 0xe2, + 0x13, 0x97, 0xaa, 0x47, 0x35, 0x46, 0xf1, 0x9d, 0x3d, 0xaa, 0x8a, 0x54, 0x2f, 0x59, 0x15, 0x55, + 0xf9, 0x06, 0x93, 0xff, 0xb0, 0x6a, 0x92, 0x0e, 0x60, 0xcb, 0x6f, 0x37, 0xbc, 0x60, 0x1c, 0x8a, + 0x18, 0xc0, 0x15, 0xd6, 0x56, 0x66, 0x00, 0x79, 0x21, 0x16, 0x84, 0xec, 0xff, 0x62, 0x01, 0x4a, + 0x33, 0xb5, 0x63, 0xd0, 0x89, 0x5f, 0x4d, 0xeb, 0xc4, 0x8b, 0x45, 0x2a, 0x2d, 0x5d, 0xd4, 0xe2, + 0xdf, 0xaa, 0x41, 0x46, 0x1c, 0x5c, 0x25, 0x71, 0x42, 0xea, 0x6f, 0xb2, 0xf0, 0x37, 0x59, 0xf8, + 0x9b, 0x2c, 0x5c, 0xb1, 0xf0, 0xf5, 0x0c, 0x0b, 0x7f, 0xaf, 0xb1, 0xeb, 0xf5, 0xfd, 0xfa, 0x2b, + 0xea, 0x02, 0xde, 0xec, 0x81, 0x81, 0x40, 0x39, 0xc1, 0xe5, 0xd5, 0xe5, 0xab, 0xb9, 0x3c, 0xfb, + 0x95, 0x34, 0xcf, 0x3e, 0x2c, 0x89, 0xff, 0x1f, 0xb8, 0xf4, 0x1f, 0x58, 0xf0, 0xb6, 0x34, 0xf7, + 0x92, 0x2b, 0x67, 0xa1, 0x11, 0x84, 0x11, 0x99, 0xf3, 0x36, 0x36, 0x48, 0x44, 0x02, 0x97, 0xc4, + 0xca, 0xb6, 0x63, 0x75, 0xb3, 0xed, 0xa0, 0x67, 0x61, 0xe8, 0x66, 0x1c, 0x06, 0x2b, 0xa1, 0x17, + 0x08, 0x16, 0x44, 0x4f, 0x1c, 0x27, 0xee, 0xec, 0x4e, 0x0c, 0xd1, 0x11, 0x95, 0xe5, 0x38, 0x85, + 0x85, 0x66, 0x61, 0xec, 0xe6, 0xab, 0x2b, 0x4e, 0x62, 0x58, 0x13, 0xe4, 0xb9, 0x9f, 0xdd, 0x47, + 0x5d, 0x7e, 0x31, 0x03, 0xc4, 0x9d, 0xf8, 0xf6, 0xdf, 0x2e, 0xc1, 0x99, 0xcc, 0x87, 0x84, 0xbe, + 0x1f, 0xb6, 0x13, 0x7a, 0x26, 0x42, 0x5f, 0xb5, 0xe0, 0x44, 0x33, 0x6d, 0xb0, 0x88, 0x85, 0xb9, + 0xfb, 0xfd, 0x85, 0xc9, 0x88, 0x8c, 0x45, 0x64, 0x66, 0x5c, 0x8c, 0xd0, 0x89, 0x0c, 0x20, 0xc6, + 0x1d, 0x7d, 0x41, 0x2f, 0x43, 0xad, 0xe9, 0xdc, 0xbe, 0xd6, 0xaa, 0x3b, 0x89, 0x3c, 0x8e, 0x76, + 0xb7, 0x22, 0xb4, 0x13, 0xcf, 0x9f, 0xe4, 0x9e, 0x1b, 0x93, 0x0b, 0x41, 0xb2, 0x1c, 0xad, 0x26, + 0x91, 0x17, 0x34, 0xb8, 0x91, 0x73, 0x49, 0x36, 0x83, 0x75, 0x8b, 0xf6, 0x57, 0xac, 0xac, 0x90, + 0x52, 0xa3, 0x13, 0x39, 0x09, 0x69, 0xec, 0xa0, 0x8f, 0x40, 0x85, 0x9e, 0x1b, 0xe5, 0xa8, 0xdc, + 0x28, 0x52, 0x72, 0x1a, 0x33, 0xa1, 0x85, 0x28, 0xfd, 0x17, 0x63, 0x4e, 0xd4, 0xfe, 0x6a, 0x2d, + 0xab, 0x2c, 0xb0, 0xbb, 0xf9, 0xf3, 0x00, 0x8d, 0x70, 0x8d, 0x34, 0x5b, 0x3e, 0x1d, 0x16, 0x8b, + 0x5d, 0xf0, 0x28, 0x53, 0xc9, 0xbc, 0x82, 0x60, 0x03, 0x0b, 0xfd, 0xb2, 0x05, 0xd0, 0x90, 0x6b, + 0x5e, 0x2a, 0x02, 0xd7, 0x8a, 0xfc, 0x1c, 0xbd, 0xa3, 0x74, 0x5f, 0x14, 0x41, 0x6c, 0x10, 0x47, + 0xbf, 0x60, 0x41, 0x35, 0x91, 0xdd, 0xe7, 0xa2, 0x71, 0xad, 0xc8, 0x9e, 0xc8, 0x8f, 0xd6, 0x3a, + 0x91, 0x1a, 0x12, 0x45, 0x17, 0xfd, 0xa2, 0x05, 0x10, 0xef, 0x04, 0xee, 0x4a, 0xe8, 0x7b, 0xee, + 0x8e, 0x90, 0x98, 0xd7, 0x0b, 0x35, 0xe7, 0xa8, 0xd6, 0x67, 0x46, 0xe8, 0x68, 0xe8, 0xff, 0xd8, + 0xa0, 0x8c, 0x3e, 0x06, 0xd5, 0x58, 0x2c, 0x37, 0x21, 0x23, 0xd7, 0x8a, 0x35, 0x2a, 0xf1, 0xb6, + 0x05, 0x7b, 0x15, 0xff, 0xb0, 0xa2, 0x89, 0xfe, 0xa6, 0x05, 0xa3, 0xad, 0xb4, 0x99, 0x50, 0x88, + 0xc3, 0xe2, 0x78, 0x40, 0xc6, 0x0c, 0xc9, 0xad, 0x2d, 0x99, 0x42, 0x9c, 0xed, 0x05, 0xe5, 0x80, + 0x7a, 0x05, 0x2f, 0xb7, 0xb8, 0xc9, 0x72, 0x40, 0x73, 0xc0, 0xf9, 0x2c, 0x10, 0x77, 0xe2, 0xa3, + 0x15, 0x38, 0x45, 0x7b, 0xb7, 0xc3, 0xd5, 0x4f, 0x29, 0x5e, 0x62, 0x26, 0x0c, 0xab, 0x33, 0x8f, + 0x88, 0x15, 0xc2, 0xee, 0x3a, 0xb2, 0x38, 0x38, 0xb7, 0x26, 0xfa, 0x23, 0x0b, 0x1e, 0xf1, 0x98, + 0x18, 0x30, 0x0d, 0xf6, 0x5a, 0x22, 0x88, 0x8b, 0x76, 0x52, 0x28, 0xaf, 0xe8, 0x26, 0x7e, 0x66, + 0x7e, 0x5c, 0x7c, 0xc1, 0x23, 0x0b, 0x7b, 0x74, 0x09, 0xef, 0xd9, 0x61, 0xf4, 0x53, 0x30, 0x2c, + 0xf7, 0xc5, 0x0a, 0x65, 0xc1, 0x4c, 0xd0, 0xd6, 0x66, 0xc6, 0xee, 0xec, 0x4e, 0x0c, 0xaf, 0x99, + 0x00, 0x9c, 0xc6, 0xb3, 0xff, 0x4d, 0x39, 0x75, 0x4b, 0xa4, 0x6c, 0x98, 0x8c, 0xdd, 0xb8, 0xd2, + 0xfe, 0x23, 0xb9, 0x67, 0xa1, 0xec, 0x46, 0x59, 0x97, 0x34, 0xbb, 0x51, 0x45, 0x31, 0x36, 0x88, + 0x53, 0xa5, 0x74, 0xcc, 0xc9, 0x5a, 0x4a, 0x05, 0x07, 0x7c, 0xb9, 0xc8, 0x2e, 0x75, 0xde, 0xe9, + 0x9d, 0x11, 0x5d, 0x1b, 0xeb, 0x00, 0xe1, 0xce, 0x2e, 0xa1, 0x8f, 0x42, 0x2d, 0x52, 0x9e, 0x2d, + 0xe5, 0x22, 0x8e, 0x6a, 0x72, 0xd9, 0x88, 0xee, 0xa8, 0x0b, 0x20, 0xed, 0xc3, 0xa2, 0x29, 0xda, + 0x7f, 0x98, 0xbe, 0x18, 0x33, 0x78, 0x47, 0x0f, 0x97, 0x7e, 0x5f, 0xb0, 0x60, 0x30, 0x0a, 0x7d, + 0xdf, 0x0b, 0x1a, 0x94, 0xcf, 0x09, 0x61, 0xfd, 0xc1, 0x23, 0x91, 0x97, 0x82, 0xa1, 0x31, 0xcd, + 0x1a, 0x6b, 0x9a, 0xd8, 0xec, 0x80, 0xfd, 0x67, 0x16, 0x8c, 0x77, 0xe3, 0xc7, 0x88, 0xc0, 0x5b, + 0x25, 0xb3, 0x51, 0x43, 0xb1, 0x1c, 0xcc, 0x11, 0x9f, 0x28, 0xb3, 0x79, 0x75, 0xe6, 0x71, 0xf1, + 0x99, 0x6f, 0x5d, 0xe9, 0x8e, 0x8a, 0xf7, 0x6a, 0x07, 0xbd, 0x04, 0x27, 0x8c, 0xef, 0x8a, 0xd5, + 0xc0, 0xd4, 0x66, 0x26, 0xa9, 0x02, 0x34, 0x9d, 0x81, 0xdd, 0xdd, 0x9d, 0x78, 0x28, 0x5b, 0x26, + 0x04, 0x46, 0x47, 0x3b, 0xf6, 0x6f, 0x94, 0xb2, 0xb3, 0xa5, 0x64, 0xfd, 0x1b, 0x56, 0x87, 0x35, + 0xe1, 0xfd, 0x47, 0x21, 0x5f, 0x99, 0xdd, 0x41, 0xb9, 0x61, 0x74, 0xc7, 0xb9, 0x8f, 0xd7, 0xf6, + 0xf6, 0xbf, 0xed, 0x83, 0x3d, 0x7a, 0xd6, 0x83, 0xf2, 0x7e, 0xe0, 0x7b, 0xd4, 0xcf, 0x59, 0xea, + 0xc2, 0x8c, 0xef, 0xe1, 0xfa, 0x51, 0x8d, 0x3d, 0x3f, 0x3f, 0xc5, 0xdc, 0x75, 0x44, 0x59, 0xd1, + 0xd3, 0x57, 0x73, 0xe8, 0x6b, 0x56, 0xfa, 0xca, 0x8f, 0x3b, 0x35, 0x7a, 0x47, 0xd6, 0x27, 0xe3, + 0x1e, 0x91, 0x77, 0x4c, 0xdf, 0x3e, 0x75, 0xbb, 0x61, 0x9c, 0x04, 0xd8, 0xf0, 0x02, 0xc7, 0xf7, + 0x5e, 0xa3, 0xa7, 0xa3, 0x0a, 0x13, 0xf0, 0x4c, 0x63, 0xba, 0xa8, 0x4a, 0xb1, 0x81, 0x71, 0xf6, + 0xaf, 0xc2, 0xa0, 0xf1, 0xe5, 0x39, 0x1e, 0x2f, 0xa7, 0x4c, 0x8f, 0x97, 0x9a, 0xe1, 0xa8, 0x72, + 0xf6, 0xbd, 0x70, 0x22, 0xdb, 0xc1, 0x83, 0xd4, 0xb7, 0xff, 0xf7, 0x40, 0xf6, 0x0e, 0x6e, 0x8d, + 0x44, 0x4d, 0xda, 0xb5, 0x37, 0x0d, 0x5b, 0x6f, 0x1a, 0xb6, 0xde, 0x34, 0x6c, 0x99, 0x77, 0x13, + 0xc2, 0x68, 0x33, 0x70, 0x4c, 0x46, 0x9b, 0x94, 0x19, 0xaa, 0x5a, 0xb8, 0x19, 0xca, 0xfe, 0x74, + 0x87, 0xe5, 0x7e, 0x2d, 0x22, 0x04, 0x85, 0x50, 0x09, 0xc2, 0x3a, 0x91, 0x3a, 0xee, 0xe5, 0x62, + 0x14, 0xb6, 0xab, 0x61, 0xdd, 0x70, 0x17, 0xa7, 0xff, 0x62, 0xcc, 0xe9, 0xd8, 0x77, 0x2a, 0x90, + 0x52, 0x27, 0xf9, 0xbc, 0xbf, 0x1d, 0x06, 0x22, 0xd2, 0x0a, 0xaf, 0xe1, 0x45, 0x21, 0xcb, 0x74, + 0x44, 0x09, 0x2f, 0xc6, 0x12, 0x4e, 0x65, 0x5e, 0xcb, 0x49, 0x36, 0x85, 0x30, 0x53, 0x32, 0x6f, + 0xc5, 0x49, 0x36, 0x31, 0x83, 0xa0, 0xf7, 0xc2, 0x48, 0x92, 0xba, 0x0a, 0x17, 0x57, 0xbe, 0x0f, + 0x09, 0xdc, 0x91, 0xf4, 0x45, 0x39, 0xce, 0x60, 0xa3, 0x57, 0xa1, 0x6f, 0x93, 0xf8, 0x4d, 0x31, + 0xf5, 0xab, 0xc5, 0xc9, 0x1a, 0xf6, 0xad, 0x97, 0x88, 0xdf, 0xe4, 0x9c, 0x90, 0xfe, 0xc2, 0x8c, + 0x14, 0x5d, 0xf7, 0xb5, 0xad, 0x76, 0x9c, 0x84, 0x4d, 0xef, 0x35, 0x69, 0xe9, 0x7c, 0x7f, 0xc1, + 0x84, 0xaf, 0xc8, 0xf6, 0xb9, 0x49, 0x49, 0xfd, 0xc5, 0x9a, 0x32, 0xeb, 0x47, 0xdd, 0x8b, 0xd8, + 0x92, 0xd9, 0x11, 0x06, 0xcb, 0xa2, 0xfb, 0x31, 0x27, 0xdb, 0xe7, 0xfd, 0x50, 0x7f, 0xb1, 0xa6, + 0x8c, 0x76, 0xd4, 0xfe, 0x1b, 0x64, 0x7d, 0xb8, 0x56, 0x70, 0x1f, 0xf8, 0xde, 0xcb, 0xdd, 0x87, + 0x8f, 0x43, 0xc5, 0xdd, 0x74, 0xa2, 0x64, 0x7c, 0x88, 0x2d, 0x1a, 0xb5, 0x8a, 0x67, 0x69, 0x21, + 0xe6, 0x30, 0xf4, 0x28, 0x94, 0x23, 0xb2, 0xc1, 0xbc, 0x93, 0x0d, 0xbf, 0x28, 0x4c, 0x36, 0x30, + 0x2d, 0xb7, 0x7f, 0xad, 0x94, 0x56, 0xdb, 0xd2, 0xdf, 0xcd, 0x57, 0xbb, 0xdb, 0x8e, 0x62, 0x69, + 0xfe, 0x32, 0x56, 0x3b, 0x2b, 0xc6, 0x12, 0x8e, 0x3e, 0x61, 0xc1, 0xc0, 0xcd, 0x38, 0x0c, 0x02, + 0x92, 0x08, 0x11, 0x79, 0xbd, 0xe0, 0xa1, 0xb8, 0xcc, 0x5b, 0xd7, 0x7d, 0x10, 0x05, 0x58, 0xd2, + 0xa5, 0xdd, 0x25, 0xb7, 0x5d, 0xbf, 0x5d, 0xef, 0x70, 0x75, 0xb9, 0xc0, 0x8b, 0xb1, 0x84, 0x53, + 0x54, 0x2f, 0xe0, 0xa8, 0x7d, 0x69, 0xd4, 0x85, 0x40, 0xa0, 0x0a, 0xb8, 0xfd, 0xcd, 0x01, 0x38, + 0x9d, 0xbb, 0x39, 0xa8, 0x42, 0xc5, 0x54, 0x96, 0x8b, 0x9e, 0x4f, 0xa4, 0x93, 0x17, 0x53, 0xa8, + 0xae, 0xab, 0x52, 0x6c, 0x60, 0xa0, 0x9f, 0x07, 0x68, 0x39, 0x91, 0xd3, 0x24, 0xca, 0x3c, 0x7d, + 0x68, 0xbd, 0x85, 0xf6, 0x63, 0x45, 0xb6, 0xa9, 0x8f, 0xe8, 0xaa, 0x28, 0xc6, 0x06, 0x49, 0xf4, + 0x1c, 0x0c, 0x46, 0xc4, 0x27, 0x4e, 0xcc, 0x9c, 0xdb, 0xb3, 0x91, 0x3a, 0x58, 0x83, 0xb0, 0x89, + 0x87, 0x9e, 0x50, 0xfe, 0x70, 0x19, 0xbf, 0xa0, 0xb4, 0x4f, 0x1c, 0x7a, 0xdd, 0x82, 0x91, 0x0d, + 0xcf, 0x27, 0x9a, 0xba, 0x88, 0xab, 0x59, 0x3e, 0xfc, 0x47, 0x5e, 0x34, 0xdb, 0xd5, 0x1c, 0x32, + 0x55, 0x1c, 0xe3, 0x0c, 0x79, 0x3a, 0xcd, 0xdb, 0x24, 0x62, 0xac, 0xb5, 0x3f, 0x3d, 0xcd, 0xd7, + 0x79, 0x31, 0x96, 0x70, 0x34, 0x0d, 0xa3, 0x2d, 0x27, 0x8e, 0x67, 0x23, 0x52, 0x27, 0x41, 0xe2, + 0x39, 0x3e, 0x8f, 0x7a, 0xa9, 0x6a, 0x67, 0xf1, 0x95, 0x34, 0x18, 0x67, 0xf1, 0xd1, 0x07, 0xe0, + 0x61, 0x6e, 0xff, 0x59, 0xf2, 0xe2, 0xd8, 0x0b, 0x1a, 0x7a, 0x19, 0x08, 0x33, 0xd8, 0x84, 0x68, + 0xea, 0xe1, 0x85, 0x7c, 0x34, 0xdc, 0xad, 0x3e, 0x7a, 0x0a, 0xaa, 0xf1, 0x96, 0xd7, 0x9a, 0x8d, + 0xea, 0x31, 0xbb, 0xfb, 0xa9, 0x6a, 0xa3, 0xeb, 0xaa, 0x28, 0xc7, 0x0a, 0x03, 0xb9, 0x30, 0xc4, + 0xa7, 0x84, 0x3b, 0xf4, 0x09, 0xfe, 0xf8, 0x74, 0x57, 0x31, 0x2d, 0x82, 0x38, 0x27, 0xb1, 0x73, + 0xeb, 0x82, 0xbc, 0x89, 0xe2, 0x17, 0x27, 0xd7, 0x8d, 0x66, 0x70, 0xaa, 0xd1, 0xf4, 0x89, 0x6d, + 0xb0, 0x87, 0x13, 0xdb, 0x73, 0x30, 0xb8, 0xd5, 0x5e, 0x27, 0x62, 0xe4, 0x05, 0xdb, 0x52, 0xab, + 0xef, 0x8a, 0x06, 0x61, 0x13, 0x8f, 0xf9, 0x52, 0xb6, 0x3c, 0xf1, 0x2f, 0x1e, 0x1f, 0x36, 0x7c, + 0x29, 0x57, 0x16, 0x64, 0x31, 0x36, 0x71, 0xec, 0x5f, 0x29, 0xa5, 0x8d, 0x12, 0x26, 0xff, 0x40, + 0x31, 0xe5, 0x12, 0xc9, 0x75, 0x27, 0x92, 0xba, 0xc4, 0x21, 0xe3, 0x86, 0x44, 0xbb, 0xd7, 0x9d, + 0xc8, 0xe4, 0x37, 0x8c, 0x00, 0x96, 0x94, 0xd0, 0x4d, 0xe8, 0x4b, 0x7c, 0xa7, 0xa0, 0x40, 0x43, + 0x83, 0xa2, 0xb6, 0x11, 0x2d, 0x4e, 0xc7, 0x98, 0xd1, 0x40, 0x8f, 0xd0, 0x83, 0xd1, 0xba, 0xbc, + 0xc4, 0x12, 0x67, 0x99, 0xf5, 0x18, 0xb3, 0x52, 0xfb, 0xcf, 0x07, 0x73, 0x58, 0xbe, 0x92, 0xb1, + 0xe8, 0x3c, 0x00, 0x9d, 0xb1, 0x95, 0x88, 0x6c, 0x78, 0xb7, 0x85, 0x8e, 0xa3, 0xd8, 0xca, 0x55, + 0x05, 0xc1, 0x06, 0x96, 0xac, 0xb3, 0xda, 0xde, 0xa0, 0x75, 0x4a, 0x9d, 0x75, 0x38, 0x04, 0x1b, + 0x58, 0xe8, 0x59, 0xe8, 0xf7, 0x9a, 0x4e, 0x43, 0xf9, 0xd8, 0x3e, 0x42, 0xf9, 0xc9, 0x02, 0x2b, + 0xb9, 0xbb, 0x3b, 0x31, 0xa2, 0x3a, 0xc4, 0x8a, 0xb0, 0xc0, 0x45, 0xbf, 0x61, 0xc1, 0x90, 0x1b, + 0x36, 0x9b, 0x61, 0xc0, 0x4f, 0xa6, 0xe2, 0x98, 0x7d, 0xf3, 0xa8, 0x34, 0x90, 0xc9, 0x59, 0x83, + 0x18, 0x3f, 0x67, 0xab, 0x88, 0x48, 0x13, 0x84, 0x53, 0xbd, 0x32, 0xd9, 0x4e, 0x65, 0x1f, 0xb6, + 0xf3, 0x9b, 0x16, 0x8c, 0xf1, 0xba, 0xc6, 0x81, 0x59, 0x04, 0xff, 0x85, 0x47, 0xfc, 0x59, 0x1d, + 0x36, 0x04, 0x65, 0x47, 0xed, 0x80, 0xe3, 0xce, 0x4e, 0xa2, 0x79, 0x18, 0xdb, 0x08, 0x23, 0x97, + 0x98, 0x03, 0x21, 0x78, 0xa6, 0x6a, 0xe8, 0x62, 0x16, 0x01, 0x77, 0xd6, 0x41, 0xd7, 0xe1, 0x21, + 0xa3, 0xd0, 0x1c, 0x07, 0xce, 0x36, 0x1f, 0x13, 0xad, 0x3d, 0x74, 0x31, 0x17, 0x0b, 0x77, 0xa9, + 0x9d, 0xe6, 0x50, 0xb5, 0x1e, 0x38, 0xd4, 0x2b, 0x70, 0xc6, 0xed, 0x1c, 0x99, 0xed, 0xb8, 0xbd, + 0x1e, 0x73, 0x26, 0x5a, 0x9d, 0xf9, 0x31, 0xd1, 0xc0, 0x99, 0xd9, 0x6e, 0x88, 0xb8, 0x7b, 0x1b, + 0xe8, 0x23, 0x50, 0x8d, 0x08, 0x9b, 0x95, 0x58, 0x44, 0xc2, 0x1d, 0xd2, 0x90, 0xa0, 0x95, 0x63, + 0xde, 0xac, 0x16, 0x0b, 0xa2, 0x20, 0xc6, 0x8a, 0x22, 0xba, 0x05, 0x03, 0x2d, 0x27, 0x71, 0x37, + 0x45, 0xfc, 0xdb, 0xa1, 0xcd, 0xde, 0x8a, 0x38, 0xbb, 0xa5, 0x30, 0x22, 0xe6, 0x39, 0x11, 0x2c, + 0xa9, 0x51, 0x45, 0xc9, 0x0d, 0x9b, 0xad, 0x30, 0x20, 0x41, 0x22, 0x39, 0xf8, 0x08, 0xbf, 0x4a, + 0x90, 0xa5, 0xd8, 0xc0, 0x40, 0x2b, 0x70, 0x8a, 0x99, 0xd5, 0x6e, 0x78, 0xc9, 0x66, 0xd8, 0x4e, + 0xe4, 0x29, 0x71, 0x7c, 0x24, 0x7d, 0x99, 0xb4, 0x98, 0x83, 0x83, 0x73, 0x6b, 0x66, 0x65, 0xcf, + 0xe8, 0xbd, 0xc9, 0x9e, 0x13, 0xfb, 0xcb, 0x9e, 0xb3, 0xef, 0x83, 0xb1, 0x0e, 0xa6, 0x71, 0x20, + 0xdb, 0xd9, 0x1c, 0x3c, 0x94, 0xbf, 0x3d, 0x0f, 0x64, 0x41, 0xfb, 0xa7, 0x19, 0x17, 0x6a, 0xe3, + 0x34, 0xd1, 0x83, 0x35, 0xd6, 0x81, 0x32, 0x09, 0xb6, 0x85, 0xb4, 0xba, 0x78, 0xb8, 0x55, 0x72, + 0x21, 0xd8, 0xe6, 0xdc, 0x85, 0x99, 0x9c, 0x2e, 0x04, 0xdb, 0x98, 0xb6, 0x8d, 0xbe, 0x64, 0xa5, + 0xb4, 0x61, 0x6e, 0xc3, 0xfd, 0xd0, 0x91, 0x1c, 0x9f, 0x7a, 0x56, 0x90, 0xed, 0x7f, 0x57, 0x82, + 0x73, 0xfb, 0x35, 0xd2, 0xc3, 0xf0, 0x3d, 0x0e, 0xfd, 0x31, 0x73, 0x8a, 0x10, 0xec, 0x7f, 0x90, + 0xee, 0x0a, 0xee, 0x26, 0xf1, 0x0a, 0x16, 0x20, 0xe4, 0x43, 0xb9, 0xe9, 0xb4, 0x84, 0x69, 0x6f, + 0xe1, 0xb0, 0xa1, 0x66, 0xf4, 0xbf, 0xe3, 0x2f, 0x39, 0x2d, 0xbe, 0x3c, 0x8d, 0x02, 0x4c, 0xc9, + 0xa0, 0x04, 0x2a, 0x4e, 0x14, 0x39, 0xf2, 0x06, 0xfe, 0x4a, 0x31, 0xf4, 0xa6, 0x69, 0x93, 0xfc, + 0x02, 0x33, 0x55, 0x84, 0x39, 0x31, 0xfb, 0x73, 0x03, 0xa9, 0xb8, 0x24, 0xe6, 0x56, 0x11, 0x43, + 0xbf, 0xb0, 0xe8, 0x59, 0x45, 0x47, 0xf8, 0xf1, 0xc0, 0x5f, 0x76, 0x58, 0x16, 0xe9, 0x13, 0x04, + 0x29, 0xf4, 0x59, 0x8b, 0x25, 0x29, 0x90, 0xc1, 0x5e, 0xe2, 0x88, 0x7a, 0x34, 0x39, 0x13, 0xcc, + 0xd4, 0x07, 0xb2, 0x10, 0x9b, 0xd4, 0x45, 0xb2, 0x11, 0xa6, 0x9a, 0x77, 0x26, 0x1b, 0x61, 0xaa, + 0xb6, 0x84, 0xa3, 0xdb, 0x39, 0xee, 0x13, 0x05, 0x04, 0xba, 0xf7, 0xe0, 0x30, 0xf1, 0x35, 0x0b, + 0xc6, 0xbc, 0xec, 0x3d, 0xb8, 0x38, 0xd0, 0xdd, 0x28, 0xc6, 0xfc, 0xd6, 0x79, 0xcd, 0xae, 0x14, + 0x87, 0x0e, 0x10, 0xee, 0xec, 0x0c, 0xaa, 0x43, 0x9f, 0x17, 0x6c, 0x84, 0x42, 0x5d, 0x9a, 0x39, + 0x5c, 0xa7, 0x16, 0x82, 0x8d, 0x50, 0xef, 0x66, 0xfa, 0x0f, 0xb3, 0xd6, 0xd1, 0x22, 0x9c, 0x92, + 0xa1, 0x29, 0x97, 0xbc, 0x38, 0x09, 0xa3, 0x9d, 0x45, 0xaf, 0xe9, 0x25, 0x4c, 0xd5, 0x29, 0xcf, + 0x8c, 0x53, 0x49, 0x84, 0x73, 0xe0, 0x38, 0xb7, 0x16, 0x7a, 0x0d, 0x06, 0xe4, 0xdd, 0x73, 0xb5, + 0x88, 0xc3, 0x71, 0xe7, 0xfa, 0x57, 0x8b, 0x69, 0x55, 0x5c, 0x3e, 0x4b, 0x82, 0xf6, 0xeb, 0x83, + 0xd0, 0x79, 0x45, 0x9e, 0xbe, 0x0f, 0xb7, 0x8e, 0xfb, 0x3e, 0x9c, 0x1e, 0x8d, 0x62, 0x7d, 0x95, + 0x5d, 0xc0, 0xda, 0x16, 0x54, 0xf5, 0x35, 0xe5, 0x4e, 0xe0, 0x62, 0x46, 0x03, 0x45, 0xd0, 0xbf, + 0x49, 0x1c, 0x3f, 0xd9, 0x2c, 0xe6, 0x46, 0xe5, 0x12, 0x6b, 0x2b, 0x1b, 0x4f, 0xc6, 0x4b, 0xb1, + 0xa0, 0x84, 0x6e, 0xc3, 0xc0, 0x26, 0x5f, 0x00, 0xe2, 0xb4, 0xb2, 0x74, 0xd8, 0xc1, 0x4d, 0xad, + 0x2a, 0x3d, 0xdd, 0xa2, 0x00, 0x4b, 0x72, 0xcc, 0xf7, 0xca, 0xf0, 0x0e, 0xe1, 0x5b, 0xb7, 0xb8, + 0x50, 0xba, 0xde, 0x5d, 0x43, 0x3e, 0x0c, 0x43, 0x11, 0x71, 0xc3, 0xc0, 0xf5, 0x7c, 0x52, 0x9f, + 0x96, 0xb7, 0x25, 0x07, 0x89, 0xa0, 0x62, 0xc6, 0x08, 0x6c, 0xb4, 0x81, 0x53, 0x2d, 0xa2, 0xcf, + 0x58, 0x30, 0xa2, 0xa2, 0xaa, 0xe9, 0x84, 0x10, 0x61, 0x15, 0x5f, 0x2c, 0x28, 0x86, 0x9b, 0xb5, + 0x39, 0x83, 0xee, 0xec, 0x4e, 0x8c, 0xa4, 0xcb, 0x70, 0x86, 0x2e, 0x7a, 0x09, 0x20, 0x5c, 0xe7, + 0x0e, 0x56, 0xd3, 0x89, 0x30, 0x91, 0x1f, 0xe4, 0x53, 0x47, 0x78, 0x24, 0xa6, 0x6c, 0x01, 0x1b, + 0xad, 0xa1, 0x2b, 0x00, 0x7c, 0xdb, 0xac, 0xed, 0xb4, 0xe4, 0x91, 0x46, 0x86, 0xc0, 0xc1, 0xaa, + 0x82, 0xdc, 0xdd, 0x9d, 0xe8, 0x34, 0x59, 0x32, 0x2f, 0x12, 0xa3, 0x3a, 0xfa, 0x39, 0x18, 0x88, + 0xdb, 0xcd, 0xa6, 0xa3, 0x0c, 0xe8, 0x05, 0xc6, 0x76, 0xf2, 0x76, 0x0d, 0x56, 0xc4, 0x0b, 0xb0, + 0xa4, 0x88, 0x6e, 0x52, 0xa6, 0x1a, 0x0b, 0x5b, 0x2a, 0xdb, 0x45, 0x5c, 0x27, 0xe0, 0x86, 0xa4, + 0x77, 0x49, 0x15, 0x1f, 0xe7, 0xe0, 0xdc, 0xdd, 0x9d, 0x78, 0x28, 0x5d, 0xbe, 0x18, 0x8a, 0x68, + 0xcb, 0xdc, 0x36, 0xd1, 0x65, 0x99, 0x64, 0x89, 0x7e, 0xb6, 0xcc, 0xfd, 0xf1, 0xa4, 0x4e, 0xb2, + 0xc4, 0x8a, 0xbb, 0x8f, 0x99, 0x59, 0x19, 0x2d, 0xc1, 0x49, 0x37, 0x0c, 0x92, 0x28, 0xf4, 0x7d, + 0x9e, 0x64, 0x8c, 0x9f, 0x2e, 0xb9, 0x81, 0xfd, 0xad, 0xa2, 0xdb, 0x27, 0x67, 0x3b, 0x51, 0x70, + 0x5e, 0x3d, 0x3b, 0x48, 0x5f, 0x76, 0x89, 0xc1, 0x79, 0x16, 0x86, 0xc8, 0xed, 0x84, 0x44, 0x81, + 0xe3, 0x5f, 0xc3, 0x8b, 0xd2, 0xb4, 0xcc, 0xf6, 0xc0, 0x05, 0xa3, 0x1c, 0xa7, 0xb0, 0x90, 0xad, + 0x4c, 0x2a, 0x46, 0x04, 0x31, 0x37, 0xa9, 0x48, 0x03, 0x8a, 0xfd, 0xcd, 0x72, 0x4a, 0x21, 0xbb, + 0x2f, 0x57, 0x6b, 0x2c, 0x55, 0x8d, 0xcc, 0xe9, 0xc3, 0x00, 0xe2, 0xa0, 0x51, 0x24, 0x65, 0x95, + 0xaa, 0x66, 0xd9, 0x24, 0x84, 0xd3, 0x74, 0xd1, 0x16, 0x54, 0x36, 0xc3, 0x38, 0x91, 0xc7, 0x8f, + 0x43, 0x9e, 0x74, 0x2e, 0x85, 0x71, 0xc2, 0xb4, 0x08, 0xf5, 0xd9, 0xb4, 0x24, 0xc6, 0x9c, 0x06, + 0x3d, 0x83, 0xc6, 0x9b, 0x4e, 0x54, 0x8f, 0x67, 0x59, 0xbc, 0x7f, 0x1f, 0x53, 0x1f, 0x94, 0xb2, + 0xb8, 0xaa, 0x41, 0xd8, 0xc4, 0xb3, 0xff, 0xab, 0x95, 0xba, 0x7f, 0xb8, 0xc1, 0x9c, 0xb7, 0xb7, + 0x49, 0x40, 0xb9, 0x81, 0xe9, 0x2e, 0xf6, 0x53, 0x99, 0x50, 0xd8, 0xb7, 0x75, 0x4b, 0xbd, 0x77, + 0x8b, 0xb6, 0x30, 0xc9, 0x9a, 0x30, 0x3c, 0xcb, 0x3e, 0x6e, 0xa5, 0x63, 0x9a, 0x4b, 0x45, 0x9c, + 0x4b, 0xcc, 0xb8, 0xfe, 0x7d, 0xc3, 0xa3, 0xed, 0x2f, 0x59, 0x30, 0x30, 0xe3, 0xb8, 0x5b, 0xe1, + 0xc6, 0x06, 0x7a, 0x0a, 0xaa, 0xf5, 0x76, 0x64, 0x86, 0x57, 0x2b, 0xcb, 0xc6, 0x9c, 0x28, 0xc7, + 0x0a, 0x83, 0x2e, 0xfd, 0x0d, 0xc7, 0x95, 0xd1, 0xfd, 0x65, 0xbe, 0xf4, 0x2f, 0xb2, 0x12, 0x2c, + 0x20, 0x74, 0xf8, 0x9b, 0xce, 0x6d, 0x59, 0x39, 0x7b, 0xf9, 0xb1, 0xa4, 0x41, 0xd8, 0xc4, 0xb3, + 0xff, 0x95, 0x05, 0xe3, 0x33, 0x4e, 0xec, 0xb9, 0xd3, 0xed, 0x64, 0x73, 0xc6, 0x4b, 0xd6, 0xdb, + 0xee, 0x16, 0x49, 0x78, 0x16, 0x08, 0xda, 0xcb, 0x76, 0x4c, 0x77, 0xa0, 0x3a, 0x0e, 0xaa, 0x5e, + 0x5e, 0x13, 0xe5, 0x58, 0x61, 0xa0, 0xd7, 0x60, 0xb0, 0xe5, 0xc4, 0xf1, 0xad, 0x30, 0xaa, 0x63, + 0xb2, 0x51, 0x4c, 0x9e, 0x98, 0x55, 0xe2, 0x46, 0x24, 0xc1, 0x64, 0x43, 0x38, 0x0a, 0xe8, 0xf6, + 0xb1, 0x49, 0xcc, 0xfe, 0x65, 0x0b, 0x4e, 0xcd, 0x10, 0x27, 0x22, 0x11, 0x4b, 0x2b, 0xa3, 0x3e, + 0x04, 0xbd, 0x0a, 0xd5, 0x84, 0x96, 0xd0, 0x1e, 0x59, 0xc5, 0xf6, 0x88, 0x5d, 0xf1, 0xaf, 0x89, + 0xc6, 0xb1, 0x22, 0x63, 0x7f, 0xc1, 0x82, 0x33, 0x79, 0x7d, 0x99, 0xf5, 0xc3, 0x76, 0xfd, 0x7e, + 0x74, 0xe8, 0x6f, 0x59, 0x30, 0xc4, 0xae, 0x4d, 0xe7, 0x48, 0xe2, 0x78, 0x7e, 0x47, 0x4a, 0x3b, + 0xab, 0xc7, 0x94, 0x76, 0xe7, 0xa0, 0x6f, 0x33, 0x6c, 0x92, 0xec, 0x95, 0xff, 0xa5, 0xb0, 0x49, + 0x30, 0x83, 0xa0, 0x67, 0xe8, 0x22, 0xf4, 0x82, 0xc4, 0xa1, 0xdb, 0x51, 0xda, 0xbe, 0x47, 0xf9, + 0x02, 0x54, 0xc5, 0xd8, 0xc4, 0xb1, 0xff, 0x65, 0x0d, 0x06, 0x84, 0x7f, 0x4a, 0xcf, 0x59, 0x49, + 0xa4, 0x89, 0xa2, 0xd4, 0xd5, 0x44, 0x11, 0x43, 0xbf, 0xcb, 0x72, 0x6b, 0x0a, 0x4d, 0xf8, 0x4a, + 0x21, 0x0e, 0x4d, 0x3c, 0x5d, 0xa7, 0xee, 0x16, 0xff, 0x8f, 0x05, 0x29, 0xf4, 0x45, 0x0b, 0x46, + 0xdd, 0x30, 0x08, 0x88, 0xab, 0xd5, 0xb4, 0xbe, 0x22, 0xfc, 0x56, 0x66, 0xd3, 0x8d, 0xea, 0x3b, + 0xbb, 0x0c, 0x00, 0x67, 0xc9, 0xa3, 0x17, 0x60, 0x98, 0x8f, 0xd9, 0xf5, 0x94, 0xc1, 0x5e, 0x67, + 0x3a, 0x33, 0x81, 0x38, 0x8d, 0x8b, 0x26, 0xf9, 0xc5, 0x87, 0xc8, 0x29, 0xd6, 0xaf, 0xed, 0x9a, + 0x46, 0x36, 0x31, 0x03, 0x03, 0x45, 0x80, 0x22, 0xb2, 0x11, 0x91, 0x78, 0x53, 0xf8, 0xef, 0x30, + 0x15, 0x71, 0xe0, 0xde, 0xf2, 0x09, 0xe0, 0x8e, 0x96, 0x70, 0x4e, 0xeb, 0x68, 0x4b, 0x9c, 0x91, + 0xab, 0x45, 0xf0, 0x73, 0x31, 0xcd, 0x5d, 0x8f, 0xca, 0x13, 0x50, 0x61, 0xa2, 0x8b, 0xa9, 0xa6, + 0x65, 0x1e, 0xc3, 0xc6, 0x04, 0x1b, 0xe6, 0xe5, 0x68, 0x0e, 0x4e, 0x64, 0xf2, 0xb4, 0xc5, 0xc2, + 0xb0, 0xae, 0xe2, 0x95, 0x32, 0x19, 0xde, 0x62, 0xdc, 0x51, 0xc3, 0xb4, 0x9f, 0x0c, 0xee, 0x63, + 0x3f, 0xd9, 0x51, 0x5e, 0xa2, 0xdc, 0xe4, 0xfd, 0x62, 0x21, 0x03, 0xd0, 0x93, 0x4b, 0xe8, 0xe7, + 0x33, 0x2e, 0xa1, 0xc3, 0xac, 0x03, 0xd7, 0x8b, 0xe9, 0xc0, 0xc1, 0xfd, 0x3f, 0xef, 0xa7, 0x3f, + 0xe7, 0xff, 0xb2, 0x40, 0xce, 0xeb, 0xac, 0xe3, 0x6e, 0x12, 0xba, 0x64, 0xd0, 0x7b, 0x61, 0x44, + 0x59, 0x01, 0xb8, 0x4a, 0x64, 0xb1, 0x55, 0xa3, 0x2e, 0xf7, 0x71, 0x0a, 0x8a, 0x33, 0xd8, 0x68, + 0x0a, 0x6a, 0x74, 0x9c, 0x78, 0x55, 0x2e, 0xf7, 0x95, 0xa5, 0x61, 0x7a, 0x65, 0x41, 0xd4, 0xd2, + 0x38, 0x28, 0x84, 0x31, 0xdf, 0x89, 0x13, 0xd6, 0x83, 0xd5, 0x9d, 0xc0, 0xbd, 0xc7, 0x6c, 0x1e, + 0x2c, 0x28, 0x66, 0x31, 0xdb, 0x10, 0xee, 0x6c, 0xdb, 0xfe, 0x6e, 0x1f, 0x0c, 0xa7, 0x38, 0xe3, + 0x01, 0x15, 0x86, 0xa7, 0xa0, 0x2a, 0x65, 0x78, 0x36, 0x6d, 0x91, 0x12, 0xf4, 0x0a, 0x83, 0x0a, + 0xad, 0x75, 0x2d, 0x55, 0xb3, 0x0a, 0x8e, 0x21, 0x70, 0xb1, 0x89, 0xc7, 0x98, 0x72, 0xe2, 0xc7, + 0xb3, 0xbe, 0x47, 0x82, 0x84, 0x77, 0xb3, 0x18, 0xa6, 0xbc, 0xb6, 0xb8, 0x6a, 0x36, 0xaa, 0x99, + 0x72, 0x06, 0x80, 0xb3, 0xe4, 0xd1, 0xa7, 0x2c, 0x18, 0x76, 0x6e, 0xc5, 0x3a, 0x01, 0xb4, 0x70, + 0xfe, 0x3c, 0xa4, 0x90, 0x4a, 0xe5, 0x94, 0xe6, 0x56, 0xeb, 0x54, 0x11, 0x4e, 0x13, 0x45, 0x6f, + 0x58, 0x80, 0xc8, 0x6d, 0xe2, 0x4a, 0xf7, 0x54, 0xd1, 0x97, 0xfe, 0x22, 0x0e, 0xcb, 0x17, 0x3a, + 0xda, 0xe5, 0x5c, 0xbd, 0xb3, 0x1c, 0xe7, 0xf4, 0xc1, 0xfe, 0x17, 0x65, 0xb5, 0xa1, 0xb4, 0x47, + 0xb4, 0x63, 0x78, 0x66, 0x5a, 0xf7, 0xee, 0x99, 0xa9, 0x3d, 0x4b, 0x3a, 0x83, 0x84, 0x53, 0x31, + 0x85, 0xa5, 0xfb, 0x14, 0x53, 0xf8, 0x0b, 0x56, 0x2a, 0x41, 0xd7, 0xe0, 0xf9, 0x97, 0x8a, 0xf5, + 0xc6, 0x9e, 0xe4, 0x5e, 0x2f, 0x19, 0xee, 0x9e, 0x76, 0x76, 0xa2, 0xdc, 0xd4, 0x40, 0x3b, 0x10, + 0x37, 0xfc, 0x0f, 0x65, 0x18, 0x34, 0x24, 0x69, 0xae, 0x5a, 0x64, 0x3d, 0x60, 0x6a, 0x51, 0xe9, + 0x00, 0x6a, 0xd1, 0xcf, 0x43, 0xcd, 0x95, 0x5c, 0xbe, 0x98, 0x14, 0xe2, 0x59, 0xd9, 0xa1, 0x19, + 0xbd, 0x2a, 0xc2, 0x9a, 0x26, 0x9a, 0x4f, 0x45, 0xa2, 0xa5, 0xce, 0xdb, 0x79, 0xa1, 0x62, 0x42, + 0x52, 0x74, 0xd6, 0xc9, 0xde, 0xff, 0x56, 0x7a, 0xf0, 0x3d, 0xfa, 0xae, 0xa5, 0x26, 0xf7, 0x18, + 0x52, 0x8e, 0xdc, 0x4c, 0xa7, 0x1c, 0xb9, 0x50, 0xc8, 0x30, 0x77, 0xc9, 0x35, 0x72, 0x15, 0x06, + 0x66, 0xc3, 0x66, 0xd3, 0x09, 0xea, 0xe8, 0x27, 0x60, 0xc0, 0xe5, 0x3f, 0x85, 0x6d, 0x8a, 0xdd, + 0x70, 0x0a, 0x28, 0x96, 0x30, 0xf4, 0x08, 0xf4, 0x39, 0x51, 0x43, 0xda, 0xa3, 0x98, 0x27, 0xd2, + 0x74, 0xd4, 0x88, 0x31, 0x2b, 0xb5, 0xff, 0x49, 0x1f, 0x30, 0x07, 0x00, 0x27, 0x22, 0xf5, 0xb5, + 0x90, 0x65, 0xfe, 0x3c, 0xd2, 0x7b, 0x41, 0x7d, 0x58, 0x7a, 0x90, 0xef, 0x06, 0x8d, 0xfb, 0xa1, + 0xf2, 0x31, 0xdf, 0x0f, 0x75, 0xb9, 0xf2, 0xeb, 0x7b, 0x80, 0xae, 0xfc, 0xec, 0xcf, 0x59, 0x80, + 0x94, 0xd7, 0x88, 0xbe, 0x93, 0x9f, 0x82, 0x9a, 0xf2, 0x1f, 0x11, 0x8a, 0x95, 0x66, 0x11, 0x12, + 0x80, 0x35, 0x4e, 0x0f, 0x27, 0xe4, 0xc7, 0x25, 0xff, 0x2e, 0xa7, 0xfd, 0xab, 0x19, 0xd7, 0x17, + 0xec, 0xdc, 0xfe, 0xbd, 0x12, 0x3c, 0xc4, 0x45, 0xf2, 0x92, 0x13, 0x38, 0x0d, 0xd2, 0xa4, 0xbd, + 0xea, 0xd5, 0xcb, 0xc2, 0xa5, 0x47, 0x33, 0x4f, 0xfa, 0x4b, 0x1f, 0x76, 0xef, 0xf2, 0x3d, 0xc7, + 0x77, 0xd9, 0x42, 0xe0, 0x25, 0x98, 0x35, 0x8e, 0x62, 0xa8, 0xca, 0xf7, 0x35, 0x04, 0x2f, 0x2e, + 0x88, 0x90, 0x62, 0x4b, 0x42, 0x6e, 0x12, 0xac, 0x08, 0x51, 0xc5, 0xd5, 0x0f, 0xdd, 0x2d, 0x4c, + 0x5a, 0x21, 0xe3, 0xbb, 0x86, 0xbb, 0xea, 0xa2, 0x28, 0xc7, 0x0a, 0xc3, 0x6e, 0xc2, 0xa8, 0x1c, + 0xc3, 0xd6, 0x15, 0xb2, 0x83, 0xc9, 0x06, 0x95, 0x3f, 0xae, 0x2c, 0x32, 0x9e, 0xfc, 0x50, 0xf2, + 0x67, 0xd6, 0x04, 0xe2, 0x34, 0xae, 0x4c, 0x06, 0x5a, 0xca, 0x4f, 0x06, 0x6a, 0xff, 0x9e, 0x05, + 0x59, 0x01, 0x68, 0xa4, 0x3e, 0xb4, 0xf6, 0x4c, 0x7d, 0x78, 0x80, 0xe4, 0x81, 0x3f, 0x0b, 0x83, + 0x4e, 0x42, 0x75, 0x16, 0x7e, 0xca, 0x2f, 0xdf, 0xdb, 0x45, 0xd0, 0x52, 0x58, 0xf7, 0x36, 0x3c, + 0x76, 0xba, 0x37, 0x9b, 0xb3, 0xff, 0xb2, 0x0f, 0xc6, 0x3a, 0x82, 0x99, 0xd0, 0xf3, 0x30, 0xa4, + 0x86, 0x42, 0xda, 0xcf, 0x6a, 0xa6, 0xcb, 0xa2, 0x86, 0xe1, 0x14, 0x66, 0x0f, 0xfb, 0x61, 0x01, + 0x4e, 0x46, 0xe4, 0xd5, 0x36, 0x69, 0x93, 0xe9, 0x8d, 0x84, 0x44, 0xab, 0xc4, 0x0d, 0x83, 0x3a, + 0x4f, 0xd0, 0x59, 0x9e, 0x79, 0xf8, 0xce, 0xee, 0xc4, 0x49, 0xdc, 0x09, 0xc6, 0x79, 0x75, 0x50, + 0x0b, 0x86, 0x7d, 0x53, 0xe5, 0x14, 0xe7, 0x8d, 0x7b, 0xd2, 0x56, 0xd5, 0x92, 0x48, 0x15, 0xe3, + 0x34, 0x81, 0xb4, 0xde, 0x5a, 0xb9, 0x4f, 0x7a, 0xeb, 0x27, 0xb5, 0xde, 0xca, 0x3d, 0x16, 0x3e, + 0x58, 0x70, 0x30, 0xdb, 0x51, 0x2b, 0xae, 0x2f, 0x42, 0x55, 0x7a, 0x73, 0xf5, 0xe4, 0x05, 0x65, + 0xb6, 0xd3, 0x85, 0x81, 0x3e, 0x01, 0x3f, 0x7e, 0x21, 0x8a, 0x8c, 0xc1, 0xbc, 0x1a, 0x26, 0xd3, + 0xbe, 0x1f, 0xde, 0xa2, 0x3a, 0xc1, 0xb5, 0x98, 0x08, 0x83, 0x8e, 0x7d, 0xb7, 0x04, 0x39, 0x67, + 0x23, 0xba, 0x1f, 0xb5, 0x22, 0x92, 0xda, 0x8f, 0x07, 0x53, 0x46, 0xd0, 0x6d, 0xee, 0xf1, 0xc6, + 0x45, 0xee, 0x07, 0x8a, 0x3e, 0xdb, 0x69, 0x27, 0x38, 0xc5, 0x8e, 0x94, 0x23, 0xdc, 0x79, 0x00, + 0xad, 0x3f, 0x8a, 0x08, 0x0b, 0x75, 0xa1, 0xae, 0xd5, 0x4c, 0x6c, 0x60, 0xd1, 0xa3, 0xbe, 0x17, + 0xc4, 0x89, 0xe3, 0xfb, 0x97, 0xbc, 0x20, 0x11, 0x36, 0x4b, 0xa5, 0x5b, 0x2c, 0x68, 0x10, 0x36, + 0xf1, 0xce, 0xbe, 0xcb, 0x98, 0xbf, 0x83, 0xcc, 0xfb, 0x26, 0x9c, 0x99, 0xf7, 0x12, 0x15, 0x17, + 0xa4, 0xd6, 0x1b, 0x55, 0x0f, 0x55, 0x9c, 0x9b, 0xd5, 0x35, 0xce, 0xcd, 0x88, 0xcb, 0x29, 0xa5, + 0xc3, 0x88, 0xb2, 0x71, 0x39, 0xf6, 0xf3, 0x70, 0x6a, 0xde, 0x4b, 0x2e, 0x7a, 0x3e, 0x39, 0x20, + 0x11, 0xfb, 0x77, 0xfb, 0x61, 0xc8, 0x8c, 0x70, 0x3d, 0x48, 0xa8, 0xde, 0x17, 0xa8, 0x06, 0x28, + 0xbe, 0xce, 0x53, 0xd7, 0x91, 0x37, 0x0e, 0x1d, 0x6e, 0x9b, 0x3f, 0x62, 0x86, 0x12, 0xa8, 0x69, + 0x62, 0xb3, 0x03, 0xe8, 0x16, 0x54, 0x36, 0x58, 0xdc, 0x48, 0xb9, 0x08, 0x9f, 0x8d, 0xbc, 0x11, + 0xd5, 0xdb, 0x91, 0x47, 0x9e, 0x70, 0x7a, 0x54, 0x70, 0x47, 0xe9, 0x60, 0x44, 0xc3, 0xa1, 0x58, + 0x84, 0x21, 0x2a, 0x8c, 0x6e, 0x22, 0xa1, 0x72, 0x0f, 0x22, 0x21, 0xc5, 0xa0, 0xfb, 0xef, 0x13, + 0x83, 0x66, 0x31, 0x40, 0xc9, 0x26, 0x53, 0x2b, 0x45, 0x04, 0xc4, 0x00, 0x1b, 0x04, 0x23, 0x06, + 0x28, 0x05, 0xc6, 0x59, 0x7c, 0xf4, 0x31, 0xc5, 0xe2, 0xab, 0x45, 0x98, 0x7b, 0xcd, 0x15, 0x7d, + 0xd4, 0xdc, 0xfd, 0x73, 0x25, 0x18, 0x99, 0x0f, 0xda, 0x2b, 0xf3, 0x2b, 0xed, 0x75, 0xdf, 0x73, + 0xaf, 0x90, 0x1d, 0xca, 0xc2, 0xb7, 0xc8, 0xce, 0xc2, 0x9c, 0xd8, 0x41, 0x6a, 0xcd, 0x5c, 0xa1, + 0x85, 0x98, 0xc3, 0x28, 0x33, 0xda, 0xf0, 0x82, 0x06, 0x89, 0x5a, 0x91, 0x27, 0x2c, 0xb1, 0x06, + 0x33, 0xba, 0xa8, 0x41, 0xd8, 0xc4, 0xa3, 0x6d, 0x87, 0xb7, 0x02, 0x12, 0x65, 0xf5, 0xeb, 0x65, + 0x5a, 0x88, 0x39, 0x8c, 0x22, 0x25, 0x51, 0x3b, 0x4e, 0xc4, 0x62, 0x54, 0x48, 0x6b, 0xb4, 0x10, + 0x73, 0x18, 0xdd, 0xe9, 0x71, 0x7b, 0x9d, 0xb9, 0xc4, 0x64, 0xc2, 0x2d, 0x56, 0x79, 0x31, 0x96, + 0x70, 0x8a, 0xba, 0x45, 0x76, 0xe6, 0xe8, 0x61, 0x3c, 0x13, 0x10, 0x76, 0x85, 0x17, 0x63, 0x09, + 0x67, 0x29, 0x44, 0xd3, 0xc3, 0xf1, 0x43, 0x97, 0x42, 0x34, 0xdd, 0xfd, 0x2e, 0xc7, 0xfa, 0x5f, + 0xb7, 0x60, 0xc8, 0x74, 0x64, 0x43, 0x8d, 0x8c, 0x2e, 0xbc, 0xdc, 0x91, 0x81, 0xfa, 0x3d, 0x79, + 0xaf, 0x33, 0x36, 0xbc, 0x24, 0x6c, 0xc5, 0x4f, 0x93, 0xa0, 0xe1, 0x05, 0x84, 0x39, 0x1a, 0x70, + 0x07, 0xb8, 0x94, 0x97, 0xdc, 0x6c, 0x58, 0x27, 0xf7, 0xa0, 0x4c, 0xdb, 0x37, 0x60, 0xac, 0x23, + 0x0a, 0xb0, 0x07, 0x15, 0x64, 0xdf, 0x18, 0x6c, 0x1b, 0xc3, 0x20, 0x6d, 0x58, 0xa6, 0xb1, 0x9a, + 0x85, 0x31, 0xbe, 0x91, 0x28, 0xa5, 0x55, 0x77, 0x93, 0x34, 0x55, 0x64, 0x27, 0x33, 0xfb, 0x5f, + 0xcf, 0x02, 0x71, 0x27, 0xbe, 0xfd, 0x79, 0x0b, 0x86, 0x53, 0x81, 0x99, 0x05, 0x29, 0x4b, 0x6c, + 0xa7, 0x85, 0xcc, 0xaf, 0x92, 0x39, 0x97, 0x97, 0x99, 0x30, 0xd5, 0x3b, 0x4d, 0x83, 0xb0, 0x89, + 0x67, 0x7f, 0xa9, 0x04, 0x55, 0xe9, 0x9b, 0xd2, 0x43, 0x57, 0x3e, 0x6b, 0xc1, 0xb0, 0xba, 0x6a, + 0x61, 0x36, 0xbc, 0x52, 0x11, 0xa1, 0x2a, 0xb4, 0x07, 0xca, 0x0a, 0x10, 0x6c, 0x84, 0x5a, 0x73, + 0xc7, 0x26, 0x31, 0x9c, 0xa6, 0x8d, 0xae, 0x03, 0xc4, 0x3b, 0x71, 0x42, 0x9a, 0x86, 0x35, 0xd1, + 0x36, 0x76, 0xdc, 0xa4, 0x1b, 0x46, 0x84, 0xee, 0xaf, 0xab, 0x61, 0x9d, 0xac, 0x2a, 0x4c, 0xad, + 0x42, 0xe9, 0x32, 0x6c, 0xb4, 0x64, 0xff, 0xa3, 0x12, 0x9c, 0xc8, 0x76, 0x09, 0x7d, 0x10, 0x86, + 0x24, 0x75, 0xe3, 0xd4, 0x29, 0x3d, 0x6b, 0x86, 0xb0, 0x01, 0xbb, 0xbb, 0x3b, 0x31, 0xd1, 0xf9, + 0xd2, 0xe7, 0xa4, 0x89, 0x82, 0x53, 0x8d, 0xf1, 0xfb, 0x2e, 0x71, 0x31, 0x3b, 0xb3, 0x33, 0xdd, + 0x6a, 0x89, 0x4b, 0x2b, 0xe3, 0xbe, 0xcb, 0x84, 0xe2, 0x0c, 0x36, 0x5a, 0x81, 0x53, 0x46, 0xc9, + 0x55, 0xe2, 0x35, 0x36, 0xd7, 0xc3, 0x48, 0x9e, 0xc0, 0x1e, 0xd1, 0x2e, 0x73, 0x9d, 0x38, 0x38, + 0xb7, 0x26, 0x95, 0xf6, 0xae, 0xd3, 0x72, 0x5c, 0x2f, 0xd9, 0x11, 0xe6, 0x51, 0xc5, 0x9b, 0x66, + 0x45, 0x39, 0x56, 0x18, 0xf6, 0x12, 0xf4, 0xf5, 0xb8, 0x82, 0x7a, 0xd2, 0xfc, 0x5f, 0x84, 0x2a, + 0x6d, 0x4e, 0xaa, 0x77, 0x45, 0x34, 0x19, 0x42, 0x55, 0xbe, 0x9b, 0x84, 0x6c, 0x28, 0x7b, 0x8e, + 0xbc, 0x52, 0x54, 0x9f, 0xb5, 0x10, 0xc7, 0x6d, 0x76, 0x98, 0xa6, 0x40, 0xf4, 0x38, 0x94, 0xc9, + 0xed, 0x56, 0xf6, 0xee, 0xf0, 0xc2, 0xed, 0x96, 0x17, 0x91, 0x98, 0x22, 0x91, 0xdb, 0x2d, 0x74, + 0x16, 0x4a, 0x5e, 0x5d, 0x08, 0x29, 0x10, 0x38, 0xa5, 0x85, 0x39, 0x5c, 0xf2, 0xea, 0xf6, 0x6d, + 0xa8, 0xa9, 0x87, 0x9a, 0xd0, 0x96, 0xe4, 0xdd, 0x56, 0x11, 0xce, 0x64, 0xb2, 0xdd, 0x2e, 0x5c, + 0xbb, 0x0d, 0xa0, 0xc3, 0x40, 0x8b, 0xe2, 0x2f, 0xe7, 0xa0, 0xcf, 0x0d, 0x45, 0xf4, 0x7c, 0x55, + 0x37, 0xc3, 0x98, 0x36, 0x83, 0xd8, 0x37, 0x60, 0xe4, 0x4a, 0x10, 0xde, 0x62, 0xef, 0x29, 0xb0, + 0xf4, 0x81, 0xb4, 0xe1, 0x0d, 0xfa, 0x23, 0xab, 0x22, 0x30, 0x28, 0xe6, 0x30, 0x95, 0xd8, 0xac, + 0xd4, 0x2d, 0xb1, 0x99, 0xfd, 0x71, 0x0b, 0x86, 0x54, 0x3c, 0xd9, 0xfc, 0xf6, 0x16, 0x6d, 0xb7, + 0x11, 0x85, 0xed, 0x56, 0xb6, 0x5d, 0xf6, 0x26, 0x1c, 0xe6, 0x30, 0x33, 0xd0, 0xb2, 0xb4, 0x4f, + 0xa0, 0xe5, 0x39, 0xe8, 0xdb, 0xf2, 0x82, 0x7a, 0xf6, 0x6d, 0xa0, 0x2b, 0x5e, 0x50, 0xc7, 0x0c, + 0x42, 0xbb, 0x70, 0x42, 0x75, 0x41, 0x0a, 0x84, 0xe7, 0x61, 0x68, 0xbd, 0xed, 0xf9, 0x75, 0x99, + 0x17, 0x31, 0x63, 0x51, 0x99, 0x31, 0x60, 0x38, 0x85, 0x49, 0xcf, 0x75, 0xeb, 0x5e, 0xe0, 0x44, + 0x3b, 0x2b, 0x5a, 0x02, 0x29, 0xa6, 0x34, 0xa3, 0x20, 0xd8, 0xc0, 0xb2, 0x5f, 0x2f, 0xc3, 0x48, + 0x3a, 0xaa, 0xae, 0x87, 0xe3, 0xd5, 0xe3, 0x50, 0x61, 0x81, 0x76, 0xd9, 0xa9, 0xe5, 0xa9, 0x04, + 0x39, 0x0c, 0xc5, 0xd0, 0xcf, 0xb3, 0x87, 0x14, 0xf3, 0xae, 0x96, 0xea, 0xa4, 0xb2, 0xc3, 0x30, + 0x97, 0x3b, 0x91, 0xb0, 0x44, 0x90, 0x42, 0x9f, 0xb2, 0x60, 0x20, 0x6c, 0x99, 0x09, 0xb1, 0x3e, + 0x50, 0x64, 0xc4, 0xa1, 0x08, 0x43, 0x12, 0x1a, 0xb1, 0x9a, 0x7a, 0x39, 0x1d, 0x92, 0xf4, 0xd9, + 0x77, 0xc3, 0x90, 0x89, 0xb9, 0x9f, 0x52, 0x5c, 0x35, 0x95, 0xe2, 0xcf, 0x9a, 0x8b, 0x42, 0xc4, + 0x54, 0xf6, 0xb0, 0xdd, 0xae, 0x41, 0xc5, 0x55, 0x7e, 0x09, 0xf7, 0x94, 0x4d, 0x57, 0xa5, 0xf3, + 0x60, 0x77, 0x53, 0xbc, 0x35, 0xfb, 0xbb, 0x96, 0xb1, 0x3e, 0x30, 0x89, 0x17, 0xea, 0x28, 0x82, + 0x72, 0x63, 0x7b, 0x4b, 0xa8, 0xa2, 0x97, 0x0b, 0x1a, 0xde, 0xf9, 0xed, 0x2d, 0xbd, 0xc6, 0xcd, + 0x52, 0x4c, 0x89, 0xf5, 0x60, 0x2c, 0x4c, 0x85, 0xde, 0x96, 0xf7, 0x0f, 0xbd, 0xb5, 0xdf, 0x28, + 0xc1, 0x58, 0xc7, 0xa2, 0x42, 0xaf, 0x41, 0x25, 0xa2, 0x5f, 0x29, 0x3e, 0x6f, 0xb1, 0xb0, 0x60, + 0xd9, 0x78, 0xa1, 0xae, 0xe5, 0x6e, 0xba, 0x1c, 0x73, 0x92, 0xe8, 0x32, 0x20, 0xed, 0x3d, 0xa3, + 0x2c, 0x95, 0xfc, 0x93, 0xcf, 0x8a, 0xaa, 0x68, 0xba, 0x03, 0x03, 0xe7, 0xd4, 0x42, 0x2f, 0x64, + 0x0d, 0x9e, 0xe5, 0xb4, 0x39, 0x7b, 0x2f, 0xdb, 0xa5, 0xfd, 0xdb, 0x25, 0x18, 0x4e, 0xe5, 0x27, + 0x43, 0x3e, 0x54, 0x89, 0xcf, 0xee, 0x1a, 0xa4, 0xb0, 0x39, 0x6c, 0xb6, 0x71, 0x25, 0x20, 0x2f, + 0x88, 0x76, 0xb1, 0xa2, 0xf0, 0x60, 0xdc, 0xf9, 0x3f, 0x0f, 0x43, 0xb2, 0x43, 0x1f, 0x70, 0x9a, + 0xbe, 0x18, 0x40, 0xb5, 0x46, 0x2f, 0x18, 0x30, 0x9c, 0xc2, 0xb4, 0x7f, 0xbf, 0x0c, 0xe3, 0xfc, + 0x72, 0xa6, 0xae, 0x56, 0xde, 0x92, 0x3c, 0x6f, 0xfd, 0x35, 0x9d, 0x45, 0xd0, 0x2a, 0xe2, 0x49, + 0xcd, 0x6e, 0x84, 0x7a, 0x72, 0x18, 0xfb, 0x6a, 0xc6, 0x61, 0x8c, 0xab, 0xdd, 0x8d, 0x23, 0xea, + 0xd1, 0x0f, 0x97, 0x07, 0xd9, 0xdf, 0x2f, 0xc1, 0x68, 0xe6, 0xe5, 0x14, 0xf4, 0x7a, 0x3a, 0xd9, + 0xb6, 0x55, 0x84, 0x4d, 0x7d, 0xcf, 0xc7, 0x34, 0x0e, 0x96, 0x72, 0xfb, 0x3e, 0x6d, 0x15, 0xfb, + 0x3b, 0x25, 0x18, 0x49, 0x3f, 0xf9, 0xf2, 0x00, 0x8e, 0xd4, 0x3b, 0xa0, 0xc6, 0x5e, 0x35, 0x60, + 0x2f, 0x15, 0x73, 0x93, 0x3c, 0x4f, 0x20, 0x2f, 0x0b, 0xb1, 0x86, 0x3f, 0x10, 0x99, 0xcc, 0xed, + 0x7f, 0x68, 0xc1, 0x69, 0xfe, 0x95, 0xd9, 0x75, 0xf8, 0xd7, 0xf3, 0x46, 0xf7, 0xe5, 0x62, 0x3b, + 0x98, 0xc9, 0x7e, 0xb9, 0xdf, 0xf8, 0xb2, 0x87, 0x45, 0x45, 0x6f, 0xd3, 0x4b, 0xe1, 0x01, 0xec, + 0xec, 0x81, 0x16, 0x83, 0xfd, 0x9d, 0x32, 0xe8, 0xb7, 0x54, 0x91, 0x27, 0xa2, 0x47, 0x0b, 0xc9, + 0x02, 0xba, 0xba, 0x13, 0xb8, 0xfa, 0xd5, 0xd6, 0x6a, 0x26, 0x78, 0xf4, 0x97, 0x2c, 0x18, 0xf4, + 0x02, 0x2f, 0xf1, 0x1c, 0x76, 0x8c, 0x2e, 0xe6, 0x41, 0x44, 0x45, 0x6e, 0x81, 0xb7, 0x1c, 0x46, + 0xe6, 0x3d, 0x8e, 0x22, 0x86, 0x4d, 0xca, 0xe8, 0xc3, 0xc2, 0xa7, 0xbb, 0x5c, 0x58, 0xdc, 0x73, + 0x35, 0xe3, 0xc8, 0xdd, 0xa2, 0x8a, 0x57, 0x12, 0x15, 0x94, 0x2e, 0x00, 0xd3, 0xa6, 0x54, 0x42, + 0x69, 0xfd, 0x3c, 0x3f, 0x2d, 0xc6, 0x9c, 0x90, 0x1d, 0x03, 0xea, 0x1c, 0x8b, 0x03, 0xfa, 0xcb, + 0x4e, 0x41, 0xcd, 0x69, 0x27, 0x61, 0x93, 0x0e, 0x93, 0xb8, 0x6a, 0xd2, 0x1e, 0xc1, 0x12, 0x80, + 0x35, 0x8e, 0xfd, 0x7a, 0x05, 0x32, 0xe1, 0x9c, 0xe8, 0xb6, 0xf9, 0x0e, 0xb0, 0x55, 0xec, 0x3b, + 0xc0, 0xaa, 0x33, 0x79, 0x6f, 0x01, 0xa3, 0x06, 0x54, 0x5a, 0x9b, 0x4e, 0x2c, 0xd5, 0xea, 0x17, + 0xd5, 0x39, 0x8e, 0x16, 0xde, 0xdd, 0x9d, 0xf8, 0x99, 0xde, 0xac, 0xae, 0x74, 0xad, 0x4e, 0xf1, + 0x14, 0x34, 0x9a, 0x34, 0x6b, 0x03, 0xf3, 0xf6, 0x0f, 0xf2, 0x24, 0xe4, 0x27, 0xc4, 0xf3, 0x0d, + 0x98, 0xc4, 0x6d, 0x3f, 0x11, 0xab, 0xe1, 0xc5, 0x02, 0x77, 0x19, 0x6f, 0x58, 0x27, 0x22, 0xe0, + 0xff, 0xb1, 0x41, 0x14, 0x7d, 0x10, 0x6a, 0x71, 0xe2, 0x44, 0xc9, 0x3d, 0x86, 0x0e, 0xab, 0x41, + 0x5f, 0x95, 0x8d, 0x60, 0xdd, 0x1e, 0x7a, 0x89, 0x25, 0x45, 0xf6, 0xe2, 0xcd, 0x7b, 0x0c, 0xc5, + 0x90, 0x09, 0x94, 0x45, 0x0b, 0xd8, 0x68, 0x0d, 0x9d, 0x07, 0x60, 0x6b, 0x9b, 0xfb, 0x1f, 0x56, + 0x99, 0x95, 0x49, 0xb1, 0x42, 0xac, 0x20, 0xd8, 0xc0, 0xb2, 0x7f, 0x12, 0xd2, 0x99, 0x34, 0xd0, + 0x84, 0x4c, 0xdc, 0xc1, 0xad, 0xd0, 0x2c, 0xa4, 0x22, 0x95, 0x63, 0xe3, 0x37, 0x2d, 0x30, 0xd3, + 0x7d, 0xa0, 0x57, 0x79, 0x5e, 0x11, 0xab, 0x88, 0x9b, 0x43, 0xa3, 0xdd, 0xc9, 0x25, 0xa7, 0x95, + 0xb9, 0xc2, 0x96, 0xc9, 0x45, 0xce, 0xbe, 0x0b, 0xaa, 0x12, 0x7a, 0x20, 0xa5, 0xee, 0x63, 0x70, + 0x52, 0x86, 0x67, 0x4a, 0xbb, 0xa9, 0xb8, 0x75, 0xda, 0xdf, 0xf4, 0x23, 0xed, 0x39, 0xa5, 0x6e, + 0xf6, 0x9c, 0x1e, 0x5e, 0x83, 0xfe, 0x2d, 0x0b, 0xce, 0x65, 0x3b, 0x10, 0x2f, 0x85, 0x81, 0x97, + 0x84, 0xd1, 0x2a, 0x49, 0x12, 0x2f, 0x68, 0xb0, 0x74, 0x6a, 0xb7, 0x9c, 0x48, 0x66, 0xab, 0x67, + 0x8c, 0xf2, 0x86, 0x13, 0x05, 0x98, 0x95, 0xa2, 0x1d, 0xe8, 0xe7, 0x4e, 0x6a, 0x42, 0x5b, 0x3f, + 0xe4, 0xde, 0xc8, 0x19, 0x0e, 0x7d, 0x5c, 0xe0, 0x0e, 0x72, 0x58, 0x10, 0xb4, 0xbf, 0x6f, 0x01, + 0x5a, 0xde, 0x26, 0x51, 0xe4, 0xd5, 0x0d, 0xb7, 0x3a, 0xf6, 0x0c, 0x92, 0xf1, 0xdc, 0x91, 0x19, + 0x3c, 0x9c, 0x79, 0x06, 0xc9, 0xf8, 0x97, 0xff, 0x0c, 0x52, 0xe9, 0x60, 0xcf, 0x20, 0xa1, 0x65, + 0x38, 0xdd, 0xe4, 0xc7, 0x0d, 0xfe, 0xb4, 0x08, 0x3f, 0x7b, 0xa8, 0x38, 0xb7, 0x33, 0x77, 0x76, + 0x27, 0x4e, 0x2f, 0xe5, 0x21, 0xe0, 0xfc, 0x7a, 0xf6, 0xbb, 0x00, 0x71, 0x6f, 0xba, 0xd9, 0x3c, + 0x5f, 0xa5, 0xae, 0xe6, 0x17, 0xfb, 0x2b, 0x15, 0x18, 0xcd, 0xe4, 0x32, 0xa6, 0x47, 0xbd, 0x4e, + 0xe7, 0xa8, 0x43, 0xcb, 0xef, 0xce, 0xee, 0xf5, 0xe4, 0x6e, 0x15, 0x40, 0xc5, 0x0b, 0x5a, 0xed, + 0xa4, 0x98, 0x30, 0x5b, 0xde, 0x89, 0x05, 0xda, 0xa0, 0x61, 0x2e, 0xa6, 0x7f, 0x31, 0x27, 0x53, + 0xa4, 0xf3, 0x56, 0x4a, 0x19, 0xef, 0xbb, 0x4f, 0xe6, 0x80, 0x4f, 0x68, 0x57, 0xaa, 0x4a, 0x11, + 0x86, 0xc5, 0xcc, 0x62, 0x39, 0xea, 0xab, 0xf6, 0x6f, 0x96, 0x60, 0xd0, 0x98, 0x34, 0xf4, 0x6b, + 0xe9, 0x64, 0x58, 0x56, 0x71, 0x9f, 0xc4, 0xda, 0x9f, 0xd4, 0xe9, 0xae, 0xf8, 0x27, 0x3d, 0xd1, + 0x99, 0x07, 0xeb, 0xee, 0xee, 0xc4, 0x89, 0x4c, 0xa6, 0xab, 0x54, 0x6e, 0xac, 0xb3, 0x1f, 0x85, + 0xd1, 0x4c, 0x33, 0x39, 0x9f, 0xbc, 0x66, 0x7e, 0xf2, 0xa1, 0xcd, 0x52, 0xe6, 0x90, 0x7d, 0x83, + 0x0e, 0x99, 0x88, 0xee, 0x0b, 0x7d, 0xd2, 0x83, 0x0d, 0x36, 0x13, 0xc4, 0x5b, 0xea, 0x31, 0x88, + 0xf7, 0x49, 0xa8, 0xb6, 0x42, 0xdf, 0x73, 0x3d, 0x95, 0x9b, 0x92, 0x85, 0x0d, 0xaf, 0x88, 0x32, + 0xac, 0xa0, 0xe8, 0x16, 0xd4, 0x6e, 0xde, 0x4a, 0xf8, 0xed, 0x8f, 0xb0, 0x6f, 0x17, 0x75, 0xe9, + 0xa3, 0x94, 0x16, 0x75, 0xbd, 0x84, 0x35, 0x2d, 0x64, 0x43, 0x3f, 0x13, 0x82, 0x32, 0x22, 0x81, + 0xd9, 0xde, 0x99, 0x74, 0x8c, 0xb1, 0x80, 0xd8, 0x5f, 0xaf, 0xc1, 0xa9, 0xbc, 0x84, 0xf2, 0xe8, + 0x23, 0xd0, 0xcf, 0xfb, 0x58, 0xcc, 0x9b, 0x25, 0x79, 0x34, 0xe6, 0x59, 0x83, 0xa2, 0x5b, 0xec, + 0x37, 0x16, 0x34, 0x05, 0x75, 0xdf, 0x59, 0x17, 0x2b, 0xe4, 0x68, 0xa8, 0x2f, 0x3a, 0x9a, 0xfa, + 0xa2, 0xc3, 0xa9, 0xfb, 0xce, 0x3a, 0xba, 0x0d, 0x95, 0x86, 0x97, 0x10, 0x47, 0x18, 0x11, 0x6e, + 0x1c, 0x09, 0x71, 0xe2, 0x70, 0x2d, 0x8d, 0xfd, 0xc4, 0x9c, 0x20, 0xfa, 0x9a, 0x05, 0xa3, 0xeb, + 0xe9, 0xec, 0x01, 0x82, 0x79, 0x3a, 0x47, 0xf0, 0x68, 0x40, 0x9a, 0x10, 0x7f, 0x07, 0x2c, 0x53, + 0x88, 0xb3, 0xdd, 0x41, 0x9f, 0xb4, 0x60, 0x60, 0xc3, 0xf3, 0x8d, 0xbc, 0xcd, 0x47, 0x30, 0x39, + 0x17, 0x19, 0x01, 0x7d, 0xe2, 0xe0, 0xff, 0x63, 0x2c, 0x29, 0x77, 0x93, 0x54, 0xfd, 0x87, 0x95, + 0x54, 0x03, 0xf7, 0x49, 0x52, 0x7d, 0xc6, 0x82, 0x9a, 0x1a, 0x69, 0x11, 0x85, 0xfd, 0xc1, 0x23, + 0x9c, 0x72, 0x6e, 0x39, 0x51, 0x7f, 0xb1, 0x26, 0x8e, 0xbe, 0x68, 0xc1, 0xa0, 0xf3, 0x5a, 0x3b, + 0x22, 0x75, 0xb2, 0x1d, 0xb6, 0x62, 0xf1, 0x88, 0xe8, 0xcb, 0xc5, 0x77, 0x66, 0x9a, 0x12, 0x99, + 0x23, 0xdb, 0xcb, 0xad, 0x58, 0x44, 0x4b, 0xe9, 0x02, 0x6c, 0x76, 0xc1, 0xde, 0x2d, 0xc1, 0xc4, + 0x3e, 0x2d, 0xa0, 0xe7, 0x61, 0x28, 0x8c, 0x1a, 0x4e, 0xe0, 0xbd, 0x66, 0xa6, 0x03, 0x51, 0x5a, + 0xd6, 0xb2, 0x01, 0xc3, 0x29, 0x4c, 0x33, 0x4e, 0xbc, 0xb4, 0x4f, 0x9c, 0xf8, 0x39, 0xe8, 0x8b, + 0x48, 0x2b, 0xcc, 0x1e, 0x16, 0x58, 0xa4, 0x02, 0x83, 0xa0, 0x47, 0xa1, 0xec, 0xb4, 0x3c, 0xe1, + 0x88, 0xa6, 0xce, 0x40, 0xd3, 0x2b, 0x0b, 0x98, 0x96, 0xa7, 0xd2, 0x56, 0x54, 0x8e, 0x25, 0x6d, + 0x05, 0x15, 0x03, 0xe2, 0xee, 0xa2, 0x5f, 0x8b, 0x81, 0xf4, 0x9d, 0x82, 0xfd, 0x46, 0x19, 0x1e, + 0xdd, 0x73, 0xbd, 0x68, 0x3f, 0x3c, 0x6b, 0x0f, 0x3f, 0x3c, 0x39, 0x3c, 0xa5, 0xfd, 0x86, 0xa7, + 0xdc, 0x65, 0x78, 0x3e, 0x49, 0xb7, 0x81, 0x4c, 0xa3, 0x52, 0xcc, 0x33, 0x90, 0xdd, 0xb2, 0xb2, + 0x88, 0x1d, 0x20, 0xa1, 0x58, 0xd3, 0xa5, 0x67, 0x80, 0x54, 0x8c, 0x74, 0xa5, 0x08, 0x31, 0xd0, + 0x35, 0x95, 0x09, 0x5f, 0xfb, 0xdd, 0x02, 0xaf, 0xed, 0xdf, 0xe9, 0x83, 0xc7, 0x7b, 0xe0, 0xde, + 0xe6, 0x2a, 0xb6, 0x7a, 0x5c, 0xc5, 0x3f, 0xe4, 0xd3, 0xf4, 0xe9, 0xdc, 0x69, 0xc2, 0xc5, 0x4f, + 0xd3, 0xde, 0x33, 0x84, 0x9e, 0x82, 0xaa, 0x17, 0xc4, 0xc4, 0x6d, 0x47, 0xdc, 0x27, 0xd9, 0x08, + 0x63, 0x5a, 0x10, 0xe5, 0x58, 0x61, 0xd0, 0x33, 0x9d, 0xeb, 0xd0, 0xed, 0x3f, 0x50, 0x50, 0xec, + 0xae, 0x19, 0x11, 0xc5, 0x55, 0x8a, 0xd9, 0x69, 0xca, 0x01, 0x38, 0x19, 0xfb, 0x6f, 0x58, 0x70, + 0xb6, 0xbb, 0x88, 0x45, 0xcf, 0xc0, 0xe0, 0x7a, 0xe4, 0x04, 0xee, 0x26, 0x7b, 0x00, 0x58, 0x2e, + 0x1d, 0xf6, 0xbd, 0xba, 0x18, 0x9b, 0x38, 0x68, 0x16, 0xc6, 0xb8, 0xe7, 0x86, 0x81, 0x21, 0x23, + 0x7f, 0xef, 0xec, 0x4e, 0x8c, 0xad, 0x65, 0x81, 0xb8, 0x13, 0xdf, 0xfe, 0x41, 0x39, 0xbf, 0x5b, + 0x5c, 0x15, 0x3b, 0xc8, 0x6a, 0x16, 0x6b, 0xb5, 0xd4, 0x03, 0xc7, 0x2d, 0x1f, 0x37, 0xc7, 0xed, + 0xeb, 0xc6, 0x71, 0xd1, 0x1c, 0x9c, 0x30, 0x5e, 0x68, 0xe2, 0xd1, 0xdc, 0xdc, 0x2d, 0x59, 0xa5, + 0x38, 0x59, 0xc9, 0xc0, 0x71, 0x47, 0x8d, 0x07, 0x7c, 0xe9, 0xfd, 0x7a, 0x09, 0xce, 0x74, 0xd5, + 0x7e, 0x8f, 0x49, 0xa2, 0x98, 0xd3, 0xdf, 0x77, 0x3c, 0xd3, 0x6f, 0x4e, 0x4a, 0x65, 0xbf, 0x49, + 0xb1, 0xff, 0xa4, 0xd4, 0x75, 0x23, 0xd0, 0x93, 0xd0, 0x8f, 0xec, 0x28, 0xbd, 0x00, 0xc3, 0x4e, + 0xab, 0xc5, 0xf1, 0x98, 0x17, 0x6d, 0x26, 0xa5, 0xd2, 0xb4, 0x09, 0xc4, 0x69, 0xdc, 0x9e, 0x74, + 0x9a, 0x3f, 0xb5, 0xa0, 0x86, 0xc9, 0x06, 0xe7, 0x46, 0xe8, 0xa6, 0x18, 0x22, 0xab, 0x88, 0xfc, + 0xb1, 0x74, 0x60, 0x63, 0x8f, 0xe5, 0x55, 0xcd, 0x1b, 0xec, 0xce, 0x17, 0xbb, 0x4a, 0x07, 0x7a, + 0xb1, 0x4b, 0xbd, 0xd9, 0x54, 0xee, 0xfe, 0x66, 0x93, 0xfd, 0xbd, 0x01, 0xfa, 0x79, 0xad, 0x70, + 0x36, 0x22, 0xf5, 0x98, 0xce, 0x6f, 0x3b, 0xf2, 0xc5, 0x22, 0x51, 0xf3, 0x7b, 0x0d, 0x2f, 0x62, + 0x5a, 0x9e, 0xba, 0x20, 0x2b, 0x1d, 0x28, 0xa1, 0x4c, 0x79, 0xdf, 0x84, 0x32, 0x2f, 0xc0, 0x70, + 0x1c, 0x6f, 0xae, 0x44, 0xde, 0xb6, 0x93, 0x90, 0x2b, 0x64, 0x47, 0xe8, 0xbe, 0x3a, 0x09, 0xc4, + 0xea, 0x25, 0x0d, 0xc4, 0x69, 0x5c, 0x34, 0x0f, 0x63, 0x3a, 0xad, 0x0b, 0x89, 0x12, 0x16, 0x73, + 0xc1, 0x57, 0x82, 0x8a, 0xf8, 0xd6, 0x89, 0x60, 0x04, 0x02, 0xee, 0xac, 0x43, 0xf9, 0x69, 0xaa, + 0x90, 0x76, 0xa4, 0x3f, 0xcd, 0x4f, 0x53, 0xed, 0xd0, 0xbe, 0x74, 0xd4, 0x40, 0x4b, 0x70, 0x92, + 0x2f, 0x8c, 0xe9, 0x56, 0xcb, 0xf8, 0xa2, 0x81, 0x74, 0xde, 0xce, 0xf9, 0x4e, 0x14, 0x9c, 0x57, + 0x0f, 0x3d, 0x07, 0x83, 0xaa, 0x78, 0x61, 0x4e, 0xdc, 0xed, 0x28, 0xdb, 0x92, 0x6a, 0x66, 0xa1, + 0x8e, 0x4d, 0x3c, 0xf4, 0x01, 0x78, 0x58, 0xff, 0xe5, 0x81, 0x79, 0xfc, 0xc2, 0x73, 0x4e, 0x64, + 0xcc, 0x52, 0x2f, 0x04, 0xcd, 0xe7, 0xa2, 0xd5, 0x71, 0xb7, 0xfa, 0x68, 0x1d, 0xce, 0x2a, 0xd0, + 0x85, 0x20, 0x61, 0x51, 0x36, 0x31, 0x99, 0x71, 0x62, 0x72, 0x2d, 0xf2, 0xc5, 0x4b, 0xd3, 0xea, + 0x11, 0xd9, 0x79, 0x2f, 0xb9, 0x94, 0x87, 0x89, 0x17, 0xf1, 0x1e, 0xad, 0xa0, 0x29, 0xa8, 0x91, + 0xc0, 0x59, 0xf7, 0xc9, 0xf2, 0xec, 0x02, 0xcb, 0xbc, 0x65, 0xdc, 0xaf, 0x5e, 0x90, 0x00, 0xac, + 0x71, 0x94, 0xdf, 0xef, 0x50, 0xd7, 0x07, 0x8d, 0x57, 0xe0, 0x54, 0xc3, 0x6d, 0x51, 0x8d, 0xd0, + 0x73, 0xc9, 0xb4, 0xcb, 0xdc, 0x1c, 0xe9, 0xc4, 0xf0, 0x84, 0xaa, 0xca, 0xa9, 0x7d, 0x7e, 0x76, + 0xa5, 0x03, 0x07, 0xe7, 0xd6, 0x64, 0xee, 0xb0, 0x51, 0x78, 0x7b, 0x67, 0xfc, 0x64, 0xc6, 0x1d, + 0x96, 0x16, 0x62, 0x0e, 0x43, 0x97, 0x01, 0xb1, 0x08, 0x89, 0x4b, 0x49, 0xd2, 0x52, 0x2a, 0xe8, + 0xf8, 0x29, 0xf6, 0x49, 0xca, 0xb9, 0xef, 0x62, 0x07, 0x06, 0xce, 0xa9, 0x45, 0x35, 0x9a, 0x20, + 0x64, 0xad, 0x8f, 0x3f, 0x9c, 0xd6, 0x68, 0xae, 0xf2, 0x62, 0x2c, 0xe1, 0xf6, 0x7f, 0xb4, 0x60, + 0x58, 0x6d, 0xed, 0x63, 0x08, 0x27, 0xf2, 0xd3, 0xe1, 0x44, 0xf3, 0x87, 0x67, 0x8e, 0xac, 0xe7, + 0x5d, 0x7c, 0xd2, 0xbf, 0x39, 0x08, 0xa0, 0x19, 0xa8, 0x92, 0x5d, 0x56, 0x57, 0xd9, 0xf5, 0xc0, + 0x32, 0xaf, 0xbc, 0x8c, 0x3c, 0x95, 0xfb, 0x9b, 0x91, 0x67, 0x15, 0x4e, 0x4b, 0xcd, 0x82, 0x5f, + 0xf6, 0x5d, 0x0a, 0x63, 0xc5, 0x0b, 0xab, 0x33, 0x8f, 0x8a, 0x86, 0x4e, 0x2f, 0xe4, 0x21, 0xe1, + 0xfc, 0xba, 0x29, 0x85, 0x66, 0x60, 0x5f, 0x2d, 0x53, 0x6d, 0xff, 0xc5, 0x0d, 0xf9, 0x34, 0x4f, + 0x66, 0xfb, 0x2f, 0x5e, 0x5c, 0xc5, 0x1a, 0x27, 0x5f, 0x06, 0xd4, 0x0a, 0x92, 0x01, 0x70, 0x60, + 0x19, 0x20, 0xb9, 0xd1, 0x60, 0x57, 0x6e, 0x24, 0x2f, 0x15, 0x86, 0xba, 0x5e, 0x2a, 0xbc, 0x17, + 0x46, 0xbc, 0x60, 0x93, 0x44, 0x5e, 0x42, 0xea, 0x6c, 0x2f, 0x30, 0x4e, 0x55, 0xd5, 0x1a, 0xc0, + 0x42, 0x0a, 0x8a, 0x33, 0xd8, 0x69, 0x16, 0x3a, 0xd2, 0x03, 0x0b, 0xed, 0x22, 0xb8, 0x46, 0x8b, + 0x11, 0x5c, 0x27, 0x0e, 0x2f, 0xb8, 0xc6, 0x8e, 0x54, 0x70, 0xa1, 0x42, 0x04, 0x57, 0x4f, 0x32, + 0xc1, 0x38, 0x99, 0x9e, 0xda, 0xe7, 0x64, 0xda, 0x4d, 0x6a, 0x9d, 0xbe, 0x67, 0xa9, 0x95, 0x2f, + 0x90, 0x1e, 0x3a, 0x6a, 0x81, 0xf4, 0x99, 0x12, 0x9c, 0xd6, 0x2c, 0x9b, 0x6e, 0x14, 0x6f, 0x83, + 0x32, 0x2d, 0xf6, 0x10, 0x1c, 0xbf, 0xa3, 0x33, 0x02, 0xe1, 0x74, 0x4c, 0x9d, 0x82, 0x60, 0x03, + 0x8b, 0xc5, 0x93, 0x91, 0x88, 0x65, 0x95, 0xce, 0xf2, 0xf3, 0x59, 0x51, 0x8e, 0x15, 0x06, 0x5d, + 0x8a, 0xf4, 0xb7, 0x88, 0xd1, 0xcd, 0xe6, 0x2b, 0x9c, 0xd5, 0x20, 0x6c, 0xe2, 0xa1, 0x27, 0x39, + 0x11, 0xc6, 0x4b, 0x28, 0x4f, 0x1f, 0x12, 0x8f, 0x67, 0x4b, 0xf6, 0xa1, 0xa0, 0xb2, 0x3b, 0x2c, + 0x70, 0xb0, 0xd2, 0xd9, 0x1d, 0xe6, 0xee, 0xa6, 0x30, 0xec, 0xff, 0x69, 0xc1, 0x99, 0xdc, 0xa1, + 0x38, 0x06, 0x39, 0x7d, 0x3b, 0x2d, 0xa7, 0x57, 0x8b, 0x3a, 0xc4, 0x18, 0x5f, 0xd1, 0x45, 0x66, + 0xff, 0x7b, 0x0b, 0x46, 0x34, 0xfe, 0x31, 0x7c, 0xaa, 0x97, 0xfe, 0xd4, 0xe2, 0xce, 0x6b, 0xb5, + 0x8e, 0x6f, 0xfb, 0xfd, 0x12, 0xa8, 0x1c, 0xa2, 0xd3, 0xae, 0xcc, 0xd0, 0xbc, 0xcf, 0xad, 0xf1, + 0x0e, 0xf4, 0xb3, 0x4b, 0xef, 0xb8, 0x18, 0x87, 0x9e, 0x34, 0x7d, 0x76, 0x81, 0xae, 0x1d, 0x0a, + 0xd8, 0xdf, 0x18, 0x0b, 0x82, 0x2c, 0xe7, 0xb9, 0x17, 0x53, 0xc6, 0x5f, 0x17, 0x21, 0x78, 0x3a, + 0xe7, 0xb9, 0x28, 0xc7, 0x0a, 0x83, 0x4a, 0x12, 0xcf, 0x0d, 0x83, 0x59, 0xdf, 0x89, 0xe5, 0xc3, + 0xac, 0x4a, 0x92, 0x2c, 0x48, 0x00, 0xd6, 0x38, 0xec, 0x3e, 0xdc, 0x8b, 0x5b, 0xbe, 0xb3, 0x63, + 0x9c, 0xca, 0x8d, 0x5c, 0x14, 0x0a, 0x84, 0x4d, 0x3c, 0xbb, 0x09, 0xe3, 0xe9, 0x8f, 0x98, 0x23, + 0x1b, 0xcc, 0x19, 0xb5, 0xa7, 0xe1, 0x9c, 0x82, 0x9a, 0xc3, 0x6a, 0x2d, 0xb6, 0x1d, 0xc1, 0x13, + 0xb4, 0x4b, 0xa6, 0x04, 0x60, 0x8d, 0x63, 0xff, 0x03, 0x0b, 0x4e, 0xe6, 0x0c, 0x5a, 0x81, 0x21, + 0x8e, 0x89, 0xe6, 0x36, 0x79, 0x3a, 0xc0, 0xdb, 0x61, 0xa0, 0x4e, 0x36, 0x1c, 0xe9, 0xee, 0x68, + 0x70, 0xcf, 0x39, 0x5e, 0x8c, 0x25, 0xdc, 0xfe, 0xed, 0x12, 0x8c, 0xa6, 0xfb, 0x1a, 0xb3, 0xb0, + 0x21, 0x3e, 0x4c, 0x5e, 0xec, 0x86, 0xdb, 0x24, 0xda, 0xa1, 0x5f, 0x6e, 0x65, 0xc2, 0x86, 0x3a, + 0x30, 0x70, 0x4e, 0x2d, 0x96, 0x41, 0xb8, 0xae, 0x46, 0x5b, 0xae, 0xc8, 0xeb, 0x45, 0xae, 0x48, + 0x3d, 0x99, 0xa6, 0x6b, 0x84, 0x22, 0x89, 0x4d, 0xfa, 0x54, 0x17, 0x61, 0x7e, 0xd8, 0x33, 0x6d, + 0xcf, 0x4f, 0xbc, 0x40, 0x7c, 0xb2, 0x58, 0xab, 0x4a, 0x17, 0x59, 0xea, 0x44, 0xc1, 0x79, 0xf5, + 0xec, 0xef, 0xf7, 0x81, 0x0a, 0xa9, 0x66, 0xae, 0x6b, 0x05, 0x39, 0xfe, 0x1d, 0x34, 0xf8, 0x4c, + 0xad, 0xad, 0xbe, 0xbd, 0x7c, 0x49, 0xb8, 0x29, 0xc7, 0xb4, 0xe7, 0xaa, 0x01, 0x5b, 0xd3, 0x20, + 0x6c, 0xe2, 0xd1, 0x9e, 0xf8, 0xde, 0x36, 0xe1, 0x95, 0xfa, 0xd3, 0x3d, 0x59, 0x94, 0x00, 0xac, + 0x71, 0x68, 0x4f, 0xea, 0xde, 0xc6, 0x86, 0xb0, 0x4b, 0xa8, 0x9e, 0xd0, 0xd1, 0xc1, 0x0c, 0xc2, + 0x73, 0xcc, 0x87, 0x5b, 0x42, 0xff, 0x36, 0x72, 0xcc, 0x87, 0x5b, 0x98, 0x41, 0xe8, 0x2c, 0x05, + 0x61, 0xd4, 0x74, 0x7c, 0xef, 0x35, 0x52, 0x57, 0x54, 0x84, 0xde, 0xad, 0x66, 0xe9, 0x6a, 0x27, + 0x0a, 0xce, 0xab, 0x47, 0x17, 0x74, 0x2b, 0x22, 0x75, 0xcf, 0x4d, 0xcc, 0xd6, 0x20, 0xbd, 0xa0, + 0x57, 0x3a, 0x30, 0x70, 0x4e, 0x2d, 0x34, 0x0d, 0xa3, 0x32, 0x24, 0x5e, 0x26, 0x3c, 0x1a, 0x4c, + 0x27, 0x58, 0xc1, 0x69, 0x30, 0xce, 0xe2, 0x53, 0x26, 0xd9, 0x14, 0x39, 0xd1, 0x98, 0x9a, 0x6e, + 0x30, 0x49, 0x99, 0x2b, 0x0d, 0x2b, 0x0c, 0xfb, 0x13, 0x65, 0x2a, 0xd4, 0xbb, 0xa4, 0x1e, 0x3c, + 0x36, 0x47, 0xd3, 0xf4, 0x8a, 0xec, 0xeb, 0x61, 0x45, 0x3e, 0x0b, 0x43, 0x37, 0xe3, 0x30, 0x50, + 0x4e, 0x9c, 0x95, 0xae, 0x4e, 0x9c, 0x06, 0x56, 0xbe, 0x13, 0x67, 0x7f, 0x51, 0x4e, 0x9c, 0x03, + 0xf7, 0xe8, 0xc4, 0xf9, 0x87, 0x15, 0x50, 0xef, 0xf5, 0x5c, 0x25, 0xc9, 0xad, 0x30, 0xda, 0xf2, + 0x82, 0x06, 0x4b, 0x25, 0xf0, 0x35, 0x0b, 0x86, 0xf8, 0x7e, 0x59, 0x34, 0x83, 0xf0, 0x36, 0x0a, + 0x7a, 0x08, 0x26, 0x45, 0x6c, 0x72, 0xcd, 0x20, 0x94, 0x79, 0xcb, 0xd7, 0x04, 0xe1, 0x54, 0x8f, + 0xd0, 0x47, 0x01, 0xa4, 0x11, 0x77, 0x43, 0x72, 0xe0, 0x85, 0x62, 0xfa, 0x87, 0xc9, 0x86, 0x56, + 0xa9, 0xd7, 0x14, 0x11, 0x6c, 0x10, 0x44, 0x9f, 0xd1, 0x01, 0x8a, 0x3c, 0xda, 0xe3, 0xc3, 0x47, + 0x32, 0x36, 0xbd, 0x84, 0x27, 0x62, 0x18, 0xf0, 0x82, 0x06, 0x5d, 0x27, 0xc2, 0xd9, 0xed, 0x6d, + 0x79, 0x69, 0x38, 0x16, 0x43, 0xa7, 0x3e, 0xe3, 0xf8, 0x4e, 0xe0, 0x92, 0x68, 0x81, 0xa3, 0x9b, + 0x8f, 0xeb, 0xb3, 0x02, 0x2c, 0x1b, 0xea, 0x78, 0xe9, 0xa8, 0xd2, 0xcb, 0x4b, 0x47, 0x67, 0xdf, + 0x07, 0x63, 0x1d, 0x93, 0x79, 0xa0, 0x68, 0xc4, 0x7b, 0x0f, 0x64, 0xb4, 0x7f, 0xa7, 0x5f, 0x0b, + 0xad, 0xab, 0x61, 0x9d, 0x3f, 0x9c, 0x13, 0xe9, 0x19, 0x15, 0x2a, 0x73, 0x81, 0x4b, 0xc4, 0x78, + 0xa0, 0x5f, 0x15, 0x62, 0x93, 0x24, 0x5d, 0xa3, 0x2d, 0x27, 0x22, 0xc1, 0x51, 0xaf, 0xd1, 0x15, + 0x45, 0x04, 0x1b, 0x04, 0xd1, 0x66, 0x2a, 0x1c, 0xe9, 0xe2, 0xe1, 0xc3, 0x91, 0x58, 0x82, 0xb2, + 0xbc, 0xf7, 0x25, 0xbe, 0x68, 0xc1, 0x48, 0x90, 0x5a, 0xb9, 0xc5, 0x78, 0x20, 0xe7, 0xef, 0x0a, + 0xfe, 0xdc, 0x5b, 0xba, 0x0c, 0x67, 0xe8, 0xe7, 0x89, 0xb4, 0xca, 0x01, 0x45, 0x9a, 0x7e, 0xb8, + 0xab, 0xbf, 0xdb, 0xc3, 0x5d, 0x28, 0x50, 0x2f, 0x17, 0x0e, 0x14, 0xfe, 0x72, 0x21, 0xe4, 0xbc, + 0x5a, 0x78, 0x03, 0x6a, 0x6e, 0x44, 0x9c, 0xe4, 0x1e, 0x1f, 0xb1, 0x63, 0xbe, 0x1d, 0xb3, 0xb2, + 0x01, 0xac, 0xdb, 0xb2, 0xff, 0x4f, 0x1f, 0x9c, 0x90, 0x23, 0x22, 0xa3, 0x17, 0xa8, 0x7c, 0xe4, + 0x74, 0xb5, 0xae, 0xac, 0xe4, 0xe3, 0x25, 0x09, 0xc0, 0x1a, 0x87, 0xea, 0x63, 0xed, 0x98, 0x2c, + 0xb7, 0x48, 0xb0, 0xe8, 0xad, 0xc7, 0xe2, 0x32, 0x56, 0x6d, 0x94, 0x6b, 0x1a, 0x84, 0x4d, 0x3c, + 0xaa, 0xdb, 0x3b, 0x86, 0xd2, 0x6a, 0xe8, 0xf6, 0x52, 0x51, 0x95, 0x70, 0xf4, 0x2b, 0xb9, 0xb9, + 0x90, 0x8b, 0x89, 0xf9, 0xeb, 0x08, 0xda, 0x38, 0xe0, 0xbb, 0xa7, 0x7f, 0xd7, 0x82, 0xd3, 0xbc, + 0x54, 0x8e, 0xe4, 0xb5, 0x56, 0xdd, 0x49, 0x48, 0x5c, 0xcc, 0xdb, 0x04, 0x39, 0xfd, 0xd3, 0xe6, + 0xe5, 0x3c, 0xb2, 0x38, 0xbf, 0x37, 0xe8, 0x75, 0x0b, 0x46, 0xb7, 0x52, 0xe9, 0x62, 0xa4, 0xe8, + 0x38, 0x6c, 0x26, 0x87, 0x54, 0xa3, 0x7a, 0xab, 0xa5, 0xcb, 0x63, 0x9c, 0xa5, 0x6e, 0xff, 0x0f, + 0x0b, 0x4c, 0x36, 0x7a, 0xfc, 0x59, 0x66, 0x0e, 0xae, 0x0a, 0x4a, 0xed, 0xb2, 0xd2, 0x55, 0xbb, + 0x7c, 0x14, 0xca, 0x6d, 0xaf, 0x2e, 0xce, 0x17, 0xfa, 0x8a, 0x78, 0x61, 0x0e, 0xd3, 0x72, 0xfb, + 0x9f, 0x57, 0xb4, 0x19, 0x44, 0x84, 0xd4, 0xfd, 0x48, 0x7c, 0xf6, 0x86, 0xca, 0x53, 0xc7, 0xbf, + 0xfc, 0x6a, 0x47, 0x9e, 0xba, 0x9f, 0x3e, 0x78, 0xc4, 0x24, 0x1f, 0xa0, 0x6e, 0x69, 0xea, 0x06, + 0xf6, 0x09, 0x97, 0xbc, 0x09, 0x55, 0x7a, 0x04, 0x63, 0xf6, 0xcc, 0x6a, 0xaa, 0x53, 0xd5, 0x4b, + 0xa2, 0xfc, 0xee, 0xee, 0xc4, 0xbb, 0x0f, 0xde, 0x2d, 0x59, 0x1b, 0xab, 0xf6, 0x51, 0x0c, 0x35, + 0xfa, 0x9b, 0x45, 0x76, 0x8a, 0xc3, 0xdd, 0x35, 0xc5, 0x33, 0x25, 0xa0, 0x90, 0xb0, 0x51, 0x4d, + 0x07, 0x05, 0x50, 0x63, 0x4f, 0x44, 0x33, 0xa2, 0xfc, 0x0c, 0xb8, 0xa2, 0xe2, 0x2b, 0x25, 0xe0, + 0xee, 0xee, 0xc4, 0x0b, 0x07, 0x27, 0xaa, 0xaa, 0x63, 0x4d, 0xc2, 0xfe, 0x52, 0x9f, 0x5e, 0xbb, + 0x22, 0x3d, 0xe1, 0x8f, 0xc4, 0xda, 0x7d, 0x3e, 0xb3, 0x76, 0xcf, 0x75, 0xac, 0xdd, 0x11, 0xfd, + 0x94, 0x71, 0x6a, 0x35, 0x1e, 0xb7, 0x22, 0xb0, 0xbf, 0xbd, 0x81, 0x69, 0x40, 0xaf, 0xb6, 0xbd, + 0x88, 0xc4, 0x2b, 0x51, 0x3b, 0xf0, 0x82, 0x06, 0x5b, 0x8e, 0x55, 0x53, 0x03, 0x4a, 0x81, 0x71, + 0x16, 0x9f, 0x1e, 0xea, 0xe9, 0x9c, 0xdf, 0x70, 0xb6, 0xf9, 0xaa, 0x32, 0x32, 0xb6, 0xad, 0x8a, + 0x72, 0xac, 0x30, 0xec, 0x6f, 0xb0, 0x5b, 0x74, 0x23, 0xa4, 0x9c, 0xae, 0x09, 0x9f, 0xbd, 0xc9, + 0xcd, 0xd3, 0xbd, 0xa9, 0x35, 0xc1, 0x1f, 0xe2, 0xe6, 0x30, 0x74, 0x0b, 0x06, 0xd6, 0xf9, 0xeb, + 0x92, 0xc5, 0x64, 0xdc, 0x17, 0x4f, 0x55, 0xb2, 0x77, 0x7b, 0xe4, 0xbb, 0x95, 0x77, 0xf5, 0x4f, + 0x2c, 0xa9, 0xd9, 0xdf, 0xae, 0xc0, 0x68, 0xe6, 0xd5, 0xe6, 0x54, 0xa2, 0xdd, 0xd2, 0xbe, 0x89, + 0x76, 0x3f, 0x04, 0x50, 0x27, 0x2d, 0x3f, 0xdc, 0x61, 0xea, 0x58, 0xdf, 0x81, 0xd5, 0x31, 0xa5, + 0xc1, 0xcf, 0xa9, 0x56, 0xb0, 0xd1, 0xa2, 0xc8, 0x71, 0xc7, 0xf3, 0xf6, 0x66, 0x72, 0xdc, 0x19, + 0xef, 0x72, 0xf4, 0x1f, 0xef, 0xbb, 0x1c, 0x1e, 0x8c, 0xf2, 0x2e, 0xaa, 0xc0, 0xed, 0x7b, 0x88, + 0xcf, 0x66, 0xa1, 0x2f, 0x73, 0xe9, 0x66, 0x70, 0xb6, 0xdd, 0xfb, 0xf9, 0x28, 0x3b, 0x7a, 0x07, + 0xd4, 0xe4, 0x3c, 0xc7, 0xe3, 0x35, 0x9d, 0xfc, 0x42, 0x2e, 0x03, 0xf6, 0x58, 0xba, 0xf8, 0xd9, + 0x91, 0x83, 0x02, 0xee, 0x57, 0x0e, 0x0a, 0xfb, 0x0b, 0x25, 0xaa, 0xc7, 0xf3, 0x7e, 0xa9, 0x74, + 0x4a, 0x4f, 0x40, 0xbf, 0xd3, 0x4e, 0x36, 0xc3, 0x8e, 0xf7, 0x29, 0xa7, 0x59, 0x29, 0x16, 0x50, + 0xb4, 0x08, 0x7d, 0x75, 0x9d, 0x22, 0xe7, 0x20, 0xf3, 0xa9, 0x4d, 0xa2, 0x4e, 0x42, 0x30, 0x6b, + 0x05, 0x3d, 0x02, 0x7d, 0x89, 0xd3, 0x90, 0xd1, 0x7a, 0x2c, 0x42, 0x7b, 0xcd, 0x69, 0xc4, 0x98, + 0x95, 0x9a, 0xe2, 0xbb, 0x6f, 0x1f, 0xf1, 0xfd, 0x02, 0x0c, 0xc7, 0x5e, 0x23, 0x70, 0x92, 0x76, + 0x44, 0x8c, 0x5b, 0x43, 0xed, 0x33, 0x62, 0x02, 0x71, 0x1a, 0xd7, 0xfe, 0xdd, 0x21, 0x38, 0xb5, + 0x3a, 0xbb, 0x24, 0x13, 0xbf, 0x1f, 0x59, 0xc0, 0x5d, 0x1e, 0x8d, 0xe3, 0x0b, 0xb8, 0xeb, 0x42, + 0xdd, 0x37, 0x02, 0xee, 0x7c, 0x23, 0xe0, 0x2e, 0x1d, 0xfd, 0x54, 0x2e, 0x22, 0xfa, 0x29, 0xaf, + 0x07, 0xbd, 0x44, 0x3f, 0x1d, 0x59, 0x04, 0xde, 0x9e, 0x1d, 0x3a, 0x50, 0x04, 0x9e, 0x0a, 0x4f, + 0x2c, 0x24, 0x2e, 0xa5, 0xcb, 0x54, 0xe5, 0x86, 0x27, 0xaa, 0xd0, 0x30, 0x1e, 0x73, 0x25, 0x58, + 0xfd, 0xcb, 0xc5, 0x77, 0xa0, 0x87, 0xd0, 0x30, 0x11, 0xf6, 0x65, 0x86, 0x23, 0x0e, 0x14, 0x11, + 0x8e, 0x98, 0xd7, 0x9d, 0x7d, 0xc3, 0x11, 0x5f, 0x80, 0x61, 0xd7, 0x0f, 0x03, 0xb2, 0x12, 0x85, + 0x49, 0xe8, 0x86, 0xbe, 0x50, 0xeb, 0xf5, 0x43, 0x34, 0x26, 0x10, 0xa7, 0x71, 0xbb, 0xc5, 0x32, + 0xd6, 0x0e, 0x1b, 0xcb, 0x08, 0xf7, 0x29, 0x96, 0xf1, 0x17, 0x75, 0xd4, 0xfd, 0x20, 0x9b, 0x91, + 0x0f, 0x15, 0x3f, 0x23, 0xbd, 0x84, 0xde, 0xa3, 0x37, 0xf8, 0x03, 0x91, 0x54, 0x31, 0x9e, 0x0d, + 0x9b, 0x54, 0xf1, 0x1b, 0x62, 0x43, 0xf2, 0xca, 0x11, 0x2c, 0xd8, 0x1b, 0xab, 0x9a, 0x8c, 0x7a, + 0x34, 0x52, 0x17, 0xe1, 0x74, 0x47, 0x0e, 0x93, 0x15, 0xe0, 0x2b, 0x25, 0xf8, 0xb1, 0x7d, 0xbb, + 0x80, 0x6e, 0x01, 0x24, 0x4e, 0x43, 0x2c, 0x54, 0x71, 0x61, 0x72, 0x48, 0xc7, 0xce, 0x35, 0xd9, + 0x1e, 0x4f, 0x67, 0xa3, 0xfe, 0xb2, 0xab, 0x08, 0xf9, 0x9b, 0xf9, 0x73, 0x86, 0x7e, 0x47, 0xd6, + 0x4f, 0x1c, 0xfa, 0x04, 0x33, 0x08, 0x15, 0xff, 0x11, 0x69, 0xe8, 0xd7, 0xd5, 0xd5, 0xf4, 0x61, + 0x56, 0x8a, 0x05, 0x14, 0x3d, 0x07, 0x83, 0x8e, 0xef, 0xf3, 0xa0, 0x21, 0x12, 0x8b, 0x17, 0xa2, + 0x74, 0xfa, 0x41, 0x0d, 0xc2, 0x26, 0x9e, 0xfd, 0x17, 0x25, 0x98, 0xd8, 0x87, 0xa7, 0x74, 0x04, + 0x8b, 0x56, 0x7a, 0x0e, 0x16, 0x15, 0x81, 0x14, 0xfd, 0x5d, 0x02, 0x29, 0x9e, 0x83, 0xc1, 0x84, + 0x38, 0x4d, 0xe1, 0x0a, 0x26, 0x2c, 0x01, 0xfa, 0x06, 0x58, 0x83, 0xb0, 0x89, 0x47, 0xb9, 0xd8, + 0x88, 0xe3, 0xba, 0x24, 0x8e, 0x65, 0xa4, 0x84, 0xb0, 0xa6, 0x16, 0x16, 0x86, 0xc1, 0x8c, 0xd4, + 0xd3, 0x29, 0x12, 0x38, 0x43, 0x32, 0x3b, 0xe0, 0xb5, 0x1e, 0x07, 0xfc, 0xeb, 0x25, 0x78, 0x74, + 0x4f, 0xe9, 0xd6, 0x73, 0x10, 0x4b, 0x3b, 0x26, 0x51, 0x76, 0xe1, 0x5c, 0x8b, 0x49, 0x84, 0x19, + 0x84, 0x8f, 0x52, 0xab, 0x65, 0xbc, 0x5e, 0x5f, 0x74, 0x44, 0x17, 0x1f, 0xa5, 0x14, 0x09, 0x9c, + 0x21, 0x79, 0xaf, 0xcb, 0xf2, 0xdb, 0x7d, 0xf0, 0x78, 0x0f, 0x3a, 0x40, 0x81, 0x91, 0x6f, 0xe9, + 0x28, 0xcd, 0xf2, 0x7d, 0x8a, 0xd2, 0xbc, 0xb7, 0xe1, 0x7a, 0x33, 0xb8, 0xb3, 0xa7, 0x08, 0xbb, + 0x6f, 0x94, 0xe0, 0x6c, 0x77, 0x85, 0x05, 0xbd, 0x07, 0x46, 0x23, 0xe5, 0xfa, 0x66, 0x06, 0x78, + 0x9e, 0xe4, 0xf6, 0x96, 0x14, 0x08, 0x67, 0x71, 0xd1, 0x24, 0x40, 0xcb, 0x49, 0x36, 0xe3, 0x0b, + 0xb7, 0xbd, 0x38, 0x11, 0x69, 0x9e, 0x46, 0xf8, 0x0d, 0x9f, 0x2c, 0xc5, 0x06, 0x06, 0x25, 0xc7, + 0xfe, 0xcd, 0x85, 0x57, 0xc3, 0x84, 0x57, 0xe2, 0x87, 0xad, 0x93, 0xf2, 0x51, 0x1c, 0x03, 0x84, + 0xb3, 0xb8, 0x94, 0x1c, 0xbb, 0x43, 0xe6, 0x1d, 0xe5, 0xa7, 0x30, 0x46, 0x6e, 0x51, 0x95, 0x62, + 0x03, 0x23, 0x1b, 0xba, 0x5a, 0xd9, 0x3f, 0x74, 0xd5, 0xfe, 0x67, 0x25, 0x38, 0xd3, 0x55, 0xe1, + 0xed, 0x8d, 0x4d, 0x3d, 0x78, 0xe1, 0xa6, 0xf7, 0xb8, 0xc3, 0x0e, 0x16, 0xa6, 0xf8, 0xa7, 0x5d, + 0x56, 0x9a, 0x08, 0x53, 0xbc, 0xf7, 0xec, 0x0b, 0x0f, 0xde, 0x78, 0x76, 0x44, 0x26, 0xf6, 0x1d, + 0x20, 0x32, 0x31, 0x33, 0x19, 0x95, 0x1e, 0xa5, 0xc3, 0x9f, 0xf7, 0x75, 0x1d, 0x5e, 0x7a, 0x40, + 0xee, 0xc9, 0x9a, 0x3d, 0x07, 0x27, 0xbc, 0x80, 0x3d, 0x90, 0xb6, 0xda, 0x5e, 0x17, 0x99, 0x7f, + 0x78, 0x7a, 0x4b, 0x15, 0xfe, 0xb0, 0x90, 0x81, 0xe3, 0x8e, 0x1a, 0x0f, 0x60, 0xa4, 0xe8, 0xbd, + 0x0d, 0xe9, 0x01, 0x39, 0xf7, 0x32, 0x9c, 0x96, 0x43, 0xb1, 0xe9, 0x44, 0xa4, 0x2e, 0x84, 0x6d, + 0x2c, 0x02, 0x5e, 0xce, 0xf0, 0xa0, 0x99, 0x1c, 0x04, 0x9c, 0x5f, 0x8f, 0xbd, 0x49, 0x15, 0xb6, + 0x3c, 0x57, 0x1c, 0x05, 0xf5, 0x9b, 0x54, 0xb4, 0x10, 0x73, 0x98, 0x96, 0x17, 0xb5, 0xe3, 0x91, + 0x17, 0x1f, 0x82, 0x9a, 0x1a, 0x6f, 0xee, 0xbb, 0xaf, 0x16, 0x79, 0x87, 0xef, 0xbe, 0x5a, 0xe1, + 0x06, 0xd6, 0x7e, 0x8f, 0xa6, 0xbe, 0x13, 0x86, 0x94, 0xf5, 0xab, 0xd7, 0x97, 0xc1, 0xec, 0x2f, + 0xf5, 0xc3, 0x70, 0x2a, 0xdb, 0x67, 0xca, 0xec, 0x6d, 0xed, 0x6b, 0xf6, 0x66, 0x61, 0x1b, 0xed, + 0x40, 0x3e, 0x1b, 0x68, 0x84, 0x6d, 0xb4, 0x03, 0x82, 0x39, 0x8c, 0x1e, 0x3a, 0xea, 0xd1, 0x0e, + 0x6e, 0x07, 0xc2, 0x0f, 0x55, 0x1d, 0x3a, 0xe6, 0x58, 0x29, 0x16, 0x50, 0xf4, 0x71, 0x0b, 0x86, + 0x62, 0x76, 0xa7, 0xc2, 0x2f, 0x0d, 0xc4, 0x22, 0xbf, 0x7c, 0xf8, 0x64, 0xa6, 0x2a, 0xb3, 0x2d, + 0xf3, 0x5b, 0x32, 0x4b, 0x70, 0x8a, 0x22, 0xfa, 0x94, 0x05, 0x35, 0xf5, 0xba, 0x91, 0x78, 0x03, + 0x74, 0xb5, 0xd8, 0x64, 0xaa, 0xdc, 0xda, 0xac, 0xae, 0xa7, 0x54, 0x56, 0x4b, 0xac, 0x09, 0xa3, + 0x58, 0x59, 0xf4, 0x07, 0x8e, 0xc6, 0xa2, 0x0f, 0x39, 0xd6, 0xfc, 0x77, 0x40, 0xad, 0xe9, 0x04, + 0xde, 0x06, 0x89, 0x13, 0x6e, 0x64, 0x97, 0x39, 0x9e, 0x65, 0x21, 0xd6, 0x70, 0xaa, 0x00, 0xc4, + 0xec, 0xc3, 0x12, 0xc3, 0x2a, 0xce, 0x14, 0x80, 0x55, 0x5d, 0x8c, 0x4d, 0x1c, 0xd3, 0x84, 0x0f, + 0xf7, 0xd5, 0x84, 0x3f, 0xb8, 0xb7, 0x09, 0xdf, 0xfe, 0xc7, 0x16, 0x9c, 0xce, 0x9d, 0xb5, 0x07, + 0xd7, 0x1d, 0xd5, 0xfe, 0x72, 0x05, 0x4e, 0xe6, 0xa4, 0xed, 0x45, 0x3b, 0xe6, 0x7a, 0xb6, 0x8a, + 0xf0, 0xec, 0x48, 0x3b, 0x2a, 0xc8, 0x61, 0xcc, 0x59, 0xc4, 0x07, 0xbb, 0x40, 0xd3, 0x97, 0x58, + 0xe5, 0xe3, 0xbd, 0xc4, 0x32, 0x96, 0x65, 0xdf, 0x7d, 0x5d, 0x96, 0x95, 0x7d, 0x6e, 0x96, 0xbe, + 0x69, 0xc1, 0x78, 0xb3, 0xcb, 0x5b, 0x11, 0xc2, 0x1c, 0x7c, 0xfd, 0x68, 0x5e, 0xa2, 0x98, 0x79, + 0xe4, 0xce, 0xee, 0x44, 0xd7, 0x27, 0x3a, 0x70, 0xd7, 0x5e, 0xd9, 0xdf, 0x2f, 0x03, 0xcb, 0x19, + 0xcd, 0x52, 0x33, 0xee, 0xa0, 0x8f, 0x99, 0xd9, 0xbf, 0xad, 0xa2, 0x32, 0x55, 0xf3, 0xc6, 0x55, + 0xf6, 0x70, 0x3e, 0x82, 0x79, 0xc9, 0xc4, 0xb3, 0x4c, 0xab, 0xd4, 0x03, 0xd3, 0xf2, 0x65, 0x9a, + 0xf5, 0x72, 0xf1, 0x69, 0xd6, 0x6b, 0xd9, 0x14, 0xeb, 0x7b, 0x4f, 0x71, 0xdf, 0x03, 0x39, 0xc5, + 0xbf, 0x6a, 0x71, 0xc6, 0x93, 0x99, 0x05, 0xad, 0x19, 0x58, 0x7b, 0x68, 0x06, 0x4f, 0x41, 0x35, + 0x26, 0xfe, 0xc6, 0x25, 0xe2, 0xf8, 0x42, 0x83, 0xd0, 0x5e, 0x05, 0xa2, 0x1c, 0x2b, 0x0c, 0xf6, + 0x0e, 0xb3, 0xef, 0x87, 0xb7, 0x2e, 0x34, 0x5b, 0xc9, 0x8e, 0xd0, 0x25, 0xf4, 0x3b, 0xcc, 0x0a, + 0x82, 0x0d, 0x2c, 0xfb, 0xef, 0x94, 0xf8, 0x0a, 0x14, 0xae, 0x29, 0xcf, 0x67, 0x5e, 0xce, 0xec, + 0xdd, 0xab, 0xe3, 0x23, 0x00, 0x6e, 0xd8, 0x6c, 0x51, 0x3d, 0x73, 0x2d, 0x14, 0x37, 0x75, 0x97, + 0x0e, 0xfd, 0x4e, 0xbf, 0x68, 0x4f, 0x7f, 0x86, 0x2e, 0xc3, 0x06, 0xbd, 0x14, 0x2f, 0x2d, 0xef, + 0xcb, 0x4b, 0x53, 0x6c, 0xa5, 0x6f, 0x1f, 0x69, 0xf7, 0x17, 0x16, 0xa4, 0x34, 0x22, 0xd4, 0x82, + 0x0a, 0xed, 0xee, 0x8e, 0xd8, 0xa1, 0xcb, 0xc5, 0xa9, 0x5f, 0x94, 0x35, 0x8a, 0x65, 0xcf, 0x7e, + 0x62, 0x4e, 0x08, 0xf9, 0xc2, 0x83, 0x85, 0x8f, 0xea, 0xd5, 0xe2, 0x08, 0x5e, 0x0a, 0xc3, 0x2d, + 0x7e, 0xdd, 0xac, 0xbd, 0x61, 0xec, 0xe7, 0x61, 0xac, 0xa3, 0x53, 0xec, 0x91, 0xbc, 0x90, 0x4a, + 0x9f, 0xcc, 0x72, 0x65, 0x01, 0xbd, 0x98, 0xc3, 0xec, 0x6f, 0x58, 0x70, 0x22, 0xdb, 0x3c, 0x7a, + 0xc3, 0x82, 0xb1, 0x38, 0xdb, 0xde, 0x51, 0x8d, 0x9d, 0xf2, 0x42, 0xed, 0x00, 0xe1, 0xce, 0x4e, + 0xd8, 0xff, 0x57, 0x2c, 0xfe, 0x1b, 0x5e, 0x50, 0x0f, 0x6f, 0x29, 0xc5, 0xc4, 0xea, 0xaa, 0x98, + 0xd0, 0xfd, 0xe8, 0x6e, 0x92, 0x7a, 0xdb, 0xef, 0x08, 0x0f, 0x5e, 0x15, 0xe5, 0x58, 0x61, 0xb0, + 0x68, 0xc8, 0xb6, 0x78, 0x87, 0x21, 0xb3, 0x28, 0xe7, 0x44, 0x39, 0x56, 0x18, 0xe8, 0x59, 0x18, + 0x32, 0x3e, 0x52, 0xae, 0x4b, 0xa6, 0x90, 0x1b, 0x22, 0x33, 0xc6, 0x29, 0x2c, 0x34, 0x09, 0xa0, + 0x94, 0x1c, 0x29, 0x22, 0x99, 0x61, 0x4a, 0x71, 0xa2, 0x18, 0x1b, 0x18, 0x2c, 0xf6, 0xd8, 0x6f, + 0xc7, 0xec, 0xe6, 0xa5, 0x5f, 0xe7, 0x06, 0x9e, 0x15, 0x65, 0x58, 0x41, 0x29, 0x37, 0x69, 0x3a, + 0x41, 0xdb, 0xf1, 0xe9, 0x08, 0x89, 0xa3, 0xa6, 0xda, 0x86, 0x4b, 0x0a, 0x82, 0x0d, 0x2c, 0xfa, + 0xc5, 0x89, 0xd7, 0x24, 0x2f, 0x85, 0x81, 0xf4, 0x1e, 0xd4, 0x97, 0x71, 0xa2, 0x1c, 0x2b, 0x0c, + 0xfb, 0xbf, 0x59, 0x30, 0xaa, 0x93, 0x1e, 0xf0, 0xe7, 0xf0, 0xcd, 0x93, 0xb1, 0xb5, 0xef, 0xc9, + 0x38, 0x1d, 0xe2, 0x5d, 0xea, 0x29, 0xc4, 0xdb, 0x8c, 0xbe, 0x2e, 0xef, 0x19, 0x7d, 0xfd, 0x13, + 0xfa, 0xa9, 0x65, 0x1e, 0xa6, 0x3d, 0x98, 0xf7, 0xcc, 0x32, 0xb2, 0xa1, 0xdf, 0x75, 0x54, 0x72, + 0xa0, 0x21, 0x7e, 0x76, 0x98, 0x9d, 0x66, 0x48, 0x02, 0x62, 0x2f, 0x43, 0x4d, 0xdd, 0x49, 0xc9, + 0x83, 0xaa, 0x95, 0x7f, 0x50, 0xed, 0x29, 0x0a, 0x74, 0x66, 0xfd, 0x5b, 0x3f, 0x78, 0xec, 0x2d, + 0x7f, 0xfc, 0x83, 0xc7, 0xde, 0xf2, 0xbd, 0x1f, 0x3c, 0xf6, 0x96, 0x8f, 0xdf, 0x79, 0xcc, 0xfa, + 0xd6, 0x9d, 0xc7, 0xac, 0x3f, 0xbe, 0xf3, 0x98, 0xf5, 0xbd, 0x3b, 0x8f, 0x59, 0xdf, 0xbf, 0xf3, + 0x98, 0xf5, 0xc5, 0xff, 0xfc, 0xd8, 0x5b, 0x5e, 0xca, 0x75, 0x1f, 0xa5, 0x3f, 0x9e, 0x76, 0xeb, + 0x53, 0xdb, 0xe7, 0x99, 0x07, 0x23, 0xdd, 0x5e, 0x53, 0xc6, 0x9a, 0x9a, 0x92, 0xdb, 0xeb, 0xff, + 0x05, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x7b, 0xca, 0xa6, 0xc3, 0xea, 0x00, 0x00, } func (m *AWSAuthConfig) Marshal() (dAtA []byte, err error) { @@ -5361,6 +5464,20 @@ func (m *AppProjectSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.DestinationServiceAccounts) > 0 { + for iNdEx := len(m.DestinationServiceAccounts) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.DestinationServiceAccounts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x72 + } + } i-- if m.PermitOnlyProjectScopedClusters { dAtA[i] = 1 @@ -5719,6 +5836,44 @@ func (m *ApplicationDestination) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *ApplicationDestinationServiceAccount) 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 *ApplicationDestinationServiceAccount) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ApplicationDestinationServiceAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.DefaultServiceAccount) + copy(dAtA[i:], m.DefaultServiceAccount) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DefaultServiceAccount))) + i-- + dAtA[i] = 0x1a + i -= len(m.Namespace) + copy(dAtA[i:], m.Namespace) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) + i-- + dAtA[i] = 0x12 + i -= len(m.Server) + copy(dAtA[i:], m.Server) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Server))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *ApplicationList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -7214,6 +7369,25 @@ func (m *ApplicationSourceHelm) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.APIVersions) > 0 { + for iNdEx := len(m.APIVersions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.APIVersions[iNdEx]) + copy(dAtA[i:], m.APIVersions[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersions[iNdEx]))) + i-- + dAtA[i] = 0x6a + } + } + i -= len(m.KubeVersion) + copy(dAtA[i:], m.KubeVersion) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.KubeVersion))) + i-- + dAtA[i] = 0x62 + i -= len(m.Namespace) + copy(dAtA[i:], m.Namespace) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) + i-- + dAtA[i] = 0x5a if m.ValuesObject != nil { { size, err := m.ValuesObject.MarshalToSizedBuffer(dAtA[:i]) @@ -7385,6 +7559,22 @@ func (m *ApplicationSourceKustomize) MarshalToSizedBuffer(dAtA []byte) (int, err _ = i var l int _ = l + if len(m.APIVersions) > 0 { + for iNdEx := len(m.APIVersions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.APIVersions[iNdEx]) + copy(dAtA[i:], m.APIVersions[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersions[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x82 + } + } + i -= len(m.KubeVersion) + copy(dAtA[i:], m.KubeVersion) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.KubeVersion))) + i-- + dAtA[i] = 0x7a i-- if m.LabelWithoutSelector { dAtA[i] = 1 @@ -7974,6 +8164,9 @@ func (m *ApplicationTree) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i = encodeVarintGenerated(dAtA, i, uint64(m.ShardsCount)) + i-- + dAtA[i] = 0x20 if len(m.Hosts) > 0 { for iNdEx := len(m.Hosts) - 1; iNdEx >= 0; iNdEx-- { { @@ -8135,6 +8328,41 @@ func (m *BasicAuthBitbucketServer) MarshalToSizedBuffer(dAtA []byte) (int, error return len(dAtA) - i, nil } +func (m *BearerTokenBitbucket) 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 *BearerTokenBitbucket) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BearerTokenBitbucket) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.TokenRef != nil { + { + size, err := m.TokenRef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *BearerTokenBitbucketCloud) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -8862,6 +9090,39 @@ func (m *ConfigManagementPlugin) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *ConfigMapKeyRef) 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 *ConfigMapKeyRef) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ConfigMapKeyRef) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Key))) + i-- + dAtA[i] = 0x12 + i -= len(m.ConfigMapName) + copy(dAtA[i:], m.ConfigMapName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ConfigMapName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *ConnectionState) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -11296,6 +11557,38 @@ func (m *PullRequestGeneratorBitbucketServer) MarshalToSizedBuffer(dAtA []byte) _ = i var l int _ = l + if m.CARef != nil { + { + size, err := m.CARef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + i-- + if m.Insecure { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + if m.BearerToken != nil { + { + size, err := m.BearerToken.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } if m.BasicAuth != nil { { size, err := m.BasicAuth.MarshalToSizedBuffer(dAtA[:i]) @@ -11383,6 +11676,18 @@ func (m *PullRequestGeneratorGitLab) MarshalToSizedBuffer(dAtA []byte) (int, err _ = i var l int _ = l + if m.CARef != nil { + { + size, err := m.CARef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } i-- if m.Insecure { dAtA[i] = 1 @@ -11615,6 +11920,13 @@ func (m *RepoCreds) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.NoProxy) + copy(dAtA[i:], m.NoProxy) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.NoProxy))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xba i-- if m.ForceHttpBasicAuth { dAtA[i] = 1 @@ -11766,6 +12078,13 @@ func (m *Repository) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.NoProxy) + copy(dAtA[i:], m.NoProxy) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.NoProxy))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xba i-- if m.ForceHttpBasicAuth { dAtA[i] = 1 @@ -12212,6 +12531,14 @@ func (m *ResourceActions) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i-- + if m.MergeBuiltinActions { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 if len(m.Definitions) > 0 { for iNdEx := len(m.Definitions) - 1; iNdEx >= 0; iNdEx-- { { @@ -13439,6 +13766,38 @@ func (m *SCMProviderGeneratorBitbucketServer) MarshalToSizedBuffer(dAtA []byte) _ = i var l int _ = l + if m.CARef != nil { + { + size, err := m.CARef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + i-- + if m.Insecure { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + if m.BearerToken != nil { + { + size, err := m.BearerToken.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } i-- if m.AllBranches { dAtA[i] = 1 @@ -13673,6 +14032,18 @@ func (m *SCMProviderGeneratorGitlab) MarshalToSizedBuffer(dAtA []byte) (int, err _ = i var l int _ = l + if m.CARef != nil { + { + size, err := m.CARef.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a + } i -= len(m.Topic) copy(dAtA[i:], m.Topic) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Topic))) @@ -14628,6 +14999,12 @@ func (m *AppProjectSpec) Size() (n int) { } } n += 2 + if len(m.DestinationServiceAccounts) > 0 { + for _, e := range m.DestinationServiceAccounts { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -14700,6 +15077,21 @@ func (m *ApplicationDestination) Size() (n int) { return n } +func (m *ApplicationDestinationServiceAccount) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Server) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Namespace) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.DefaultServiceAccount) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *ApplicationList) Size() (n int) { if m == nil { return 0 @@ -15287,6 +15679,16 @@ func (m *ApplicationSourceHelm) Size() (n int) { l = m.ValuesObject.Size() n += 1 + l + sovGenerated(uint64(l)) } + l = len(m.Namespace) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.KubeVersion) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.APIVersions) > 0 { + for _, s := range m.APIVersions { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -15375,6 +15777,14 @@ func (m *ApplicationSourceKustomize) Size() (n int) { } } n += 2 + l = len(m.KubeVersion) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.APIVersions) > 0 { + for _, s := range m.APIVersions { + l = len(s) + n += 2 + l + sovGenerated(uint64(l)) + } + } return n } @@ -15568,6 +15978,7 @@ func (m *ApplicationTree) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + n += 1 + sovGenerated(uint64(m.ShardsCount)) return n } @@ -15615,6 +16026,19 @@ func (m *BasicAuthBitbucketServer) Size() (n int) { return n } +func (m *BearerTokenBitbucket) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.TokenRef != nil { + l = m.TokenRef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + func (m *BearerTokenBitbucketCloud) Size() (n int) { if m == nil { return 0 @@ -15879,6 +16303,19 @@ func (m *ConfigManagementPlugin) Size() (n int) { return n } +func (m *ConfigMapKeyRef) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ConfigMapName) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Key) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *ConnectionState) Size() (n int) { if m == nil { return 0 @@ -16810,6 +17247,15 @@ func (m *PullRequestGeneratorBitbucketServer) Size() (n int) { l = m.BasicAuth.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.BearerToken != nil { + l = m.BearerToken.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + n += 2 + if m.CARef != nil { + l = m.CARef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -16853,6 +17299,10 @@ func (m *PullRequestGeneratorGitLab) Size() (n int) { l = len(m.PullRequestState) n += 1 + l + sovGenerated(uint64(l)) n += 2 + if m.CARef != nil { + l = m.CARef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -16950,6 +17400,8 @@ func (m *RepoCreds) Size() (n int) { l = len(m.Proxy) n += 2 + l + sovGenerated(uint64(l)) n += 3 + l = len(m.NoProxy) + n += 2 + l + sovGenerated(uint64(l)) return n } @@ -17012,6 +17464,8 @@ func (m *Repository) Size() (n int) { l = len(m.GCPServiceAccountKey) n += 2 + l + sovGenerated(uint64(l)) n += 3 + l = len(m.NoProxy) + n += 2 + l + sovGenerated(uint64(l)) return n } @@ -17136,6 +17590,7 @@ func (m *ResourceActions) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + n += 2 return n } @@ -17595,6 +18050,15 @@ func (m *SCMProviderGeneratorBitbucketServer) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } n += 2 + if m.BearerToken != nil { + l = m.BearerToken.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + n += 2 + if m.CARef != nil { + l = m.CARef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -17692,6 +18156,10 @@ func (m *SCMProviderGeneratorGitlab) Size() (n int) { } l = len(m.Topic) n += 1 + l + sovGenerated(uint64(l)) + if m.CARef != nil { + l = m.CARef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -18083,6 +18551,11 @@ func (this *AppProjectSpec) String() string { repeatedStringForClusterResourceBlacklist += fmt.Sprintf("%v", f) + "," } repeatedStringForClusterResourceBlacklist += "}" + repeatedStringForDestinationServiceAccounts := "[]ApplicationDestinationServiceAccount{" + for _, f := range this.DestinationServiceAccounts { + repeatedStringForDestinationServiceAccounts += strings.Replace(strings.Replace(f.String(), "ApplicationDestinationServiceAccount", "ApplicationDestinationServiceAccount", 1), `&`, ``, 1) + "," + } + repeatedStringForDestinationServiceAccounts += "}" s := strings.Join([]string{`&AppProjectSpec{`, `SourceRepos:` + fmt.Sprintf("%v", this.SourceRepos) + `,`, `Destinations:` + repeatedStringForDestinations + `,`, @@ -18097,6 +18570,7 @@ func (this *AppProjectSpec) String() string { `ClusterResourceBlacklist:` + repeatedStringForClusterResourceBlacklist + `,`, `SourceNamespaces:` + fmt.Sprintf("%v", this.SourceNamespaces) + `,`, `PermitOnlyProjectScopedClusters:` + fmt.Sprintf("%v", this.PermitOnlyProjectScopedClusters) + `,`, + `DestinationServiceAccounts:` + repeatedStringForDestinationServiceAccounts + `,`, `}`, }, "") return s @@ -18158,6 +18632,18 @@ func (this *ApplicationDestination) String() string { }, "") return s } +func (this *ApplicationDestinationServiceAccount) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ApplicationDestinationServiceAccount{`, + `Server:` + fmt.Sprintf("%v", this.Server) + `,`, + `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, + `DefaultServiceAccount:` + fmt.Sprintf("%v", this.DefaultServiceAccount) + `,`, + `}`, + }, "") + return s +} func (this *ApplicationList) String() string { if this == nil { return "nil" @@ -18546,6 +19032,9 @@ func (this *ApplicationSourceHelm) String() string { `IgnoreMissingValueFiles:` + fmt.Sprintf("%v", this.IgnoreMissingValueFiles) + `,`, `SkipCrds:` + fmt.Sprintf("%v", this.SkipCrds) + `,`, `ValuesObject:` + strings.Replace(fmt.Sprintf("%v", this.ValuesObject), "RawExtension", "runtime.RawExtension", 1) + `,`, + `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, + `KubeVersion:` + fmt.Sprintf("%v", this.KubeVersion) + `,`, + `APIVersions:` + fmt.Sprintf("%v", this.APIVersions) + `,`, `}`, }, "") return s @@ -18621,6 +19110,8 @@ func (this *ApplicationSourceKustomize) String() string { `Patches:` + repeatedStringForPatches + `,`, `Components:` + fmt.Sprintf("%v", this.Components) + `,`, `LabelWithoutSelector:` + fmt.Sprintf("%v", this.LabelWithoutSelector) + `,`, + `KubeVersion:` + fmt.Sprintf("%v", this.KubeVersion) + `,`, + `APIVersions:` + fmt.Sprintf("%v", this.APIVersions) + `,`, `}`, }, "") return s @@ -18763,6 +19254,7 @@ func (this *ApplicationTree) String() string { `Nodes:` + repeatedStringForNodes + `,`, `OrphanedNodes:` + repeatedStringForOrphanedNodes + `,`, `Hosts:` + repeatedStringForHosts + `,`, + `ShardsCount:` + fmt.Sprintf("%v", this.ShardsCount) + `,`, `}`, }, "") return s @@ -18801,6 +19293,16 @@ func (this *BasicAuthBitbucketServer) String() string { }, "") return s } +func (this *BearerTokenBitbucket) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&BearerTokenBitbucket{`, + `TokenRef:` + strings.Replace(this.TokenRef.String(), "SecretRef", "SecretRef", 1) + `,`, + `}`, + }, "") + return s +} func (this *BearerTokenBitbucketCloud) String() string { if this == nil { return "nil" @@ -19003,6 +19505,17 @@ func (this *ConfigManagementPlugin) String() string { }, "") return s } +func (this *ConfigMapKeyRef) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ConfigMapKeyRef{`, + `ConfigMapName:` + fmt.Sprintf("%v", this.ConfigMapName) + `,`, + `Key:` + fmt.Sprintf("%v", this.Key) + `,`, + `}`, + }, "") + return s +} func (this *ConnectionState) String() string { if this == nil { return "nil" @@ -19761,6 +20274,9 @@ func (this *PullRequestGeneratorBitbucketServer) String() string { `Repo:` + fmt.Sprintf("%v", this.Repo) + `,`, `API:` + fmt.Sprintf("%v", this.API) + `,`, `BasicAuth:` + strings.Replace(this.BasicAuth.String(), "BasicAuthBitbucketServer", "BasicAuthBitbucketServer", 1) + `,`, + `BearerToken:` + strings.Replace(this.BearerToken.String(), "BearerTokenBitbucket", "BearerTokenBitbucket", 1) + `,`, + `Insecure:` + fmt.Sprintf("%v", this.Insecure) + `,`, + `CARef:` + strings.Replace(this.CARef.String(), "ConfigMapKeyRef", "ConfigMapKeyRef", 1) + `,`, `}`, }, "") return s @@ -19787,6 +20303,7 @@ func (this *PullRequestGeneratorGitLab) String() string { `Labels:` + fmt.Sprintf("%v", this.Labels) + `,`, `PullRequestState:` + fmt.Sprintf("%v", this.PullRequestState) + `,`, `Insecure:` + fmt.Sprintf("%v", this.Insecure) + `,`, + `CARef:` + strings.Replace(this.CARef.String(), "ConfigMapKeyRef", "ConfigMapKeyRef", 1) + `,`, `}`, }, "") return s @@ -19852,6 +20369,7 @@ func (this *RepoCreds) String() string { `GCPServiceAccountKey:` + fmt.Sprintf("%v", this.GCPServiceAccountKey) + `,`, `Proxy:` + fmt.Sprintf("%v", this.Proxy) + `,`, `ForceHttpBasicAuth:` + fmt.Sprintf("%v", this.ForceHttpBasicAuth) + `,`, + `NoProxy:` + fmt.Sprintf("%v", this.NoProxy) + `,`, `}`, }, "") return s @@ -19899,6 +20417,7 @@ func (this *Repository) String() string { `Project:` + fmt.Sprintf("%v", this.Project) + `,`, `GCPServiceAccountKey:` + fmt.Sprintf("%v", this.GCPServiceAccountKey) + `,`, `ForceHttpBasicAuth:` + fmt.Sprintf("%v", this.ForceHttpBasicAuth) + `,`, + `NoProxy:` + fmt.Sprintf("%v", this.NoProxy) + `,`, `}`, }, "") return s @@ -20004,6 +20523,7 @@ func (this *ResourceActions) String() string { s := strings.Join([]string{`&ResourceActions{`, `ActionDiscoveryLua:` + fmt.Sprintf("%v", this.ActionDiscoveryLua) + `,`, `Definitions:` + repeatedStringForDefinitions + `,`, + `MergeBuiltinActions:` + fmt.Sprintf("%v", this.MergeBuiltinActions) + `,`, `}`, }, "") return s @@ -20326,6 +20846,9 @@ func (this *SCMProviderGeneratorBitbucketServer) String() string { `API:` + fmt.Sprintf("%v", this.API) + `,`, `BasicAuth:` + strings.Replace(this.BasicAuth.String(), "BasicAuthBitbucketServer", "BasicAuthBitbucketServer", 1) + `,`, `AllBranches:` + fmt.Sprintf("%v", this.AllBranches) + `,`, + `BearerToken:` + strings.Replace(this.BearerToken.String(), "BearerTokenBitbucket", "BearerTokenBitbucket", 1) + `,`, + `Insecure:` + fmt.Sprintf("%v", this.Insecure) + `,`, + `CARef:` + strings.Replace(this.CARef.String(), "ConfigMapKeyRef", "ConfigMapKeyRef", 1) + `,`, `}`, }, "") return s @@ -20385,6 +20908,7 @@ func (this *SCMProviderGeneratorGitlab) String() string { `Insecure:` + fmt.Sprintf("%v", this.Insecure) + `,`, `IncludeSharedProjects:` + valueToStringGenerated(this.IncludeSharedProjects) + `,`, `Topic:` + fmt.Sprintf("%v", this.Topic) + `,`, + `CARef:` + strings.Replace(this.CARef.String(), "ConfigMapKeyRef", "ConfigMapKeyRef", 1) + `,`, `}`, }, "") return s @@ -21461,6 +21985,40 @@ func (m *AppProjectSpec) Unmarshal(dAtA []byte) error { } } m.PermitOnlyProjectScopedClusters = bool(v != 0) + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DestinationServiceAccounts", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DestinationServiceAccounts = append(m.DestinationServiceAccounts, ApplicationDestinationServiceAccount{}) + if err := m.DestinationServiceAccounts[len(m.DestinationServiceAccounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -22142,6 +22700,152 @@ func (m *ApplicationDestination) Unmarshal(dAtA []byte) error { } return nil } +func (m *ApplicationDestinationServiceAccount) 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: ApplicationDestinationServiceAccount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ApplicationDestinationServiceAccount: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Server", 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.Server = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", 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.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DefaultServiceAccount", 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.DefaultServiceAccount = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ApplicationList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -26799,14 +27503,142 @@ func (m *ApplicationSourceHelm) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.FileParameters = append(m.FileParameters, HelmFileParameter{}) - if err := m.FileParameters[len(m.FileParameters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.FileParameters = append(m.FileParameters, HelmFileParameter{}) + if err := m.FileParameters[len(m.FileParameters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", 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.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PassCredentials", 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.PassCredentials = bool(v != 0) + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IgnoreMissingValueFiles", 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.IgnoreMissingValueFiles = bool(v != 0) + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SkipCrds", 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.SkipCrds = bool(v != 0) + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValuesObject", 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.ValuesObject == nil { + m.ValuesObject = &runtime.RawExtension{} + } + if err := m.ValuesObject.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 6: + case 11: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -26834,13 +27666,13 @@ func (m *ApplicationSourceHelm) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Version = string(dAtA[iNdEx:postIndex]) + m.Namespace = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field PassCredentials", wireType) + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KubeVersion", wireType) } - var v int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -26850,57 +27682,29 @@ func (m *ApplicationSourceHelm) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.PassCredentials = bool(v != 0) - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field IgnoreMissingValueFiles", 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 - } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated } - m.IgnoreMissingValueFiles = bool(v != 0) - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field SkipCrds", wireType) + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated } - 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 - } + if postIndex > l { + return io.ErrUnexpectedEOF } - m.SkipCrds = bool(v != 0) - case 10: + m.KubeVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 13: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ValuesObject", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field APIVersions", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -26910,27 +27714,23 @@ func (m *ApplicationSourceHelm) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if m.ValuesObject == nil { - m.ValuesObject = &runtime.RawExtension{} - } - if err := m.ValuesObject.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.APIVersions = append(m.APIVersions, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -27584,99 +28384,183 @@ func (m *ApplicationSourceKustomize) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Namespace = string(dAtA[iNdEx:postIndex]) + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CommonAnnotationsEnvsubst", 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.CommonAnnotationsEnvsubst = bool(v != 0) + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Replicas", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Replicas = append(m.Replicas, KustomizeReplica{}) + if err := m.Replicas[len(m.Replicas)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Patches", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Patches = append(m.Patches, KustomizePatch{}) + if err := m.Patches[len(m.Patches)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Components", 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.Components = append(m.Components, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 14: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LabelWithoutSelector", 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.LabelWithoutSelector = bool(v != 0) + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KubeVersion", 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.KubeVersion = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 10: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CommonAnnotationsEnvsubst", 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.CommonAnnotationsEnvsubst = bool(v != 0) - case 11: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Replicas", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Replicas = append(m.Replicas, KustomizeReplica{}) - if err := m.Replicas[len(m.Replicas)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 12: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Patches", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Patches = append(m.Patches, KustomizePatch{}) - if err := m.Patches[len(m.Patches)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 13: + case 16: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Components", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field APIVersions", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -27704,28 +28588,8 @@ func (m *ApplicationSourceKustomize) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Components = append(m.Components, string(dAtA[iNdEx:postIndex])) + m.APIVersions = append(m.APIVersions, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 14: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LabelWithoutSelector", 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.LabelWithoutSelector = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -29125,6 +29989,25 @@ func (m *ApplicationTree) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ShardsCount", wireType) + } + m.ShardsCount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ShardsCount |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -29261,7 +30144,141 @@ func (m *ApplicationWatchEvent) Unmarshal(dAtA []byte) error { } return nil } -func (m *Backoff) Unmarshal(dAtA []byte) error { +func (m *Backoff) 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: Backoff: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Backoff: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Duration", 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.Duration = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Factor", wireType) + } + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Factor = &v + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxDuration", 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.MaxDuration = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BasicAuthBitbucketServer) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -29284,15 +30301,15 @@ func (m *Backoff) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Backoff: wiretype end group for non-group") + return fmt.Errorf("proto: BasicAuthBitbucketServer: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Backoff: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: BasicAuthBitbucketServer: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -29320,33 +30337,13 @@ func (m *Backoff) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Duration = string(dAtA[iNdEx:postIndex]) + m.Username = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Factor", wireType) - } - var v int64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.Factor = &v - case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxDuration", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PasswordRef", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -29356,23 +30353,27 @@ func (m *Backoff) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.MaxDuration = string(dAtA[iNdEx:postIndex]) + if m.PasswordRef == nil { + m.PasswordRef = &SecretRef{} + } + if err := m.PasswordRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -29395,7 +30396,7 @@ func (m *Backoff) Unmarshal(dAtA []byte) error { } return nil } -func (m *BasicAuthBitbucketServer) Unmarshal(dAtA []byte) error { +func (m *BearerTokenBitbucket) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -29418,47 +30419,15 @@ func (m *BasicAuthBitbucketServer) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: BasicAuthBitbucketServer: wiretype end group for non-group") + return fmt.Errorf("proto: BearerTokenBitbucket: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: BasicAuthBitbucketServer: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: BearerTokenBitbucket: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 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.Username = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PasswordRef", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TokenRef", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -29485,10 +30454,10 @@ func (m *BasicAuthBitbucketServer) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.PasswordRef == nil { - m.PasswordRef = &SecretRef{} + if m.TokenRef == nil { + m.TokenRef = &SecretRef{} } - if err := m.PasswordRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.TokenRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -31821,49 +32790,184 @@ func (m *ConfigManagementPlugin) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Init", 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.Init == nil { + m.Init = &Command{} + } + if err := m.Init.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Generate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Generate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LockRepo", 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.LockRepo = bool(v != 0) + 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 *ConfigMapKeyRef) 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: ConfigMapKeyRef: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConfigMapKeyRef: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConfigMapName", 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.ConfigMapName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Init", 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.Init == nil { - m.Init = &Command{} - } - if err := m.Init.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Generate", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -31873,45 +32977,24 @@ func (m *ConfigManagementPlugin) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Generate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Key = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LockRepo", 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.LockRepo = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -39755,11 +40838,197 @@ func (m *PullRequestGeneratorBitbucket) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Repo = string(dAtA[iNdEx:postIndex]) + m.Repo = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field API", 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.API = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BasicAuth", 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.BasicAuth == nil { + m.BasicAuth = &BasicAuthBitbucketServer{} + } + if err := m.BasicAuth.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BearerToken", 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.BearerToken == nil { + m.BearerToken = &BearerTokenBitbucketCloud{} + } + if err := m.BearerToken.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 *PullRequestGeneratorBitbucketServer) 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: PullRequestGeneratorBitbucketServer: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PullRequestGeneratorBitbucketServer: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", 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.Project = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field API", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Repo", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -39787,13 +41056,13 @@ func (m *PullRequestGeneratorBitbucket) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.API = string(dAtA[iNdEx:postIndex]) + m.Repo = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BasicAuth", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field API", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -39803,31 +41072,27 @@ func (m *PullRequestGeneratorBitbucket) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if m.BasicAuth == nil { - m.BasicAuth = &BasicAuthBitbucketServer{} - } - if err := m.BasicAuth.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.API = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BearerToken", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BasicAuth", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -39854,68 +41119,18 @@ func (m *PullRequestGeneratorBitbucket) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.BearerToken == nil { - m.BearerToken = &BearerTokenBitbucketCloud{} + if m.BasicAuth == nil { + m.BasicAuth = &BasicAuthBitbucketServer{} } - if err := m.BearerToken.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.BasicAuth.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 *PullRequestGeneratorBitbucketServer) 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: PullRequestGeneratorBitbucketServer: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PullRequestGeneratorBitbucketServer: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BearerToken", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -39925,61 +41140,33 @@ func (m *PullRequestGeneratorBitbucketServer) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Project = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Repo", 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 m.BearerToken == nil { + m.BearerToken = &BearerTokenBitbucket{} } - if postIndex > l { - return io.ErrUnexpectedEOF + if err := m.BearerToken.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - m.Repo = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field API", wireType) + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Insecure", wireType) } - var stringLen uint64 + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -39989,27 +41176,15 @@ func (m *PullRequestGeneratorBitbucketServer) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int(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.API = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: + m.Insecure = bool(v != 0) + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BasicAuth", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CARef", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -40036,10 +41211,10 @@ func (m *PullRequestGeneratorBitbucketServer) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.BasicAuth == nil { - m.BasicAuth = &BasicAuthBitbucketServer{} + if m.CARef == nil { + m.CARef = &ConfigMapKeyRef{} } - if err := m.BasicAuth.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.CARef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -40393,6 +41568,42 @@ func (m *PullRequestGeneratorGitLab) Unmarshal(dAtA []byte) error { } } m.Insecure = bool(v != 0) + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CARef", 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.CARef == nil { + m.CARef = &ConfigMapKeyRef{} + } + if err := m.CARef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -41468,6 +42679,38 @@ func (m *RepoCreds) Unmarshal(dAtA []byte) error { } } m.ForceHttpBasicAuth = bool(v != 0) + case 23: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NoProxy", 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.NoProxy = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -42188,11 +43431,63 @@ func (m *Repository) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Project = string(dAtA[iNdEx:postIndex]) + m.Project = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 21: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GCPServiceAccountKey", 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.GCPServiceAccountKey = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 21: + case 22: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ForceHttpBasicAuth", 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.ForceHttpBasicAuth = bool(v != 0) + case 23: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GCPServiceAccountKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NoProxy", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -42220,28 +43515,8 @@ func (m *Repository) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.GCPServiceAccountKey = string(dAtA[iNdEx:postIndex]) + m.NoProxy = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 22: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ForceHttpBasicAuth", 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.ForceHttpBasicAuth = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -43296,6 +44571,26 @@ func (m *ResourceActions) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MergeBuiltinActions", 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.MergeBuiltinActions = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -47170,13 +48465,211 @@ func (m *SCMProviderGeneratorAWSCodeCommit) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Role = string(dAtA[iNdEx:postIndex]) + m.Role = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Region", 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.Region = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AllBranches", 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.AllBranches = bool(v != 0) + 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 *SCMProviderGeneratorAzureDevOps) 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: SCMProviderGeneratorAzureDevOps: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SCMProviderGeneratorAzureDevOps: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Organization", 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.Organization = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field API", 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.API = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TeamProject", 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.TeamProject = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Region", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AccessTokenRef", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -47186,25 +48679,29 @@ func (m *SCMProviderGeneratorAWSCodeCommit) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Region = string(dAtA[iNdEx:postIndex]) + if m.AccessTokenRef == nil { + m.AccessTokenRef = &SecretRef{} + } + if err := m.AccessTokenRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 4: + case 9: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field AllBranches", wireType) } @@ -47245,7 +48742,7 @@ func (m *SCMProviderGeneratorAWSCodeCommit) Unmarshal(dAtA []byte) error { } return nil } -func (m *SCMProviderGeneratorAzureDevOps) Unmarshal(dAtA []byte) error { +func (m *SCMProviderGeneratorBitbucket) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -47268,47 +48765,15 @@ func (m *SCMProviderGeneratorAzureDevOps) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SCMProviderGeneratorAzureDevOps: wiretype end group for non-group") + return fmt.Errorf("proto: SCMProviderGeneratorBitbucket: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SCMProviderGeneratorAzureDevOps: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SCMProviderGeneratorBitbucket: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Organization", 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.Organization = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field API", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -47336,11 +48801,11 @@ func (m *SCMProviderGeneratorAzureDevOps) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.API = string(dAtA[iNdEx:postIndex]) + m.Owner = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 7: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TeamProject", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -47368,11 +48833,11 @@ func (m *SCMProviderGeneratorAzureDevOps) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.TeamProject = string(dAtA[iNdEx:postIndex]) + m.User = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 8: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AccessTokenRef", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AppPasswordRef", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -47399,14 +48864,14 @@ func (m *SCMProviderGeneratorAzureDevOps) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.AccessTokenRef == nil { - m.AccessTokenRef = &SecretRef{} + if m.AppPasswordRef == nil { + m.AppPasswordRef = &SecretRef{} } - if err := m.AccessTokenRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.AppPasswordRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 9: + case 4: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field AllBranches", wireType) } @@ -47447,7 +48912,7 @@ func (m *SCMProviderGeneratorAzureDevOps) Unmarshal(dAtA []byte) error { } return nil } -func (m *SCMProviderGeneratorBitbucket) Unmarshal(dAtA []byte) error { +func (m *SCMProviderGeneratorBitbucketServer) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -47470,15 +48935,15 @@ func (m *SCMProviderGeneratorBitbucket) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SCMProviderGeneratorBitbucket: wiretype end group for non-group") + return fmt.Errorf("proto: SCMProviderGeneratorBitbucketServer: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SCMProviderGeneratorBitbucket: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SCMProviderGeneratorBitbucketServer: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -47506,11 +48971,11 @@ func (m *SCMProviderGeneratorBitbucket) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Owner = string(dAtA[iNdEx:postIndex]) + m.Project = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field API", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -47538,11 +49003,11 @@ func (m *SCMProviderGeneratorBitbucket) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.User = string(dAtA[iNdEx:postIndex]) + m.API = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AppPasswordRef", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BasicAuth", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -47569,10 +49034,10 @@ func (m *SCMProviderGeneratorBitbucket) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.AppPasswordRef == nil { - m.AppPasswordRef = &SecretRef{} + if m.BasicAuth == nil { + m.BasicAuth = &BasicAuthBitbucketServer{} } - if err := m.AppPasswordRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.BasicAuth.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -47596,61 +49061,11 @@ func (m *SCMProviderGeneratorBitbucket) Unmarshal(dAtA []byte) error { } } m.AllBranches = bool(v != 0) - 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 *SCMProviderGeneratorBitbucketServer) 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: SCMProviderGeneratorBitbucketServer: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SCMProviderGeneratorBitbucketServer: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BearerToken", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -47660,29 +49075,33 @@ func (m *SCMProviderGeneratorBitbucketServer) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Project = string(dAtA[iNdEx:postIndex]) + if m.BearerToken == nil { + m.BearerToken = &BearerTokenBitbucket{} + } + if err := m.BearerToken.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field API", wireType) + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Insecure", wireType) } - var stringLen uint64 + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -47692,27 +49111,15 @@ func (m *SCMProviderGeneratorBitbucketServer) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int(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.API = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: + m.Insecure = bool(v != 0) + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BasicAuth", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CARef", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -47739,33 +49146,13 @@ func (m *SCMProviderGeneratorBitbucketServer) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.BasicAuth == nil { - m.BasicAuth = &BasicAuthBitbucketServer{} + if m.CARef == nil { + m.CARef = &ConfigMapKeyRef{} } - if err := m.BasicAuth.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.CARef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AllBranches", 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.AllBranches = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -48634,6 +50021,42 @@ func (m *SCMProviderGeneratorGitlab) Unmarshal(dAtA []byte) error { } m.Topic = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CARef", 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.CARef == nil { + m.CARef = &ConfigMapKeyRef{} + } + if err := m.CARef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + 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 bc162dca1fc3f..0b79d47202cb9 100644 --- a/pkg/apis/application/v1alpha1/generated.proto +++ b/pkg/apis/application/v1alpha1/generated.proto @@ -38,7 +38,7 @@ message AWSAuthConfig { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:resource:path=appprojects,shortName=appproj;appprojs message AppProject { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; optional AppProjectSpec spec = 2; @@ -48,7 +48,7 @@ message AppProject { // AppProjectList is list of AppProject resources // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object message AppProjectList { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; repeated AppProject items = 2; } @@ -68,10 +68,10 @@ message AppProjectSpec { repeated ProjectRole roles = 4; // ClusterResourceWhitelist contains list of whitelisted cluster level resources - repeated k8s.io.apimachinery.pkg.apis.meta.v1.GroupKind clusterResourceWhitelist = 5; + repeated .k8s.io.apimachinery.pkg.apis.meta.v1.GroupKind clusterResourceWhitelist = 5; // NamespaceResourceBlacklist contains list of blacklisted namespace level resources - repeated k8s.io.apimachinery.pkg.apis.meta.v1.GroupKind namespaceResourceBlacklist = 6; + repeated .k8s.io.apimachinery.pkg.apis.meta.v1.GroupKind namespaceResourceBlacklist = 6; // OrphanedResources specifies if controller should monitor orphaned resources of apps in this project optional OrphanedResourcesMonitorSettings orphanedResources = 7; @@ -80,19 +80,22 @@ message AppProjectSpec { repeated SyncWindow syncWindows = 8; // NamespaceResourceWhitelist contains list of whitelisted namespace level resources - repeated k8s.io.apimachinery.pkg.apis.meta.v1.GroupKind namespaceResourceWhitelist = 9; + repeated .k8s.io.apimachinery.pkg.apis.meta.v1.GroupKind namespaceResourceWhitelist = 9; // SignatureKeys contains a list of PGP key IDs that commits in Git must be signed with in order to be allowed for sync repeated SignatureKey signatureKeys = 10; // ClusterResourceBlacklist contains list of blacklisted cluster level resources - repeated k8s.io.apimachinery.pkg.apis.meta.v1.GroupKind clusterResourceBlacklist = 11; + repeated .k8s.io.apimachinery.pkg.apis.meta.v1.GroupKind clusterResourceBlacklist = 11; // SourceNamespaces defines the namespaces application resources are allowed to be created in repeated string sourceNamespaces = 12; // PermitOnlyProjectScopedClusters determines whether destinations can only reference clusters which are project-scoped optional bool permitOnlyProjectScopedClusters = 13; + + // DestinationServiceAccounts holds information about the service accounts to be impersonated for the application sync operation for each destination. + repeated ApplicationDestinationServiceAccount destinationServiceAccounts = 14; } // AppProjectStatus contains status information for AppProject CRs @@ -111,7 +114,7 @@ message AppProjectStatus { // +kubebuilder:printcolumn:name="Revision",type=string,JSONPath=`.status.sync.revision`,priority=10 // +kubebuilder:printcolumn:name="Project",type=string,JSONPath=`.spec.project`,priority=10 message Application { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; optional ApplicationSpec spec = 2; @@ -129,7 +132,7 @@ message ApplicationCondition { optional string message = 2; // LastTransitionTime is the time the condition was last observed - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 3; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 3; } // ApplicationDestination holds information about the application's destination @@ -145,10 +148,22 @@ message ApplicationDestination { optional string name = 3; } +// ApplicationDestinationServiceAccount holds information about the service account to be impersonated for the application sync operation. +message ApplicationDestinationServiceAccount { + // Server specifies the URL of the target cluster's Kubernetes control plane API. + optional string server = 1; + + // Namespace specifies the target namespace for the application's resources. + optional string namespace = 2; + + // ServiceAccountName to be used for impersonation during the sync operation + optional string defaultServiceAccount = 3; +} + // ApplicationList is list of Application resources // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object message ApplicationList { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; repeated Application items = 2; } @@ -174,7 +189,7 @@ message ApplicationPreservedFields { // +kubebuilder:resource:path=applicationsets,shortName=appset;appsets // +kubebuilder:subresource:status message ApplicationSet { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; optional ApplicationSetSpec spec = 2; @@ -187,7 +202,7 @@ message ApplicationSetApplicationStatus { optional string application = 1; // LastTransitionTime is the time the status was last updated - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 2; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 2; // Message contains human-readable message indicating details about the status optional string message = 3; @@ -211,7 +226,7 @@ message ApplicationSetCondition { optional string message = 2; // LastTransitionTime is the time the condition was last observed - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 3; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastTransitionTime = 3; // True/False/Unknown optional string status = 4; @@ -239,7 +254,7 @@ message ApplicationSetGenerator { optional MergeGenerator merge = 8; // Selector allows to post-filter all generator. - optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 9; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 9; optional PluginGenerator plugin = 10; } @@ -248,7 +263,7 @@ message ApplicationSetGenerator { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:object:root=true message ApplicationSetList { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; repeated ApplicationSet items = 2; } @@ -269,13 +284,13 @@ message ApplicationSetNestedGenerator { optional PullRequestGenerator pullRequest = 6; // Matrix should have the form of NestedMatrixGenerator - optional k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1.JSON matrix = 7; + optional .k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1.JSON matrix = 7; // Merge should have the form of NestedMergeGenerator - optional k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1.JSON merge = 8; + optional .k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1.JSON merge = 8; // Selector allows to post-filter all generator. - optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 9; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 9; optional PluginGenerator plugin = 10; } @@ -296,7 +311,7 @@ message ApplicationSetResourceIgnoreDifferences { message ApplicationSetRolloutStep { repeated ApplicationMatchExpression matchExpressions = 1; - optional k8s.io.apimachinery.pkg.util.intstr.IntOrString maxUpdate = 2; + optional .k8s.io.apimachinery.pkg.util.intstr.IntOrString maxUpdate = 2; } message ApplicationSetRolloutStrategy { @@ -399,7 +414,7 @@ message ApplicationSetTerminalGenerator { optional PluginGenerator plugin = 7; // Selector allows to post-filter all generator. - optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 8; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 8; } // ApplicationSetTree holds nodes which belongs to the application @@ -488,7 +503,18 @@ message ApplicationSourceHelm { // ValuesObject specifies Helm values to be passed to helm template, defined as a map. This takes precedence over Values. // +kubebuilder:pruning:PreserveUnknownFields - optional k8s.io.apimachinery.pkg.runtime.RawExtension valuesObject = 10; + optional .k8s.io.apimachinery.pkg.runtime.RawExtension valuesObject = 10; + + // Namespace is an optional namespace to template with. If left empty, defaults to the app's destination namespace. + optional string namespace = 11; + + // 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. + optional string kubeVersion = 12; + + // APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + // Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + repeated string apiVersions = 13; } // ApplicationSourceJsonnet holds options specific to applications of type Jsonnet @@ -546,6 +572,14 @@ message ApplicationSourceKustomize { // LabelWithoutSelector specifies whether to apply common labels to resource selectors or not optional bool labelWithoutSelector = 14; + + // 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. + optional string kubeVersion = 15; + + // 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; } // ApplicationSourcePlugin holds options specific to config management plugins @@ -621,14 +655,14 @@ message ApplicationStatus { repeated ApplicationCondition conditions = 5; // ReconciledAt indicates when the application state was reconciled using the latest git version - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time reconciledAt = 6; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time reconciledAt = 6; // OperationState contains information about any ongoing operations, such as a sync optional OperationState operationState = 7; // ObservedAt indicates when the application state was updated without querying latest git state // Deprecated: controller no longer updates ObservedAt field - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time observedAt = 8; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time observedAt = 8; // SourceType specifies the type of this application optional string sourceType = 9; @@ -666,6 +700,9 @@ message ApplicationTree { // Hosts holds list of Kubernetes nodes that run application related pods repeated HostInfo hosts = 3; + + // ShardsCount contains total number of shards the application tree is split into + optional int64 shardsCount = 4; } // ApplicationWatchEvent contains information about application change. @@ -701,6 +738,12 @@ message BasicAuthBitbucketServer { optional SecretRef passwordRef = 2; } +// BearerTokenBitbucket defines the Bearer token for BitBucket AppToken auth. +message BearerTokenBitbucket { + // Password (or personal access token) reference. + optional SecretRef tokenRef = 1; +} + // BearerTokenBitbucketCloud defines the Bearer token for BitBucket AppToken auth. message BearerTokenBitbucketCloud { // Password (or personal access token) reference. @@ -741,7 +784,7 @@ message Cluster { repeated string namespaces = 6; // RefreshRequestedAt holds time when cluster cache refresh has been requested - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time refreshRequestedAt = 7; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time refreshRequestedAt = 7; // Info holds information about cluster cache and state optional ClusterInfo info = 8; @@ -771,7 +814,7 @@ message ClusterCacheInfo { optional int64 apisCount = 2; // LastCacheSyncTime holds time of most recent cache synchronization - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time lastCacheSyncTime = 3; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time lastCacheSyncTime = 3; } // ClusterConfig is the configuration attributes. This structure is subset of the go-client @@ -802,7 +845,7 @@ message ClusterGenerator { // 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. - optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 1; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 1; optional ApplicationSetTemplate template = 2; @@ -830,7 +873,7 @@ message ClusterInfo { // ClusterList is a collection of Clusters. message ClusterList { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; repeated Cluster items = 2; } @@ -877,6 +920,13 @@ message ConfigManagementPlugin { optional bool lockRepo = 4; } +// Utility struct for a reference to a configmap key. +message ConfigMapKeyRef { + optional string configMapName = 1; + + optional string key = 2; +} + // ConnectionState contains information about remote resource connection state, currently used for clusters and repositories message ConnectionState { // Status contains the current status indicator for the connection @@ -886,7 +936,7 @@ message ConnectionState { optional string message = 2; // ModifiedAt contains the timestamp when this connection status has been determined - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time attemptedAt = 3; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time attemptedAt = 3; } // DuckType defines a generator to match against clusters registered with ArgoCD. @@ -901,7 +951,7 @@ message DuckTypeGenerator { optional int64 requeueAfterSeconds = 3; - optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector labelSelector = 4; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector labelSelector = 4; optional ApplicationSetTemplate template = 5; @@ -992,7 +1042,7 @@ message GnuPGPublicKey { // GnuPGPublicKeyList is a collection of GnuPGPublicKey objects message GnuPGPublicKeyList { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; repeated GnuPGPublicKey items = 2; } @@ -1040,7 +1090,7 @@ message HostInfo { repeated HostResourceInfo resourcesInfo = 2; - optional k8s.io.api.core.v1.NodeSystemInfo systemInfo = 3; + optional .k8s.io.api.core.v1.NodeSystemInfo systemInfo = 3; } // TODO: describe this type @@ -1133,7 +1183,7 @@ message KustomizeReplica { optional string name = 1; // Number of replicas - optional k8s.io.apimachinery.pkg.util.intstr.IntOrString count = 2; + optional .k8s.io.apimachinery.pkg.util.intstr.IntOrString count = 2; } message KustomizeResId { @@ -1155,7 +1205,7 @@ message KustomizeSelector { // ListGenerator include items info message ListGenerator { // +kubebuilder:validation:Optional - repeated k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1.JSON elements = 1; + repeated .k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1.JSON elements = 1; optional ApplicationSetTemplate template = 2; @@ -1257,10 +1307,10 @@ message OperationState { optional SyncOperationResult syncResult = 4; // StartedAt contains time of operation start - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time startedAt = 6; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time startedAt = 6; // FinishedAt contains time of operation completion - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time finishedAt = 7; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time finishedAt = 7; // RetryCount contains time of operation retries optional int64 retryCount = 8; @@ -1334,7 +1384,7 @@ message PluginGenerator { message PluginInput { // Parameters contains the information to pass to the plugin. It is a map. The keys must be strings, and the // values can be any type. - map parameters = 1; + map parameters = 1; } // ProjectRole represents a role that has access to a project @@ -1432,6 +1482,15 @@ message PullRequestGeneratorBitbucketServer { // Credentials for Basic auth optional BasicAuthBitbucketServer basicAuth = 4; + + // Credentials for AccessToken (Bearer auth) + optional BearerTokenBitbucket bearerToken = 5; + + // Allow self-signed TLS / Certificates; default: false + optional bool insecure = 6; + + // ConfigMap key holding the trusted certificates + optional ConfigMapKeyRef caRef = 7; } // PullRequestGeneratorFilter is a single pull request filter. @@ -1462,6 +1521,9 @@ message PullRequestGeneratorGitLab { // Skips validating the SCM provider's TLS certificate - useful for self-signed certificates.; default: false optional bool insecure = 6; + + // ConfigMap key holding the trusted certificates + optional ConfigMapKeyRef caRef = 7; } // PullRequestGeneratorGitea defines connection info specific to Gitea. @@ -1557,11 +1619,14 @@ message RepoCreds { // ForceHttpBasicAuth specifies whether Argo CD should attempt to force basic auth for HTTP connections optional bool forceHttpBasicAuth = 20; + + // 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; } // RepositoryList is a collection of Repositories. message RepoCredsList { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; repeated RepoCreds items = 2; } @@ -1634,6 +1699,9 @@ message Repository { // ForceHttpBasicAuth specifies whether Argo CD should attempt to force basic auth for HTTP connections optional bool forceHttpBasicAuth = 22; + + // 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; } // A RepositoryCertificate is either SSH known hosts entry or TLS certificate @@ -1656,7 +1724,7 @@ message RepositoryCertificate { // RepositoryCertificateList is a collection of RepositoryCertificates message RepositoryCertificateList { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; // List of certificates to be processed repeated RepositoryCertificate items = 2; @@ -1664,7 +1732,7 @@ message RepositoryCertificateList { // RepositoryList is a collection of Repositories. message RepositoryList { - optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; repeated Repository items = 2; } @@ -1709,6 +1777,8 @@ message ResourceActions { optional string actionDiscoveryLua = 1; repeated ResourceActionDefinition definitions = 2; + + optional bool mergeBuiltinActions = 3; } // ResourceDiff holds the diff of a live and target resource object @@ -1773,7 +1843,7 @@ message ResourceNetworkingInfo { map labels = 3; - repeated k8s.io.api.core.v1.LoadBalancerIngress ingress = 4; + repeated .k8s.io.api.core.v1.LoadBalancerIngress ingress = 4; // ExternalURLs holds list of URLs which should be available externally. List is populated for ingress resources using rules hostnames. repeated string externalURLs = 5; @@ -1796,7 +1866,7 @@ message ResourceNode { optional HealthStatus health = 7; - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time createdAt = 8; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time createdAt = 8; } // ResourceOverride holds configuration to customize resource diffing and health assessment @@ -1903,7 +1973,7 @@ message RevisionHistory { optional string revision = 2; // DeployedAt holds the time the sync operation completed - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time deployedAt = 4; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time deployedAt = 4; // ID is an auto incrementing identifier of the RevisionHistory optional int64 id = 5; @@ -1912,7 +1982,7 @@ message RevisionHistory { optional ApplicationSource source = 6; // DeployStartedAt holds the time the sync operation started - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time deployStartedAt = 7; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time deployStartedAt = 7; // Sources is a reference to the application sources used for the sync operation repeated ApplicationSource sources = 8; @@ -1932,7 +2002,7 @@ message RevisionMetadata { optional string author = 1; // Date specifies when the revision was authored - optional k8s.io.apimachinery.pkg.apis.meta.v1.Time date = 2; + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time date = 2; // Tags specifies any tags currently attached to the revision // Floating tags can move from one revision to another @@ -2041,6 +2111,15 @@ message SCMProviderGeneratorBitbucketServer { // Scan all branches instead of just the default branch. optional bool allBranches = 4; + + // Credentials for AccessToken (Bearer auth) + optional BearerTokenBitbucket bearerToken = 5; + + // Allow self-signed TLS / Certificates; default: false + optional bool insecure = 6; + + // ConfigMap key holding the trusted certificates + optional ConfigMapKeyRef caRef = 7; } // SCMProviderGeneratorFilter is a single repository filter. @@ -2124,6 +2203,9 @@ message SCMProviderGeneratorGitlab { // Filter repos list based on Gitlab Topic. optional string topic = 8; + + // ConfigMap key holding the trusted certificates + optional ConfigMapKeyRef caRef = 9; } // Utility struct for a reference to a secret key. @@ -2241,7 +2323,6 @@ message SyncStatus { optional string status = 1; // ComparedTo contains information about what has been compared - // +patchStrategy=replace optional ComparedTo comparedTo = 2; // Revision contains information about the revision the comparison has been performed to diff --git a/pkg/apis/application/v1alpha1/openapi_generated.go b/pkg/apis/application/v1alpha1/openapi_generated.go index 2fcbbb94edb0b..1b2533532bc0e 100644 --- a/pkg/apis/application/v1alpha1/openapi_generated.go +++ b/pkg/apis/application/v1alpha1/openapi_generated.go @@ -22,6 +22,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "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), @@ -56,6 +57,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "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), @@ -68,6 +70,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "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.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), @@ -471,11 +474,25 @@ func schema_pkg_apis_application_v1alpha1_AppProjectSpec(ref common.ReferenceCal Format: "", }, }, + "destinationServiceAccounts": { + SchemaProps: spec.SchemaProps{ + Description: "DestinationServiceAccounts holds information about the service accounts to be impersonated for the application sync operation for each destination.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestinationServiceAccount"), + }, + }, + }, + }, + }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationDestination", "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"}, + "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"}, } } @@ -634,6 +651,40 @@ func schema_pkg_apis_application_v1alpha1_ApplicationDestination(ref common.Refe } } +func schema_pkg_apis_application_v1alpha1_ApplicationDestinationServiceAccount(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ApplicationDestinationServiceAccount holds information about the service account to be impersonated for the application sync operation.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "server": { + SchemaProps: spec.SchemaProps{ + Description: "Server specifies the URL of the target cluster's Kubernetes control plane API.", + Type: []string{"string"}, + Format: "", + }, + }, + "namespace": { + SchemaProps: spec.SchemaProps{ + Description: "Namespace specifies the target namespace for the application's resources.", + Type: []string{"string"}, + Format: "", + }, + }, + "defaultServiceAccount": { + SchemaProps: spec.SchemaProps{ + Description: "ServiceAccountName to be used for impersonation during the sync operation", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_pkg_apis_application_v1alpha1_ApplicationList(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -1833,6 +1884,35 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceHelm(ref common.Refer Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), }, }, + "namespace": { + SchemaProps: spec.SchemaProps{ + Description: "Namespace is an optional namespace to template with. If left empty, defaults to the app's destination namespace.", + Type: []string{"string"}, + Format: "", + }, + }, + "kubeVersion": { + SchemaProps: spec.SchemaProps{ + Description: "KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster.", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersions": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, Argo CD uses the API versions of the target cluster. The format is [group/]version/kind.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, }, }, }, @@ -2052,6 +2132,28 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceKustomize(ref common. Format: "", }, }, + "kubeVersion": { + SchemaProps: spec.SchemaProps{ + Description: "KubeVersion specifies the Kubernetes API version to pass to Helm when templating manifests. By default, Argo CD uses the Kubernetes version of the target cluster.", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersions": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, Argo CD uses the API versions of the target cluster. The format is [group/]version/kind.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, }, }, }, @@ -2550,6 +2652,28 @@ func schema_pkg_apis_application_v1alpha1_BasicAuthBitbucketServer(ref common.Re } } +func schema_pkg_apis_application_v1alpha1_BearerTokenBitbucket(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "BearerTokenBitbucket defines the Bearer token for BitBucket AppToken auth.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "tokenRef": { + SchemaProps: spec.SchemaProps{ + Description: "Password (or personal access token) reference.", + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"), + }, + }, + }, + Required: []string{"tokenRef"}, + }, + }, + Dependencies: []string{ + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.SecretRef"}, + } +} + func schema_pkg_apis_application_v1alpha1_BearerTokenBitbucketCloud(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -3149,6 +3273,34 @@ func schema_pkg_apis_application_v1alpha1_ConfigManagementPlugin(ref common.Refe } } +func schema_pkg_apis_application_v1alpha1_ConfigMapKeyRef(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Utility struct for a reference to a configmap key.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "configMapName": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "key": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"configMapName", "key"}, + }, + }, + } +} + func schema_pkg_apis_application_v1alpha1_ConnectionState(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -5172,12 +5324,31 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorBitbucketServer(re 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/v2/pkg/apis/application/v1alpha1.BearerTokenBitbucket"), + }, + }, + "insecure": { + SchemaProps: spec.SchemaProps{ + Description: "Allow self-signed TLS / Certificates; default: false", + Type: []string{"boolean"}, + Format: "", + }, + }, + "caRef": { + SchemaProps: spec.SchemaProps{ + Description: "ConfigMap key holding the trusted certificates", + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef"), + }, + }, }, Required: []string{"project", "repo", "api"}, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer"}, + "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"}, } } @@ -5263,12 +5434,18 @@ func schema_pkg_apis_application_v1alpha1_PullRequestGeneratorGitLab(ref common. Format: "", }, }, + "caRef": { + SchemaProps: spec.SchemaProps{ + Description: "ConfigMap key holding the trusted certificates", + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef"), + }, + }, }, Required: []string{"project"}, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v2/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"}, } } @@ -5540,6 +5717,13 @@ func schema_pkg_apis_application_v1alpha1_RepoCreds(ref common.ReferenceCallback Format: "", }, }, + "noProxy": { + SchemaProps: spec.SchemaProps{ + Description: "NoProxy specifies a list of targets where the proxy isn't used, applies only in cases where the proxy is applied", + Type: []string{"string"}, + Format: "", + }, + }, }, Required: []string{"url"}, }, @@ -5744,6 +5928,13 @@ func schema_pkg_apis_application_v1alpha1_Repository(ref common.ReferenceCallbac Format: "", }, }, + "noProxy": { + SchemaProps: spec.SchemaProps{ + Description: "NoProxy specifies a list of targets where the proxy isn't used, applies only in cases where the proxy is applied", + Type: []string{"string"}, + Format: "", + }, + }, }, Required: []string{"repo"}, }, @@ -7122,12 +7313,31 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorBitbucketServer(re Format: "", }, }, + "bearerToken": { + SchemaProps: spec.SchemaProps{ + Description: "Credentials for AccessToken (Bearer auth)", + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BearerTokenBitbucket"), + }, + }, + "insecure": { + SchemaProps: spec.SchemaProps{ + Description: "Allow self-signed TLS / Certificates; default: false", + Type: []string{"boolean"}, + Format: "", + }, + }, + "caRef": { + SchemaProps: spec.SchemaProps{ + Description: "ConfigMap key holding the trusted certificates", + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef"), + }, + }, }, Required: []string{"project", "api"}, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.BasicAuthBitbucketServer"}, + "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"}, } } @@ -7361,12 +7571,18 @@ func schema_pkg_apis_application_v1alpha1_SCMProviderGeneratorGitlab(ref common. Format: "", }, }, + "caRef": { + SchemaProps: spec.SchemaProps{ + Description: "ConfigMap key holding the trusted certificates", + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ConfigMapKeyRef"), + }, + }, }, Required: []string{"group"}, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v2/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"}, } } @@ -7758,11 +7974,6 @@ func schema_pkg_apis_application_v1alpha1_SyncStatus(ref common.ReferenceCallbac }, }, "comparedTo": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-patch-strategy": "replace", - }, - }, SchemaProps: spec.SchemaProps{ Description: "ComparedTo contains information about what has been compared", Default: map[string]interface{}{}, diff --git a/pkg/apis/application/v1alpha1/repository_types.go b/pkg/apis/application/v1alpha1/repository_types.go index 665c1f3c2afc9..5a30d24fbcfdb 100644 --- a/pkg/apis/application/v1alpha1/repository_types.go +++ b/pkg/apis/application/v1alpha1/repository_types.go @@ -3,6 +3,7 @@ package v1alpha1 import ( "fmt" "net/url" + "strings" "github.com/argoproj/argo-cd/v2/util/cert" "github.com/argoproj/argo-cd/v2/util/git" @@ -44,6 +45,8 @@ type RepoCreds struct { 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"` + // 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"` } // Repository is a repository holding application configurations @@ -93,6 +96,8 @@ type Repository struct { 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"` + // 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"` } // IsInsecure returns true if the repository has been configured to skip server verification @@ -183,6 +188,9 @@ func (repo *Repository) CopyCredentialsFrom(source *RepoCreds) { if repo.Proxy == "" { repo.Proxy = source.Proxy } + if repo.NoProxy == "" { + repo.NoProxy = source.NoProxy + } repo.ForceHttpBasicAuth = source.ForceHttpBasicAuth } } @@ -193,13 +201,13 @@ func (repo *Repository) GetGitCreds(store git.CredsStore) git.Creds { return git.NopCreds{} } if repo.Password != "" { - return git.NewHTTPSCreds(repo.Username, repo.Password, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure(), repo.Proxy, store, repo.ForceHttpBasicAuth) + 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) + return git.NewSSHCreds(repo.SSHPrivateKey, getCAPath(repo.Repo), repo.IsInsecure(), store, repo.Proxy, repo.NoProxy) } if repo.GithubAppPrivateKey != "" && repo.GithubAppId != 0 && repo.GithubAppInstallationId != 0 { - return git.NewGitHubAppCreds(repo.GithubAppId, repo.GithubAppInstallationId, repo.GithubAppPrivateKey, repo.GitHubAppEnterpriseBaseURL, repo.Repo, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure(), repo.Proxy, store) + return git.NewGitHubAppCreds(repo.GithubAppId, repo.GithubAppInstallationId, repo.GithubAppPrivateKey, repo.GitHubAppEnterpriseBaseURL, repo.Repo, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure(), repo.Proxy, repo.NoProxy, store) } if repo.GCPServiceAccountKey != "" { return git.NewGoogleCloudCreds(repo.GCPServiceAccountKey, store) @@ -227,21 +235,22 @@ func getCAPath(repoURL string) string { } hostname := "" - // url.Parse() will happily parse most things thrown at it. When the URL - // is either https or oci, we use the parsed hostname to retrieve the cert, - // otherwise we'll use the parsed path (OCI repos are often specified as - // hostname, without protocol). - parsedURL, err := url.Parse(repoURL) + var parsedURL *url.URL + var err error + // Without schema in url, url.Parse() treats the url as differently + // and may incorrectly parses the hostname if url contains a path or port. + // To ensure proper parsing, prepend a dummy schema. + if !strings.Contains(repoURL, "://") { + parsedURL, err = url.Parse("protocol://" + repoURL) + } else { + parsedURL, err = url.Parse(repoURL) + } if err != nil { log.Warnf("Could not parse repo URL '%s': %v", repoURL, err) return "" } - if parsedURL.Scheme == "https" || parsedURL.Scheme == "oci" { - hostname = parsedURL.Host - } else if parsedURL.Scheme == "" { - hostname = parsedURL.Path - } + hostname = parsedURL.Hostname() if hostname == "" { log.Warnf("Could not get hostname for repository '%s'", repoURL) return "" diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index f31ae025e452a..1337bd8c72772 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -233,7 +233,7 @@ func (a *ApplicationSpec) GetSources() ApplicationSources { } func (a *ApplicationSpec) HasMultipleSources() bool { - return a.Sources != nil && len(a.Sources) > 0 + return len(a.Sources) > 0 } func (a *ApplicationSpec) GetSourcePtrByPosition(sourcePosition int) *ApplicationSource { @@ -292,6 +292,51 @@ func (a *ApplicationSource) IsZero() bool { a.Plugin.IsZero() } +// GetNamespaceOrDefault gets the static namespace configured in the source. If none is configured, returns the given +// default. +func (a *ApplicationSource) GetNamespaceOrDefault(defaultNamespace string) string { + if a == nil { + return defaultNamespace + } + if a.Helm != nil && a.Helm.Namespace != "" { + return a.Helm.Namespace + } + if a.Kustomize != nil && a.Kustomize.Namespace != "" { + return a.Kustomize.Namespace + } + return defaultNamespace +} + +// GetKubeVersionOrDefault gets the static Kubernetes API version configured in the source. If none is configured, +// returns the given default. +func (a *ApplicationSource) GetKubeVersionOrDefault(defaultKubeVersion string) string { + if a == nil { + return defaultKubeVersion + } + if a.Helm != nil && a.Helm.KubeVersion != "" { + return a.Helm.KubeVersion + } + if a.Kustomize != nil && a.Kustomize.KubeVersion != "" { + return a.Kustomize.KubeVersion + } + return defaultKubeVersion +} + +// GetAPIVersionsOrDefault gets the static API versions list configured in the source. If none is configured, returns +// the given default. +func (a *ApplicationSource) GetAPIVersionsOrDefault(defaultAPIVersions []string) []string { + if a == nil { + return defaultAPIVersions + } + if a.Helm != nil && len(a.Helm.APIVersions) > 0 { + return a.Helm.APIVersions + } + if a.Kustomize != nil && len(a.Kustomize.APIVersions) > 0 { + return a.Kustomize.APIVersions + } + return defaultAPIVersions +} + // ApplicationSourceType specifies the type of the application's source type ApplicationSourceType string @@ -342,6 +387,14 @@ type ApplicationSourceHelm struct { // ValuesObject specifies Helm values to be passed to helm template, defined as a map. This takes precedence over Values. // +kubebuilder:pruning:PreserveUnknownFields ValuesObject *runtime.RawExtension `json:"valuesObject,omitempty" protobuf:"bytes,10,opt,name=valuesObject"` + // Namespace is an optional namespace to template with. If left empty, defaults to the app's destination namespace. + Namespace string `json:"namespace,omitempty" protobuf:"bytes,11,opt,name=namespace"` + // 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. + KubeVersion string `json:"kubeVersion,omitempty" protobuf:"bytes,12,opt,name=kubeVersion"` + // APIVersions specifies the Kubernetes resource API versions to pass to Helm when templating manifests. By default, + // Argo CD uses the API versions of the target cluster. The format is [group/]version/kind. + APIVersions []string `json:"apiVersions,omitempty" protobuf:"bytes,13,opt,name=apiVersions"` } // HelmParameter is a parameter that's passed to helm template during manifest generation @@ -423,7 +476,7 @@ func (in *ApplicationSourceHelm) AddFileParameter(p HelmFileParameter) { // IsZero Returns true if the Helm options in an application source are considered zero func (h *ApplicationSourceHelm) IsZero() bool { - return h == nil || (h.Version == "") && (h.ReleaseName == "") && len(h.ValueFiles) == 0 && len(h.Parameters) == 0 && len(h.FileParameters) == 0 && h.ValuesIsEmpty() && !h.PassCredentials && !h.IgnoreMissingValueFiles && !h.SkipCrds + return h == nil || (h.Version == "") && (h.ReleaseName == "") && len(h.ValueFiles) == 0 && len(h.Parameters) == 0 && len(h.FileParameters) == 0 && h.ValuesIsEmpty() && !h.PassCredentials && !h.IgnoreMissingValueFiles && !h.SkipCrds && h.KubeVersion == "" && len(h.APIVersions) == 0 && h.Namespace == "" } // KustomizeImage represents a Kustomize image definition in the format [old_image_name=]: @@ -490,6 +543,12 @@ type ApplicationSourceKustomize struct { Components []string `json:"components,omitempty" protobuf:"bytes,13,rep,name=components"` // 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 + // uses the Kubernetes version of the target cluster. + KubeVersion string `json:"kubeVersion,omitempty" protobuf:"bytes,15,opt,name=kubeVersion"` + // 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"` } type KustomizeReplica struct { @@ -595,7 +654,9 @@ func (k *ApplicationSourceKustomize) IsZero() bool { len(k.CommonLabels) == 0 && len(k.CommonAnnotations) == 0 && len(k.Patches) == 0 && - len(k.Components) == 0 + len(k.Components) == 0 && + k.KubeVersion == "" && + len(k.APIVersions) == 0 } // MergeImage merges a new Kustomize image identifier in to a list of images @@ -608,7 +669,7 @@ func (k *ApplicationSourceKustomize) MergeImage(image KustomizeImage) { } } -// MergeReplicas merges a new Kustomize replica identifier in to a list of replicas +// MergeReplica merges a new Kustomize replica identifier in to a list of replicas func (k *ApplicationSourceKustomize) MergeReplica(replica KustomizeReplica) { i := k.Replicas.FindByName(replica.Name) if i >= 0 { @@ -1459,7 +1520,7 @@ type SyncStatusCode string const ( // SyncStatusCodeUnknown indicates that the status of a sync could not be reliably determined SyncStatusCodeUnknown SyncStatusCode = "Unknown" - // SyncStatusCodeOutOfSync indicates that desired and live states match + // SyncStatusCodeSynced indicates that desired and live states match SyncStatusCodeSynced SyncStatusCode = "Synced" // SyncStatusCodeOutOfSync indicates that there is a drift between desired and live states SyncStatusCodeOutOfSync SyncStatusCode = "OutOfSync" @@ -1519,8 +1580,7 @@ type SyncStatus struct { // Status is the sync state of the comparison Status SyncStatusCode `json:"status" protobuf:"bytes,1,opt,name=status,casttype=SyncStatusCode"` // ComparedTo contains information about what has been compared - // +patchStrategy=replace - ComparedTo ComparedTo `json:"comparedTo,omitempty" protobuf:"bytes,2,opt,name=comparedTo" patchStrategy:"replace"` + ComparedTo ComparedTo `json:"comparedTo,omitempty" protobuf:"bytes,2,opt,name=comparedTo"` // Revision contains information about the revision the comparison has been performed to Revision string `json:"revision,omitempty" protobuf:"bytes,3,opt,name=revision"` // Revisions contains information about the revisions of multiple sources the comparison has been performed to @@ -1580,6 +1640,60 @@ type ApplicationTree struct { OrphanedNodes []ResourceNode `json:"orphanedNodes,omitempty" protobuf:"bytes,2,rep,name=orphanedNodes"` // Hosts holds list of Kubernetes nodes that run application related pods Hosts []HostInfo `json:"hosts,omitempty" protobuf:"bytes,3,rep,name=hosts"` + // ShardsCount contains total number of shards the application tree is split into + ShardsCount int64 `json:"shardsCount,omitempty" protobuf:"bytes,4,opt,name=shardsCount"` +} + +func (t *ApplicationTree) Merge(other *ApplicationTree) { + t.Nodes = append(t.Nodes, other.Nodes...) + t.OrphanedNodes = append(t.OrphanedNodes, other.OrphanedNodes...) + t.Hosts = append(t.Hosts, other.Hosts...) + t.Normalize() +} + +// GetShards split application tree into shards with populated metadata +func (t *ApplicationTree) GetShards(size int64) []*ApplicationTree { + t.Normalize() + if size == 0 { + return []*ApplicationTree{t} + } + + var items []func(*ApplicationTree) + for i := range t.Nodes { + item := t.Nodes[i] + items = append(items, func(shard *ApplicationTree) { + shard.Nodes = append(shard.Nodes, item) + }) + } + for i := range t.OrphanedNodes { + item := t.OrphanedNodes[i] + items = append(items, func(shard *ApplicationTree) { + shard.OrphanedNodes = append(shard.OrphanedNodes, item) + }) + } + for i := range t.Hosts { + item := t.Hosts[i] + items = append(items, func(shard *ApplicationTree) { + shard.Hosts = append(shard.Hosts, item) + }) + } + var shards []*ApplicationTree + for len(items) > 0 { + shard := &ApplicationTree{} + shards = append(shards, shard) + cnt := 0 + for i := int64(0); i < size && i < int64(len(items)); i++ { + items[i](shard) + cnt++ + } + items = items[cnt:] + } + if len(shards) > 0 { + shards[0].ShardsCount = int64(len(shards)) + } else { + shards = []*ApplicationTree{{ShardsCount: 0}} + } + return shards } // Normalize sorts application tree nodes and hosts. The persistent order allows to @@ -2030,8 +2144,9 @@ func (o *ResourceOverride) GetActions() (ResourceActions, error) { // TODO: describe this type // TODO: describe members of this type type ResourceActions struct { - 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"` + 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"` } // TODO: describe this type @@ -2073,6 +2188,8 @@ var validActions = map[string]bool{ var validActionPatterns = []*regexp.Regexp{ regexp.MustCompile("action/.*"), + regexp.MustCompile("update/.*"), + regexp.MustCompile("delete/.*"), } func isValidAction(action string) bool { @@ -2229,6 +2346,8 @@ type AppProjectSpec struct { SourceNamespaces []string `json:"sourceNamespaces,omitempty" protobuf:"bytes,12,opt,name=sourceNamespaces"` // PermitOnlyProjectScopedClusters determines whether destinations can only reference clusters which are project-scoped PermitOnlyProjectScopedClusters bool `json:"permitOnlyProjectScopedClusters,omitempty" protobuf:"bytes,13,opt,name=permitOnlyProjectScopedClusters"` + // DestinationServiceAccounts holds information about the service accounts to be impersonated for the application sync operation for each destination. + DestinationServiceAccounts []ApplicationDestinationServiceAccount `json:"destinationServiceAccounts,omitempty" protobuf:"bytes,14,name=destinationServiceAccounts"` } // SyncWindows is a collection of sync windows in this project @@ -2645,6 +2764,16 @@ type KustomizeOptions struct { BinaryPath string `protobuf:"bytes,2,opt,name=binaryPath"` } +// ApplicationDestinationServiceAccount holds information about the service account to be impersonated for the application sync operation. +type ApplicationDestinationServiceAccount struct { + // Server specifies the URL of the target cluster's Kubernetes control plane API. + Server string `json:"server,omitempty" protobuf:"bytes,1,opt,name=server"` + // Namespace specifies the target namespace for the application's resources. + Namespace string `json:"namespace,omitempty" protobuf:"bytes,2,opt,name=namespace"` + // ServiceAccountName to be used for impersonation during the sync operation + DefaultServiceAccount string `json:"defaultServiceAccount,omitempty" protobuf:"bytes,3,opt,name=defaultServiceAccount"` +} + // 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.ObjectMeta.Finalizers { @@ -3150,3 +3279,15 @@ func (a *Application) QualifiedName() string { func (a *Application) RBACName(defaultNS string) string { return security.RBACName(defaultNS, a.Spec.GetProject(), a.Namespace, a.Name) } + +// GetAnnotation returns the value of the specified annotation if it exists, +// e.g., a.GetAnnotation("argocd.argoproj.io/manifest-generate-paths"). +// If the annotation does not exist, it returns an empty string. +func (a *Application) GetAnnotation(annotation string) string { + v, exists := a.Annotations[annotation] + if !exists { + return "" + } + + return v +} diff --git a/pkg/apis/application/v1alpha1/types_test.go b/pkg/apis/application/v1alpha1/types_test.go index e878864028cce..08b83c238a93d 100644 --- a/pkg/apis/application/v1alpha1/types_test.go +++ b/pkg/apis/application/v1alpha1/types_test.go @@ -7,14 +7,10 @@ import ( "os" "path" "reflect" - "strings" "testing" "time" - "github.com/argoproj/gitops-engine/pkg/diff" "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/utils/ptr" argocdcommon "github.com/argoproj/argo-cd/v2/common" @@ -442,8 +438,8 @@ func TestAppProject_IsDestinationPermitted_PermitOnlyProjectScopedClusters(t *te _, err := proj.IsDestinationPermitted(ApplicationDestination{Server: "https://my-cluster.123.com", Namespace: "default"}, func(_ string) ([]*Cluster, error) { return nil, errors.New("some error") }) - assert.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "could not retrieve project clusters")) + require.Error(t, err) + assert.Contains(t, err.Error(), "could not retrieve project clusters") } func TestAppProject_IsGroupKindPermitted(t *testing.T) { @@ -501,14 +497,14 @@ func TestAppProject_GetRoleByName(t *testing.T) { t.Run("NotExists", func(t *testing.T) { p := &AppProject{} role, i, err := p.GetRoleByName("test-role") - assert.Error(t, err) + require.Error(t, err) assert.Equal(t, -1, i) assert.Nil(t, role) }) t.Run("NotExists", func(t *testing.T) { p := AppProject{Spec: AppProjectSpec{Roles: []ProjectRole{{Name: "test-role"}}}} role, i, err := p.GetRoleByName("test-role") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, 0, i) assert.Equal(t, &ProjectRole{Name: "test-role"}, role) }) @@ -518,20 +514,20 @@ func TestAppProject_AddGroupToRole(t *testing.T) { t.Run("NoRole", func(t *testing.T) { p := &AppProject{} got, err := p.AddGroupToRole("test-role", "test-group") - assert.Error(t, err) + require.Error(t, err) assert.False(t, got) }) t.Run("NoGroup", func(t *testing.T) { p := &AppProject{Spec: AppProjectSpec{Roles: []ProjectRole{{Name: "test-role", Groups: []string{}}}}} got, err := p.AddGroupToRole("test-role", "test-group") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, got) assert.Len(t, p.Spec.Roles[0].Groups, 1) }) t.Run("Exists", func(t *testing.T) { p := &AppProject{Spec: AppProjectSpec{Roles: []ProjectRole{{Name: "test-role", Groups: []string{"test-group"}}}}} got, err := p.AddGroupToRole("test-role", "test-group") - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, got) }) } @@ -540,19 +536,19 @@ func TestAppProject_RemoveGroupFromRole(t *testing.T) { t.Run("NoRole", func(t *testing.T) { p := &AppProject{} got, err := p.RemoveGroupFromRole("test-role", "test-group") - assert.Error(t, err) + require.Error(t, err) assert.False(t, got) }) t.Run("NoGroup", func(t *testing.T) { p := &AppProject{Spec: AppProjectSpec{Roles: []ProjectRole{{Name: "test-role", Groups: []string{}}}}} got, err := p.RemoveGroupFromRole("test-role", "test-group") - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, got) }) t.Run("Exists", func(t *testing.T) { p := &AppProject{Spec: AppProjectSpec{Roles: []ProjectRole{{Name: "test-role", Groups: []string{"test-group"}}}}} got, err := p.RemoveGroupFromRole("test-role", "test-group") - assert.NoError(t, err) + require.NoError(t, err) assert.True(t, got) assert.Empty(t, p.Spec.Roles[0].Groups) }) @@ -570,14 +566,14 @@ func newTestProject() *AppProject { func TestAppProject_ValidateSources(t *testing.T) { p := newTestProject() err := p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) badSources := []string{ "!*", } for _, badName := range badSources { p.Spec.SourceRepos = []string{badName} err = p.ValidateProject() - assert.Error(t, err) + require.Error(t, err) } duplicateSources := []string{ @@ -586,21 +582,21 @@ func TestAppProject_ValidateSources(t *testing.T) { } p.Spec.SourceRepos = duplicateSources err = p.ValidateProject() - assert.Error(t, err) + require.Error(t, err) } // TestAppProject_ValidateDestinations tests for an invalid destination func TestAppProject_ValidateDestinations(t *testing.T) { p := newTestProject() err := p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) badNamespaces := []string{ "!*", } for _, badName := range badNamespaces { p.Spec.Destinations[0].Namespace = badName err = p.ValidateProject() - assert.Error(t, err) + require.Error(t, err) } goodNamespaces := []string{ @@ -610,7 +606,7 @@ func TestAppProject_ValidateDestinations(t *testing.T) { for _, goodNamespace := range goodNamespaces { p.Spec.Destinations[0].Namespace = goodNamespace err = p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) } badServers := []string{ @@ -619,7 +615,7 @@ func TestAppProject_ValidateDestinations(t *testing.T) { for _, badServer := range badServers { p.Spec.Destinations[0].Server = badServer err = p.ValidateProject() - assert.Error(t, err) + require.Error(t, err) } goodServers := []string{ @@ -629,7 +625,7 @@ func TestAppProject_ValidateDestinations(t *testing.T) { for _, badName := range goodServers { p.Spec.Destinations[0].Server = badName err = p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) } badNames := []string{ @@ -638,7 +634,7 @@ func TestAppProject_ValidateDestinations(t *testing.T) { for _, badName := range badNames { p.Spec.Destinations[0].Name = badName err = p.ValidateProject() - assert.Error(t, err) + require.Error(t, err) } goodNames := []string{ @@ -648,7 +644,7 @@ func TestAppProject_ValidateDestinations(t *testing.T) { for _, goodName := range goodNames { p.Spec.Destinations[0].Name = goodName err = p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) } validDestination := ApplicationDestination{ @@ -658,12 +654,12 @@ func TestAppProject_ValidateDestinations(t *testing.T) { p.Spec.Destinations[0] = validDestination err = p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) // no duplicates allowed p.Spec.Destinations = []ApplicationDestination{validDestination, validDestination} err = p.ValidateProject() - assert.Error(t, err) + require.Error(t, err) cluster1Destination := ApplicationDestination{ Name: "cluster1", @@ -676,12 +672,12 @@ func TestAppProject_ValidateDestinations(t *testing.T) { // allow multiple destinations with blank server, same namespace but unique cluster name p.Spec.Destinations = []ApplicationDestination{cluster1Destination, cluster2Destination} err = p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) t.Run("must reject duplicate source namespaces", func(t *testing.T) { p.Spec.SourceNamespaces = []string{"argocd", "argocd"} err = p.ValidateProject() - assert.Error(t, err) + require.Error(t, err) }) } @@ -689,7 +685,7 @@ func TestAppProject_ValidateDestinations(t *testing.T) { func TestAppProject_ValidateRoleName(t *testing.T) { p := newTestProject() err := p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) badRoleNames := []string{ "", " ", @@ -705,7 +701,7 @@ func TestAppProject_ValidateRoleName(t *testing.T) { for _, badName := range badRoleNames { p.Spec.Roles[0].Name = badName err = p.ValidateProject() - assert.Error(t, err) + require.Error(t, err) } goodRoleNames := []string{ "MY-ROLE", @@ -714,7 +710,7 @@ func TestAppProject_ValidateRoleName(t *testing.T) { for _, goodName := range goodRoleNames { p.Spec.Roles[0].Name = goodName err = p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) } } @@ -722,10 +718,10 @@ func TestAppProject_ValidateRoleName(t *testing.T) { func TestAppProject_ValidateGroupName(t *testing.T) { p := newTestProject() err := p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) p.Spec.Roles[0].Groups = []string{"mygroup"} err = p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) badGroupNames := []string{ "", " ", @@ -739,7 +735,7 @@ func TestAppProject_ValidateGroupName(t *testing.T) { for _, badName := range badGroupNames { p.Spec.Roles[0].Groups = []string{badName} err = p.ValidateProject() - assert.Error(t, err) + require.Error(t, err) } goodGroupNames := []string{ "my:group", @@ -747,7 +743,7 @@ func TestAppProject_ValidateGroupName(t *testing.T) { for _, goodName := range goodGroupNames { p.Spec.Roles[0].Groups = []string{goodName} err = p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) } } @@ -755,15 +751,15 @@ func TestAppProject_ValidateSyncWindowList(t *testing.T) { t.Run("WorkingSyncWindow", func(t *testing.T) { p := newTestProjectWithSyncWindows() err := p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("HasNilSyncWindow", func(t *testing.T) { p := newTestProjectWithSyncWindows() err := p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) p.Spec.SyncWindows = append(p.Spec.SyncWindows, nil) err = p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) }) } @@ -771,7 +767,7 @@ func TestAppProject_ValidateSyncWindowList(t *testing.T) { func TestAppProject_InvalidPolicyRules(t *testing.T) { p := newTestProject() err := p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) type badPolicy struct { policy string errmsg string @@ -805,9 +801,8 @@ func TestAppProject_InvalidPolicyRules(t *testing.T) { for _, bad := range badPolicies { p.Spec.Roles[0].Policies = []string{bad.policy} err = p.ValidateProject() - if assert.Error(t, err) { - assert.Contains(t, err.Error(), bad.errmsg) - } + require.Error(t, err) + assert.Contains(t, err.Error(), bad.errmsg) } } @@ -815,7 +810,7 @@ func TestAppProject_InvalidPolicyRules(t *testing.T) { func TestAppProject_ValidPolicyRules(t *testing.T) { p := newTestProject() err := p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) goodPolicies := []string{ "p,proj:my-proj:my-role,applications,get,my-proj/*,allow", "p, proj:my-proj:my-role, applications, get, my-proj/*, allow", @@ -828,15 +823,19 @@ func TestAppProject_ValidPolicyRules(t *testing.T) { "p, proj:my-proj:my-role, applications, *, my-proj/foo, allow", "p, proj:my-proj:my-role, applications, create, my-proj/foo, allow", "p, proj:my-proj:my-role, applications, update, my-proj/foo, allow", + "p, proj:my-proj:my-role, applications, update/*, my-proj/foo, allow", + "p, proj:my-proj:my-role, applications, update/*/Pod/*, my-proj/foo, allow", "p, proj:my-proj:my-role, applications, sync, my-proj/foo, allow", "p, proj:my-proj:my-role, applications, delete, my-proj/foo, allow", + "p, proj:my-proj:my-role, applications, delete/*, my-proj/foo, allow", + "p, proj:my-proj:my-role, applications, delete/*/Pod/*, my-proj/foo, allow", "p, proj:my-proj:my-role, applications, action/*, my-proj/foo, allow", "p, proj:my-proj:my-role, applications, action/apps/Deployment/restart, my-proj/foo, allow", } for _, good := range goodPolicies { p.Spec.Roles[0].Policies = []string{good} err = p.ValidateProject() - assert.NoError(t, err) + require.NoError(t, err) } } @@ -850,7 +849,7 @@ func TestExplicitType(t *testing.T) { }, } explicitType, err := src.ExplicitType() - assert.Error(t, err) + require.Error(t, err) assert.Nil(t, explicitType) src = ApplicationSource{ Helm: &ApplicationSourceHelm{ @@ -859,7 +858,7 @@ func TestExplicitType(t *testing.T) { } explicitType, err = src.ExplicitType() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, ApplicationSourceTypeHelm, *explicitType) } @@ -869,7 +868,7 @@ func TestExplicitTypeWithDirectory(t *testing.T) { Directory: &ApplicationSourceDirectory{}, } _, err := src.ExplicitType() - assert.Error(t, err, "cannot add directory with any other types") + require.Error(t, err, "cannot add directory with any other types") } func TestAppSourceEquality(t *testing.T) { @@ -884,6 +883,153 @@ func TestAppSourceEquality(t *testing.T) { assert.False(t, left.Equals(right)) } +func TestAppSource_GetKubeVersionOrDefault(t *testing.T) { + defaultKV := "999.999.999" + cases := []struct { + name string + source *ApplicationSource + expect string + }{ + { + "nil source returns default", + nil, + defaultKV, + }, + { + "source without Helm or Kustomize returns default", + &ApplicationSource{}, + defaultKV, + }, + { + "source with empty Helm returns default", + &ApplicationSource{Helm: &ApplicationSourceHelm{}}, + defaultKV, + }, + { + "source with empty Kustomize returns default", + &ApplicationSource{Kustomize: &ApplicationSourceKustomize{}}, + defaultKV, + }, + { + "source with Helm override returns override", + &ApplicationSource{Helm: &ApplicationSourceHelm{KubeVersion: "1.2.3"}}, + "1.2.3", + }, + { + "source with Kustomize override returns override", + &ApplicationSource{Kustomize: &ApplicationSourceKustomize{KubeVersion: "1.2.3"}}, + "1.2.3", + }, + } + + for _, tc := range cases { + tcc := tc + t.Run(tcc.name, func(t *testing.T) { + t.Parallel() + kv := tcc.source.GetKubeVersionOrDefault(defaultKV) + assert.Equal(t, tcc.expect, kv) + }) + } +} + +func TestAppSource_GetAPIVersionsOrDefault(t *testing.T) { + defaultAPIVersions := []string{"v1", "v2"} + cases := []struct { + name string + source *ApplicationSource + expect []string + }{ + { + "nil source returns default", + nil, + defaultAPIVersions, + }, + { + "source without Helm or Kustomize returns default", + &ApplicationSource{}, + defaultAPIVersions, + }, + { + "source with empty Helm returns default", + &ApplicationSource{Helm: &ApplicationSourceHelm{}}, + defaultAPIVersions, + }, + { + "source with empty Kustomize returns default", + &ApplicationSource{Kustomize: &ApplicationSourceKustomize{}}, + defaultAPIVersions, + }, + { + "source with Helm override returns override", + &ApplicationSource{Helm: &ApplicationSourceHelm{APIVersions: []string{"v3", "v4"}}}, + []string{"v3", "v4"}, + }, + { + "source with Kustomize override returns override", + &ApplicationSource{Kustomize: &ApplicationSourceKustomize{APIVersions: []string{"v3", "v4"}}}, + []string{"v3", "v4"}, + }, + } + + for _, tc := range cases { + tcc := tc + t.Run(tcc.name, func(t *testing.T) { + t.Parallel() + kv := tcc.source.GetAPIVersionsOrDefault(defaultAPIVersions) + assert.Equal(t, tcc.expect, kv) + }) + } +} + +func TestAppSource_GetNamespaceOrDefault(t *testing.T) { + defaultNS := "default" + cases := []struct { + name string + source *ApplicationSource + expect string + }{ + { + "nil source returns default", + nil, + defaultNS, + }, + { + "source without Helm or Kustomize returns default", + &ApplicationSource{}, + defaultNS, + }, + { + "source with empty Helm returns default", + &ApplicationSource{Helm: &ApplicationSourceHelm{}}, + defaultNS, + }, + { + "source with empty Kustomize returns default", + &ApplicationSource{Kustomize: &ApplicationSourceKustomize{}}, + defaultNS, + }, + { + "source with Helm override returns override", + &ApplicationSource{Helm: &ApplicationSourceHelm{Namespace: "not-default"}}, + "not-default", + }, + { + "source with Kustomize override returns override", + &ApplicationSource{Kustomize: &ApplicationSourceKustomize{Namespace: "not-default"}}, + "not-default", + }, + } + + for _, tc := range cases { + tcc := tc + t.Run(tcc.name, func(t *testing.T) { + t.Parallel() + kv := tcc.source.GetNamespaceOrDefault(defaultNS) + assert.Equal(t, tcc.expect, kv) + }) + } +} + func TestAppDestinationEquality(t *testing.T) { left := &ApplicationDestination{ Server: "https://kubernetes.default.svc", @@ -1122,6 +1268,7 @@ func TestRepository_CopyCredentialsFrom(t *testing.T) { {"SourceSSHPrivateKey", &Repository{}, &RepoCreds{SSHPrivateKey: "foo"}, Repository{SSHPrivateKey: "foo"}}, {"SourceTLSClientCertData", &Repository{}, &RepoCreds{TLSClientCertData: "foo"}, Repository{TLSClientCertData: "foo"}}, {"SourceTLSClientCertKey", &Repository{}, &RepoCreds{TLSClientCertKey: "foo"}, Repository{TLSClientCertKey: "foo"}}, + {"SourceContainsProxy", &Repository{}, &RepoCreds{Proxy: "http://proxy.argoproj.io:3128", NoProxy: ".example.com"}, Repository{Proxy: "http://proxy.argoproj.io:3128", NoProxy: ".example.com"}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1314,16 +1461,16 @@ func TestApplicationSourceHelm_AddFileParameter(t *testing.T) { func TestNewHelmParameter(t *testing.T) { t.Run("Invalid", func(t *testing.T) { _, err := NewHelmParameter("garbage", false) - assert.EqualError(t, err, "Expected helm parameter of the form: param=value. 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) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, &HelmParameter{Name: "foo", Value: "bar"}, p) }) t.Run("String", func(t *testing.T) { p, err := NewHelmParameter("foo=bar", true) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, &HelmParameter{Name: "foo", Value: "bar", ForceString: true}, p) }) } @@ -1331,16 +1478,16 @@ func TestNewHelmParameter(t *testing.T) { func TestNewKustomizeReplica(t *testing.T) { t.Run("Valid", func(t *testing.T) { r, err := NewKustomizeReplica("my-deployment=2") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, &KustomizeReplica{Name: "my-deployment", Count: intstr.Parse("2")}, r) }) t.Run("InvalidFormat", func(t *testing.T) { _, err := NewKustomizeReplica("garbage") - assert.EqualError(t, err, "expected parameter of the form: name=count. Received: garbage") + require.EqualError(t, err, "expected parameter of the form: name=count. Received: garbage") }) t.Run("InvalidCount", func(t *testing.T) { _, err := NewKustomizeReplica("my-deployment=garbage") - assert.EqualError(t, err, "expected integer value for count. Received: garbage") + require.EqualError(t, err, "expected integer value for count. Received: garbage") }) } @@ -1351,7 +1498,7 @@ func TestKustomizeReplica_GetIntCount(t *testing.T) { Count: intstr.FromString("2"), } count, err := kr.GetIntCount() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, 2, count) }) t.Run("String which cannot be converted to integer", func(t *testing.T) { @@ -1360,7 +1507,7 @@ func TestKustomizeReplica_GetIntCount(t *testing.T) { Count: intstr.FromString("garbage"), } count, err := kr.GetIntCount() - assert.EqualError(t, err, "expected integer value for count. Received: garbage") + require.EqualError(t, err, "expected integer value for count. Received: garbage") assert.Equal(t, 0, count) }) t.Run("Integer", func(t *testing.T) { @@ -1369,7 +1516,7 @@ func TestKustomizeReplica_GetIntCount(t *testing.T) { Count: intstr.FromInt(2), } count, err := kr.GetIntCount() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, 2, count) }) } @@ -1623,7 +1770,7 @@ func TestSyncWindows_HasWindows(t *testing.T) { t.Run("False", func(t *testing.T) { proj := newTestProjectWithSyncWindows() err := proj.Spec.DeleteWindow(0) - assert.NoError(t, err) + require.NoError(t, err) assert.False(t, proj.Spec.SyncWindows.HasWindows()) }) } @@ -1982,10 +2129,10 @@ func TestAppProjectSpec_AddWindow(t *testing.T) { t.Run(tt.name, func(t *testing.T) { switch tt.want { case "error": - assert.Error(t, tt.p.Spec.AddWindow(tt.k, tt.s, tt.d, tt.a, tt.n, tt.c, tt.m, tt.t)) + 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": - assert.NoError(t, tt.p.Spec.AddWindow(tt.k, tt.s, tt.d, tt.a, tt.n, tt.c, tt.m, tt.t)) - assert.NoError(t, tt.p.Spec.DeleteWindow(0)) + 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)) } }) } @@ -1997,12 +2144,12 @@ func TestAppProjectSpec_DeleteWindow(t *testing.T) { proj.Spec.SyncWindows = append(proj.Spec.SyncWindows, window2) t.Run("CannotFind", func(t *testing.T) { err := proj.Spec.DeleteWindow(3) - assert.Error(t, err) + require.Error(t, err) assert.Len(t, proj.Spec.SyncWindows, 2) }) t.Run("Delete", func(t *testing.T) { err := proj.Spec.DeleteWindow(0) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, proj.Spec.SyncWindows, 1) }) } @@ -2506,31 +2653,31 @@ 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{}, "") - assert.NoError(t, err) + 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{}, "") - assert.NoError(t, err) + 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"}, "") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []string{"cluster1"}, e.Clusters) }) t.Run("MissingConfig", func(t *testing.T) { err := e.Update("", "", []string{}, []string{}, []string{}, "") - assert.EqualError(t, err, "cannot update: require one or more of schedule, duration, application, namespace, or cluster") + 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{}, "") - assert.NoError(t, err) + 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{}, "") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "* 1 0 0 *", e.Schedule) }) } @@ -2538,22 +2685,22 @@ func TestSyncWindow_Update(t *testing.T) { func TestSyncWindow_Validate(t *testing.T) { window := &SyncWindow{Kind: "allow", Schedule: "* * * * *", Duration: "1h"} t.Run("Validates", func(t *testing.T) { - assert.NoError(t, window.Validate()) + require.NoError(t, window.Validate()) }) t.Run("IncorrectKind", func(t *testing.T) { window.Kind = "wrong" - assert.Error(t, window.Validate()) + require.Error(t, window.Validate()) }) t.Run("IncorrectSchedule", func(t *testing.T) { window.Kind = "allow" window.Schedule = "* * *" - assert.Error(t, window.Validate()) + require.Error(t, window.Validate()) }) t.Run("IncorrectDuration", func(t *testing.T) { window.Kind = "allow" window.Schedule = "* * * * *" window.Duration = "1000days" - assert.Error(t, window.Validate()) + require.Error(t, window.Validate()) }) } @@ -2965,7 +3112,7 @@ func TestRetryStrategy_NextRetryAtDefaultBackoff(t *testing.T) { for i, expected := range expectedTimes { retryAt, err := retry.NextRetryAt(now, int64(i)) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expected.Format(time.RFC850), retryAt.Format(time.RFC850)) } } @@ -2989,7 +3136,7 @@ func TestRetryStrategy_NextRetryAtCustomBackoff(t *testing.T) { for i, expected := range expectedTimes { retryAt, err := retry.NextRetryAt(now, int64(i)) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expected.Format(time.RFC850), retryAt.Format(time.RFC850)) } } @@ -3049,7 +3196,7 @@ func TestRemoveEnvEntry(t *testing.T) { &EnvEntry{"gamma", "delta"}, }, } - assert.NoError(t, plugins.RemoveEnvEntry("alpha")) + require.NoError(t, plugins.RemoveEnvEntry("alpha")) want := Env{&EnvEntry{"foo", "bar"}, &EnvEntry{"gamma", "delta"}} assert.Equal(t, want, plugins.Env) }) @@ -3058,7 +3205,7 @@ func TestRemoveEnvEntry(t *testing.T) { Name: "test", Env: Env{&EnvEntry{"foo", "bar"}}, } - assert.NoError(t, plugins.RemoveEnvEntry("foo")) + require.NoError(t, plugins.RemoveEnvEntry("foo")) assert.Equal(t, Env{}, plugins.Env) }) t.Run("Remove unknown element from the list", func(t *testing.T) { @@ -3067,15 +3214,15 @@ func TestRemoveEnvEntry(t *testing.T) { Env: Env{&EnvEntry{"foo", "bar"}}, } err := plugins.RemoveEnvEntry("key") - assert.EqualError(t, err, `unable to find env variable with key "key" for plugin "test"`) + require.EqualError(t, err, `unable to find env variable with key "key" for plugin "test"`) err = plugins.RemoveEnvEntry("bar") - assert.EqualError(t, err, `unable to find env variable with key "bar" for plugin "test"`) + require.EqualError(t, err, `unable to find env variable with key "bar" for plugin "test"`) assert.Equal(t, Env{&EnvEntry{"foo", "bar"}}, plugins.Env) }) t.Run("Remove element from an empty list", func(t *testing.T) { plugins := &ApplicationSourcePlugin{Name: "test"} err := plugins.RemoveEnvEntry("key") - assert.EqualError(t, err, `unable to find env variable with key "key" for plugin "test"`) + require.EqualError(t, err, `unable to find env variable with key "key" for plugin "test"`) }) } @@ -3090,7 +3237,7 @@ func TestOrphanedResourcesMonitorSettings_IsWarn(t *testing.T) { assert.True(t, settings.IsWarn()) } -func Test_isValidPolicy(t *testing.T) { +func Test_isValidPolicyObject(t *testing.T) { policyTests := []struct { name string policy string @@ -3156,28 +3303,28 @@ func Test_isValidPolicy(t *testing.T) { func Test_validatePolicy_projIsNotRegex(t *testing.T) { // Make sure the "." in "some.project" isn't treated as the regex wildcard. err := validatePolicy("some.project", "org-admin", "p, proj:some.project:org-admin, applications, *, some-project/*, allow") - assert.Error(t, err) + require.Error(t, err) err = validatePolicy("some.project", "org-admin", "p, proj:some.project:org-admin, applications, *, some.project/*, allow") - assert.NoError(t, err) + require.NoError(t, err) err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, applications, *, some-project/*, allow") - assert.NoError(t, err) + require.NoError(t, err) } func Test_validatePolicy_ValidResource(t *testing.T) { err := validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, applications, *, some-project/*, allow") - assert.NoError(t, err) + require.NoError(t, err) err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, repositories, *, some-project/*, allow") - assert.NoError(t, err) + require.NoError(t, err) err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, clusters, *, some-project/*, allow") - assert.NoError(t, err) + require.NoError(t, err) err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, exec, *, some-project/*, allow") - assert.NoError(t, err) + require.NoError(t, err) err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, logs, *, some-project/*, allow") - assert.NoError(t, err) + require.NoError(t, err) err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, unknown, *, some-project/*, allow") - assert.Error(t, err) + require.Error(t, err) } func TestEnvsubst(t *testing.T) { @@ -3217,9 +3364,9 @@ func Test_validateGroupName(t *testing.T) { t.Run(tt.name, func(t *testing.T) { err := validateGroupName(tt.groupname) if tt.isvalid { - assert.NoError(t, err) + require.NoError(t, err) } else { - assert.Error(t, err) + require.Error(t, err) } }) } @@ -3240,18 +3387,25 @@ func TestGetCAPath(t *testing.T) { "https://foo.example.com", "oci://foo.example.com", "foo.example.com", + "foo.example.com/charts", + "https://foo.example.com:5000", + "foo.example.com:5000", + "foo.example.com:5000/charts", + "ssh://foo.example.com", } invalidpath := []string{ "https://bar.example.com", "oci://bar.example.com", "bar.example.com", - "ssh://foo.example.com", - "git@example.com:organization/reponame.git", + "ssh://bar.example.com", + "git@foo.example.com:organization/reponame.git", + "ssh://git@foo.example.com:organization/reponame.git", "/some/invalid/thing", "../another/invalid/thing", "./also/invalid", "$invalid/as/well", "..", + "://invalid", } for _, str := range validcert { @@ -3736,34 +3890,72 @@ func TestApplicationSpec_GetSourcePtrByIndex(t *testing.T) { } } -func TestHelmValuesObjectHasReplaceStrategy(t *testing.T) { - app := Application{ - Status: ApplicationStatus{Sync: SyncStatus{ComparedTo: ComparedTo{ - Source: ApplicationSource{ - Helm: &ApplicationSourceHelm{ - ValuesObject: &runtime.RawExtension{ - Object: &unstructured.Unstructured{Object: map[string]interface{}{"key": []string{"value"}}}, - }, - }, - }, - }}}, +func TestApplicationTree_GetShards(t *testing.T) { + tree := &ApplicationTree{ + Nodes: []ResourceNode{ + {ResourceRef: ResourceRef{Name: "node 1"}}, {ResourceRef: ResourceRef{Name: "node 2"}}, {ResourceRef: ResourceRef{Name: "node 3"}}, + }, + OrphanedNodes: []ResourceNode{ + {ResourceRef: ResourceRef{Name: "orph-node 1"}}, {ResourceRef: ResourceRef{Name: "orph-node 2"}}, {ResourceRef: ResourceRef{Name: "orph-node 3"}}, + }, + Hosts: []HostInfo{ + {Name: "host 1"}, {Name: "host 2"}, {Name: "host 3"}, + }, } - appModified := Application{ - Status: ApplicationStatus{Sync: SyncStatus{ComparedTo: ComparedTo{ - Source: ApplicationSource{ - Helm: &ApplicationSourceHelm{ - ValuesObject: &runtime.RawExtension{ - Object: &unstructured.Unstructured{Object: map[string]interface{}{"key": []string{"value-modified1"}}}, - }, - }, - }, - }}}, - } + shards := tree.GetShards(2) + require.Len(t, shards, 5) + require.Equal(t, &ApplicationTree{ + ShardsCount: 5, + Nodes: []ResourceNode{ + {ResourceRef: ResourceRef{Name: "node 1"}}, {ResourceRef: ResourceRef{Name: "node 2"}}, + }, + }, shards[0]) + require.Equal(t, &ApplicationTree{ + Nodes: []ResourceNode{{ResourceRef: ResourceRef{Name: "node 3"}}}, + OrphanedNodes: []ResourceNode{{ResourceRef: ResourceRef{Name: "orph-node 1"}}}, + }, shards[1]) + require.Equal(t, &ApplicationTree{ + OrphanedNodes: []ResourceNode{{ResourceRef: ResourceRef{Name: "orph-node 2"}}, {ResourceRef: ResourceRef{Name: "orph-node 3"}}}, + }, shards[2]) + require.Equal(t, &ApplicationTree{ + Hosts: []HostInfo{{Name: "host 1"}, {Name: "host 2"}}, + }, shards[3]) + require.Equal(t, &ApplicationTree{ + Hosts: []HostInfo{{Name: "host 3"}}, + }, shards[4]) +} - patch, _, err := diff.CreateTwoWayMergePatch( - app, - appModified, Application{}) - require.NoError(t, err) - assert.Equal(t, `{"status":{"sync":{"comparedTo":{"destination":{},"source":{"helm":{"valuesObject":{"key":["value-modified1"]}},"repoURL":""}}}}}`, string(patch)) +func TestApplicationTree_Merge(t *testing.T) { + tree := &ApplicationTree{} + tree.Merge(&ApplicationTree{ + ShardsCount: 5, + Nodes: []ResourceNode{ + {ResourceRef: ResourceRef{Name: "node 1"}}, {ResourceRef: ResourceRef{Name: "node 2"}}, + }, + }) + tree.Merge(&ApplicationTree{ + Nodes: []ResourceNode{{ResourceRef: ResourceRef{Name: "node 3"}}}, + OrphanedNodes: []ResourceNode{{ResourceRef: ResourceRef{Name: "orph-node 1"}}}, + }) + tree.Merge(&ApplicationTree{ + OrphanedNodes: []ResourceNode{{ResourceRef: ResourceRef{Name: "orph-node 2"}}, {ResourceRef: ResourceRef{Name: "orph-node 3"}}}, + }) + tree.Merge(&ApplicationTree{ + Hosts: []HostInfo{{Name: "host 1"}, {Name: "host 2"}}, + }) + tree.Merge(&ApplicationTree{ + Hosts: []HostInfo{{Name: "host 3"}}, + }) + require.Equal(t, &ApplicationTree{ + Nodes: []ResourceNode{ + {ResourceRef: ResourceRef{Name: "node 1"}}, {ResourceRef: ResourceRef{Name: "node 2"}}, {ResourceRef: ResourceRef{Name: "node 3"}}, + }, + OrphanedNodes: []ResourceNode{ + {ResourceRef: ResourceRef{Name: "orph-node 1"}}, {ResourceRef: ResourceRef{Name: "orph-node 2"}}, {ResourceRef: ResourceRef{Name: "orph-node 3"}}, + }, + Hosts: []HostInfo{ + {Name: "host 1"}, {Name: "host 2"}, {Name: "host 3"}, + }, + }, tree) } diff --git a/pkg/apis/application/v1alpha1/values_test.go b/pkg/apis/application/v1alpha1/values_test.go index f21f17168a2e8..6c2c5676f3f62 100644 --- a/pkg/apis/application/v1alpha1/values_test.go +++ b/pkg/apis/application/v1alpha1/values_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestValues_SetString(t *testing.T) { @@ -69,12 +70,12 @@ func TestValues_SetString(t *testing.T) { if !testCase.expectError { assert.Equal(t, testCase.expectValue, source.ValuesString()) data, err := source.ValuesObject.MarshalJSON() - assert.NoError(t, err) + require.NoError(t, err) err = source.ValuesObject.UnmarshalJSON(data) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testCase.expectValue, source.ValuesString()) } else { - assert.Error(t, err) + require.Error(t, err) } }) } diff --git a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go index a6de15dd7a265..7e1d69473b067 100644 --- a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go @@ -156,6 +156,11 @@ func (in *AppProjectSpec) DeepCopyInto(out *AppProjectSpec) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.DestinationServiceAccounts != nil { + in, out := &in.DestinationServiceAccounts, &out.DestinationServiceAccounts + *out = make([]ApplicationDestinationServiceAccount, len(*in)) + copy(*out, *in) + } return } @@ -261,6 +266,22 @@ func (in *ApplicationDestination) DeepCopy() *ApplicationDestination { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ApplicationDestinationServiceAccount) DeepCopyInto(out *ApplicationDestinationServiceAccount) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationDestinationServiceAccount. +func (in *ApplicationDestinationServiceAccount) DeepCopy() *ApplicationDestinationServiceAccount { + if in == nil { + return nil + } + out := new(ApplicationDestinationServiceAccount) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ApplicationList) DeepCopyInto(out *ApplicationList) { *out = *in diff --git a/pkg/ratelimiter/ratelimiter.go b/pkg/ratelimiter/ratelimiter.go index 1c491a584873e..53536f7b39a62 100644 --- a/pkg/ratelimiter/ratelimiter.go +++ b/pkg/ratelimiter/ratelimiter.go @@ -35,10 +35,10 @@ func GetDefaultAppRateLimiterConfig() *AppControllerRateLimiterConfig { // NewCustomAppControllerRateLimiter is a constructor for the rate limiter for a workqueue used by app controller. It has // both overall and per-item rate limiting. The overall is a token bucket and the per-item is exponential(with auto resets) -func NewCustomAppControllerRateLimiter(cfg *AppControllerRateLimiterConfig) workqueue.RateLimiter { - return workqueue.NewMaxOfRateLimiter( +func NewCustomAppControllerRateLimiter(cfg *AppControllerRateLimiterConfig) workqueue.TypedRateLimiter[string] { + return workqueue.NewTypedMaxOfRateLimiter[string]( NewItemExponentialRateLimiterWithAutoReset(cfg.BaseDelay, cfg.MaxDelay, cfg.FailureCoolDown, cfg.BackoffFactor), - &workqueue.BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(cfg.BucketQPS), int(cfg.BucketSize))}, + &workqueue.TypedBucketRateLimiter[string]{Limiter: rate.NewLimiter(rate.Limit(cfg.BucketQPS), int(cfg.BucketSize))}, ) } @@ -59,9 +59,9 @@ type ItemExponentialRateLimiterWithAutoReset struct { backoffFactor float64 } -var _ workqueue.RateLimiter = &ItemExponentialRateLimiterWithAutoReset{} +var _ workqueue.TypedRateLimiter[string] = &ItemExponentialRateLimiterWithAutoReset{} -func NewItemExponentialRateLimiterWithAutoReset(baseDelay, maxDelay, failureCoolDown time.Duration, backoffFactor float64) workqueue.RateLimiter { +func NewItemExponentialRateLimiterWithAutoReset(baseDelay, maxDelay, failureCoolDown time.Duration, backoffFactor float64) workqueue.TypedRateLimiter[string] { return &ItemExponentialRateLimiterWithAutoReset{ failures: map[interface{}]failureData{}, baseDelay: baseDelay, @@ -71,7 +71,7 @@ func NewItemExponentialRateLimiterWithAutoReset(baseDelay, maxDelay, failureCool } } -func (r *ItemExponentialRateLimiterWithAutoReset) When(item interface{}) time.Duration { +func (r *ItemExponentialRateLimiterWithAutoReset) When(item string) time.Duration { r.failuresLock.Lock() defer r.failuresLock.Unlock() @@ -109,14 +109,14 @@ func (r *ItemExponentialRateLimiterWithAutoReset) When(item interface{}) time.Du return calculated } -func (r *ItemExponentialRateLimiterWithAutoReset) NumRequeues(item interface{}) int { +func (r *ItemExponentialRateLimiterWithAutoReset) NumRequeues(item string) int { r.failuresLock.Lock() defer r.failuresLock.Unlock() return r.failures[item].failures } -func (r *ItemExponentialRateLimiterWithAutoReset) Forget(item interface{}) { +func (r *ItemExponentialRateLimiterWithAutoReset) Forget(item string) { r.failuresLock.Lock() defer r.failuresLock.Unlock() diff --git a/reposerver/apiclient/clientset.go b/reposerver/apiclient/clientset.go index 23453a800ae52..11bccf550203d 100644 --- a/reposerver/apiclient/clientset.go +++ b/reposerver/apiclient/clientset.go @@ -21,8 +21,6 @@ import ( "github.com/argoproj/argo-cd/v2/util/io" ) -//go:generate go run github.com/vektra/mockery/v2@v2.40.2 --name=RepoServerServiceClient - // MaxGRPCMessageSize contains max grpc message size var MaxGRPCMessageSize = env.ParseNumFromEnv(common.EnvGRPCMaxSizeMB, 100, 0, math.MaxInt32) * 1024 * 1024 @@ -84,6 +82,7 @@ func NewConnection(address string, timeoutSeconds int, tlsConfig *TLSConfigurati opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) } + // 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 8ae768cb58119..c0966b799de50 100644 --- a/reposerver/apiclient/clientset_test.go +++ b/reposerver/apiclient/clientset_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" @@ -16,7 +17,7 @@ func TestNewRepoServerClient_CorrectClientReturned(t *testing.T) { closer, client, err := mockClientset.NewRepoServerClient() - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, closer) assert.NotNil(t, client) assert.Equal(t, mockClientset.RepoServerServiceClient, client) @@ -59,7 +60,7 @@ func TestNewConnection_TLSWithStrictValidation(t *testing.T) { conn, err := apiclient.NewConnection("example.com:443", 10, &tlsConfig) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, conn) } @@ -72,7 +73,7 @@ func TestNewConnection_TLSWithStrictValidationAndCertificates(t *testing.T) { conn, err := apiclient.NewConnection("example.com:443", 10, &tlsConfig) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, conn) } @@ -86,6 +87,6 @@ func TestNewConnection_InsecureConnection(t *testing.T) { conn, err := apiclient.NewConnection("example.com:80", 10, &tlsConfig) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, conn) } diff --git a/reposerver/apiclient/mocks/RepoServerServiceClient.go b/reposerver/apiclient/mocks/RepoServerServiceClient.go index 2dd9abb7f638e..056747e5b28be 100644 --- a/reposerver/apiclient/mocks/RepoServerServiceClient.go +++ b/reposerver/apiclient/mocks/RepoServerServiceClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.40.2. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks diff --git a/reposerver/apiclient/mocks/RepoServerService_GenerateManifestWithFilesClient.go b/reposerver/apiclient/mocks/RepoServerService_GenerateManifestWithFilesClient.go index 79151a7ca1f58..eaed2fcb9e571 100644 --- a/reposerver/apiclient/mocks/RepoServerService_GenerateManifestWithFilesClient.go +++ b/reposerver/apiclient/mocks/RepoServerService_GenerateManifestWithFilesClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.13.1. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks @@ -21,7 +21,15 @@ type RepoServerService_GenerateManifestWithFilesClient struct { 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 { @@ -30,7 +38,6 @@ func (_m *RepoServerService_GenerateManifestWithFilesClient) CloseAndRecv() (*ap } } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -44,6 +51,10 @@ func (_m *RepoServerService_GenerateManifestWithFilesClient) CloseAndRecv() (*ap 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() @@ -58,6 +69,10 @@ func (_m *RepoServerService_GenerateManifestWithFilesClient) CloseSend() error { 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() @@ -74,7 +89,15 @@ func (_m *RepoServerService_GenerateManifestWithFilesClient) Context() context.C 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 { @@ -83,7 +106,6 @@ func (_m *RepoServerService_GenerateManifestWithFilesClient) Header() (metadata. } } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -97,6 +119,10 @@ func (_m *RepoServerService_GenerateManifestWithFilesClient) Header() (metadata. 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) @@ -111,6 +137,10 @@ func (_m *RepoServerService_GenerateManifestWithFilesClient) RecvMsg(m interface 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) @@ -125,6 +155,10 @@ func (_m *RepoServerService_GenerateManifestWithFilesClient) Send(_a0 *apiclient 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) @@ -139,6 +173,10 @@ func (_m *RepoServerService_GenerateManifestWithFilesClient) SendMsg(m interface 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() @@ -151,13 +189,12 @@ func (_m *RepoServerService_GenerateManifestWithFilesClient) Trailer() metadata. return r0 } -type mockConstructorTestingTNewRepoServerService_GenerateManifestWithFilesClient interface { +// 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 { mock.TestingT Cleanup(func()) -} - -// 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. -func NewRepoServerService_GenerateManifestWithFilesClient(t mockConstructorTestingTNewRepoServerService_GenerateManifestWithFilesClient) *RepoServerService_GenerateManifestWithFilesClient { +}) *RepoServerService_GenerateManifestWithFilesClient { mock := &RepoServerService_GenerateManifestWithFilesClient{} mock.Mock.Test(t) diff --git a/reposerver/apiclient/repository.pb.go b/reposerver/apiclient/repository.pb.go index 549137a342809..61c14068bdd18 100644 --- a/reposerver/apiclient/repository.pb.go +++ b/reposerver/apiclient/repository.pb.go @@ -43,8 +43,10 @@ type ManifestRequest struct { // Deprecated: use sidecar plugins instead. Plugins []*v1alpha1.ConfigManagementPlugin `protobuf:"bytes,12,rep,name=plugins,proto3" json:"plugins,omitempty"` KustomizeOptions *v1alpha1.KustomizeOptions `protobuf:"bytes,13,opt,name=kustomizeOptions,proto3" json:"kustomizeOptions,omitempty"` - KubeVersion string `protobuf:"bytes,14,opt,name=kubeVersion,proto3" json:"kubeVersion,omitempty"` - ApiVersions []string `protobuf:"bytes,15,rep,name=apiVersions,proto3" json:"apiVersions,omitempty"` + // KubeVersion is the Kubernetes API version from the destination cluster. + KubeVersion string `protobuf:"bytes,14,opt,name=kubeVersion,proto3" json:"kubeVersion,omitempty"` + // ApiVersions is the list of API versions from the destination cluster, used for rendering Helm charts. + ApiVersions []string `protobuf:"bytes,15,rep,name=apiVersions,proto3" json:"apiVersions,omitempty"` // Request to verify the signature when generating the manifests (only for Git repositories) VerifySignature bool `protobuf:"varint,16,opt,name=verifySignature,proto3" json:"verifySignature,omitempty"` HelmRepoCreds []*v1alpha1.RepoCreds `protobuf:"bytes,17,rep,name=helmRepoCreds,proto3" json:"helmRepoCreds,omitempty"` @@ -57,10 +59,12 @@ type ManifestRequest struct { // This is used to surface "source not permitted" errors for Helm repositories ProjectSourceRepos []string `protobuf:"bytes,24,rep,name=projectSourceRepos,proto3" json:"projectSourceRepos,omitempty"` // This is used to surface "source not permitted" errors for Helm repositories - ProjectName string `protobuf:"bytes,25,opt,name=projectName,proto3" json:"projectName,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ProjectName string `protobuf:"bytes,25,opt,name=projectName,proto3" json:"projectName,omitempty"` + // argocd.argoproj.io/manifest-generate-paths annotation value of the Application to allow optimize which resources propagated to cmpserver + AnnotationManifestGeneratePaths string `protobuf:"bytes,26,opt,name=AnnotationManifestGeneratePaths,proto3" json:"AnnotationManifestGeneratePaths,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *ManifestRequest) Reset() { *m = ManifestRequest{} } @@ -250,6 +254,13 @@ func (m *ManifestRequest) GetProjectName() string { return "" } +func (m *ManifestRequest) GetAnnotationManifestGeneratePaths() string { + if m != nil { + return m.AnnotationManifestGeneratePaths + } + return "" +} + type ManifestRequestWithFiles struct { // Types that are valid to be assigned to Part: // *ManifestRequestWithFiles_Request @@ -689,7 +700,9 @@ type ManifestResponse struct { Revision string `protobuf:"bytes,4,opt,name=revision,proto3" json:"revision,omitempty"` SourceType string `protobuf:"bytes,6,opt,name=sourceType,proto3" json:"sourceType,omitempty"` // Raw response of git verify-commit operation (always the empty string for Helm) - VerifyResult string `protobuf:"bytes,7,opt,name=verifyResult,proto3" json:"verifyResult,omitempty"` + VerifyResult string `protobuf:"bytes,7,opt,name=verifyResult,proto3" json:"verifyResult,omitempty"` + // Commands is the list of commands used to hydrate the manifests + Commands []string `protobuf:"bytes,8,rep,name=commands,proto3" json:"commands,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -770,6 +783,13 @@ func (m *ManifestResponse) GetVerifyResult() string { return "" } +func (m *ManifestResponse) GetCommands() []string { + if m != nil { + return m.Commands + } + return nil +} + type ListRefsRequest struct { Repo *v1alpha1.Repository `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -2196,6 +2216,7 @@ type UpdateRevisionForPathsRequest struct { SyncedRevision string `protobuf:"bytes,11,opt,name=syncedRevision,proto3" json:"syncedRevision,omitempty"` Revision string `protobuf:"bytes,12,opt,name=revision,proto3" json:"revision,omitempty"` Paths []string `protobuf:"bytes,13,rep,name=paths,proto3" json:"paths,omitempty"` + NoRevisionCache bool `protobuf:"varint,14,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -2325,7 +2346,16 @@ func (m *UpdateRevisionForPathsRequest) GetPaths() []string { return nil } +func (m *UpdateRevisionForPathsRequest) GetNoRevisionCache() bool { + if m != nil { + return m.NoRevisionCache + } + return false +} + type UpdateRevisionForPathsResponse struct { + Changes bool `protobuf:"varint,1,opt,name=changes,proto3" json:"changes,omitempty"` + Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -2364,6 +2394,20 @@ func (m *UpdateRevisionForPathsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_UpdateRevisionForPathsResponse proto.InternalMessageInfo +func (m *UpdateRevisionForPathsResponse) GetChanges() bool { + if m != nil { + return m.Changes + } + return false +} + +func (m *UpdateRevisionForPathsResponse) GetRevision() string { + if m != nil { + return m.Revision + } + return "" +} + func init() { proto.RegisterType((*ManifestRequest)(nil), "repository.ManifestRequest") proto.RegisterMapType((map[string]bool)(nil), "repository.ManifestRequest.EnabledSourceTypesEntry") @@ -2414,151 +2458,154 @@ func init() { } var fileDescriptor_dd8723cfcc820480 = []byte{ - // 2298 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x5a, 0xcd, 0x73, 0x1c, 0x47, - 0x15, 0xd7, 0x7e, 0x6a, 0xf7, 0x49, 0xd6, 0x47, 0xdb, 0x96, 0xc7, 0x1b, 0x5b, 0xa5, 0x0c, 0xd8, - 0xe5, 0xd8, 0xc9, 0x6e, 0x59, 0xae, 0xc4, 0xe0, 0x84, 0x50, 0x8a, 0x62, 0x4b, 0x8e, 0x2d, 0x5b, - 0x8c, 0x1d, 0x28, 0x83, 0x81, 0xea, 0x9d, 0xed, 0xdd, 0x9d, 0xec, 0x7c, 0xb4, 0x67, 0x7a, 0x14, - 0xd6, 0x55, 0x9c, 0xa0, 0xb8, 0x70, 0xe7, 0xc0, 0x95, 0x7f, 0x80, 0x0b, 0xc5, 0x91, 0x03, 0xc5, - 0xc7, 0x91, 0xe2, 0xc2, 0x11, 0xca, 0x47, 0xfe, 0x0a, 0xaa, 0x3f, 0xe6, 0x73, 0x67, 0xd7, 0x0a, - 0x6b, 0x2b, 0x90, 0x8b, 0x34, 0xfd, 0xba, 0xfb, 0xbd, 0xd7, 0xaf, 0xdf, 0x7b, 0xfd, 0x7b, 0xdd, - 0x0b, 0x97, 0x7d, 0x42, 0xbd, 0x80, 0xf8, 0x47, 0xc4, 0xef, 0x88, 0x4f, 0x8b, 0x79, 0xfe, 0x38, - 0xf5, 0xd9, 0xa6, 0xbe, 0xc7, 0x3c, 0x04, 0x09, 0xa5, 0x75, 0x7f, 0x60, 0xb1, 0x61, 0xd8, 0x6d, - 0x9b, 0x9e, 0xd3, 0xc1, 0xfe, 0xc0, 0xa3, 0xbe, 0xf7, 0x99, 0xf8, 0x78, 0xc7, 0xec, 0x75, 0x8e, - 0xb6, 0x3b, 0x74, 0x34, 0xe8, 0x60, 0x6a, 0x05, 0x1d, 0x4c, 0xa9, 0x6d, 0x99, 0x98, 0x59, 0x9e, - 0xdb, 0x39, 0xba, 0x8e, 0x6d, 0x3a, 0xc4, 0xd7, 0x3b, 0x03, 0xe2, 0x12, 0x1f, 0x33, 0xd2, 0x93, - 0x9c, 0x5b, 0x6f, 0x0c, 0x3c, 0x6f, 0x60, 0x93, 0x8e, 0x68, 0x75, 0xc3, 0x7e, 0x87, 0x38, 0x94, - 0x29, 0xb1, 0xfa, 0xbf, 0x97, 0x61, 0xf5, 0x00, 0xbb, 0x56, 0x9f, 0x04, 0xcc, 0x20, 0xcf, 0x42, - 0x12, 0x30, 0xf4, 0x14, 0xaa, 0x5c, 0x19, 0xad, 0xb4, 0x55, 0xba, 0xb2, 0xb4, 0xbd, 0xdf, 0x4e, - 0xb4, 0x69, 0x47, 0xda, 0x88, 0x8f, 0x1f, 0x9b, 0xbd, 0xf6, 0xd1, 0x76, 0x9b, 0x8e, 0x06, 0x6d, - 0xae, 0x4d, 0x3b, 0xa5, 0x4d, 0x3b, 0xd2, 0xa6, 0x6d, 0xc4, 0xcb, 0x32, 0x04, 0x57, 0xd4, 0x82, - 0x86, 0x4f, 0x8e, 0xac, 0xc0, 0xf2, 0x5c, 0xad, 0xbc, 0x55, 0xba, 0xd2, 0x34, 0xe2, 0x36, 0xd2, - 0x60, 0xd1, 0xf5, 0x76, 0xb1, 0x39, 0x24, 0x5a, 0x65, 0xab, 0x74, 0xa5, 0x61, 0x44, 0x4d, 0xb4, - 0x05, 0x4b, 0x98, 0xd2, 0xfb, 0xb8, 0x4b, 0xec, 0x7b, 0x64, 0xac, 0x55, 0xc5, 0xc4, 0x34, 0x89, - 0xcf, 0xc5, 0x94, 0x3e, 0xc0, 0x0e, 0xd1, 0x6a, 0xa2, 0x37, 0x6a, 0xa2, 0x0b, 0xd0, 0x74, 0xb1, - 0x43, 0x02, 0x8a, 0x4d, 0xa2, 0x35, 0x44, 0x5f, 0x42, 0x40, 0x3f, 0x85, 0xf5, 0x94, 0xe2, 0x8f, - 0xbc, 0xd0, 0x37, 0x89, 0x06, 0x62, 0xe9, 0x0f, 0xe7, 0x5b, 0xfa, 0x4e, 0x9e, 0xad, 0x31, 0x29, - 0x09, 0xfd, 0x08, 0x6a, 0x62, 0xe7, 0xb5, 0xa5, 0xad, 0xca, 0x2b, 0xb5, 0xb6, 0x64, 0x8b, 0x5c, - 0x58, 0xa4, 0x76, 0x38, 0xb0, 0xdc, 0x40, 0x5b, 0x16, 0x12, 0x1e, 0xcf, 0x27, 0x61, 0xd7, 0x73, - 0xfb, 0xd6, 0xe0, 0x00, 0xbb, 0x78, 0x40, 0x1c, 0xe2, 0xb2, 0x43, 0xc1, 0xdc, 0x88, 0x84, 0xa0, - 0xe7, 0xb0, 0x36, 0x0a, 0x03, 0xe6, 0x39, 0xd6, 0x73, 0xf2, 0x90, 0xf2, 0xb9, 0x81, 0x76, 0x4a, - 0x58, 0xf3, 0xc1, 0x7c, 0x82, 0xef, 0xe5, 0xb8, 0x1a, 0x13, 0x72, 0xb8, 0x93, 0x8c, 0xc2, 0x2e, - 0xf9, 0x2e, 0xf1, 0x85, 0x77, 0xad, 0x48, 0x27, 0x49, 0x91, 0xa4, 0x1b, 0x59, 0xaa, 0x15, 0x68, - 0xab, 0x5b, 0x15, 0xe9, 0x46, 0x31, 0x09, 0x5d, 0x81, 0xd5, 0x23, 0xe2, 0x5b, 0xfd, 0xf1, 0x23, - 0x6b, 0xe0, 0x62, 0x16, 0xfa, 0x44, 0x5b, 0x13, 0xae, 0x98, 0x27, 0x23, 0x07, 0x4e, 0x0d, 0x89, - 0xed, 0x70, 0x93, 0xef, 0xfa, 0xa4, 0x17, 0x68, 0xeb, 0xc2, 0xbe, 0x7b, 0xf3, 0xef, 0xa0, 0x60, - 0x67, 0x64, 0xb9, 0x73, 0xc5, 0x5c, 0xcf, 0x50, 0x91, 0x22, 0x63, 0x04, 0x49, 0xc5, 0x72, 0x64, - 0x74, 0x19, 0x56, 0x98, 0x8f, 0xcd, 0x91, 0xe5, 0x0e, 0x0e, 0x08, 0x1b, 0x7a, 0x3d, 0xed, 0xb4, - 0xb0, 0x44, 0x8e, 0x8a, 0x4c, 0x40, 0xc4, 0xc5, 0x5d, 0x9b, 0xf4, 0xa4, 0x2f, 0x3e, 0x1e, 0x53, - 0x12, 0x68, 0x67, 0xc4, 0x2a, 0x6e, 0xb4, 0x53, 0x19, 0x2a, 0x97, 0x20, 0xda, 0xb7, 0x27, 0x66, - 0xdd, 0x76, 0x99, 0x3f, 0x36, 0x0a, 0xd8, 0xa1, 0x11, 0x2c, 0xf1, 0x75, 0x44, 0xae, 0x70, 0x56, - 0xb8, 0xc2, 0xdd, 0xf9, 0x6c, 0xb4, 0x9f, 0x30, 0x34, 0xd2, 0xdc, 0x51, 0x1b, 0xd0, 0x10, 0x07, - 0x07, 0xa1, 0xcd, 0x2c, 0x6a, 0x13, 0xa9, 0x46, 0xa0, 0x6d, 0x08, 0x33, 0x15, 0xf4, 0xa0, 0x7b, - 0x00, 0x3e, 0xe9, 0x47, 0xe3, 0xce, 0x89, 0x95, 0x5f, 0x9b, 0xb5, 0x72, 0x23, 0x1e, 0x2d, 0x57, - 0x9c, 0x9a, 0xce, 0x85, 0xf3, 0x65, 0x10, 0x93, 0xa9, 0x68, 0x17, 0x61, 0xad, 0x09, 0x17, 0x2b, - 0xe8, 0xe1, 0xbe, 0xa8, 0xa8, 0x22, 0x69, 0x9d, 0x97, 0xde, 0x9a, 0x22, 0xb5, 0x6e, 0xc3, 0xb9, - 0x29, 0xa6, 0x46, 0x6b, 0x50, 0x19, 0x91, 0xb1, 0x48, 0xd1, 0x4d, 0x83, 0x7f, 0xa2, 0x33, 0x50, - 0x3b, 0xc2, 0x76, 0x48, 0x44, 0x52, 0x6d, 0x18, 0xb2, 0x71, 0xab, 0xfc, 0x8d, 0x52, 0xeb, 0x17, - 0x25, 0x58, 0xcd, 0x29, 0x5e, 0x30, 0xff, 0x87, 0xe9, 0xf9, 0xaf, 0xc0, 0x8d, 0xfb, 0x8f, 0xb1, - 0x3f, 0x20, 0x2c, 0xa5, 0x88, 0xfe, 0xf7, 0x12, 0x68, 0x39, 0x8b, 0x7e, 0xcf, 0x62, 0xc3, 0x3b, - 0x96, 0x4d, 0x02, 0x74, 0x13, 0x16, 0x7d, 0x49, 0x53, 0x07, 0xcf, 0x1b, 0x33, 0x36, 0x62, 0x7f, - 0xc1, 0x88, 0x46, 0xa3, 0x0f, 0xa1, 0xe1, 0x10, 0x86, 0x7b, 0x98, 0x61, 0xa5, 0xfb, 0x56, 0xd1, - 0x4c, 0x2e, 0xe5, 0x40, 0x8d, 0xdb, 0x5f, 0x30, 0xe2, 0x39, 0xe8, 0x5d, 0xa8, 0x99, 0xc3, 0xd0, - 0x1d, 0x89, 0x23, 0x67, 0x69, 0xfb, 0xe2, 0xb4, 0xc9, 0xbb, 0x7c, 0xd0, 0xfe, 0x82, 0x21, 0x47, - 0x7f, 0x54, 0x87, 0x2a, 0xc5, 0x3e, 0xd3, 0xef, 0xc0, 0x99, 0x22, 0x11, 0xfc, 0x9c, 0x33, 0x87, - 0xc4, 0x1c, 0x05, 0xa1, 0xa3, 0xcc, 0x1c, 0xb7, 0x11, 0x82, 0x6a, 0x60, 0x3d, 0x97, 0xa6, 0xae, - 0x18, 0xe2, 0x5b, 0x7f, 0x0b, 0xd6, 0x27, 0xa4, 0xf1, 0x4d, 0x95, 0xba, 0x71, 0x0e, 0xcb, 0x4a, - 0xb4, 0x1e, 0xc2, 0xd9, 0xc7, 0xc2, 0x16, 0x71, 0xb2, 0x3f, 0x89, 0x93, 0x5b, 0xdf, 0x87, 0x8d, - 0xbc, 0xd8, 0x80, 0x7a, 0x6e, 0x40, 0xb8, 0xeb, 0x8b, 0xec, 0x68, 0x91, 0x5e, 0xd2, 0x2b, 0xb4, - 0x68, 0x18, 0x05, 0x3d, 0xfa, 0x6f, 0xca, 0xb0, 0x61, 0x90, 0xc0, 0xb3, 0x8f, 0x48, 0x94, 0xba, - 0x4e, 0x06, 0x7c, 0xfc, 0x00, 0x2a, 0x98, 0x52, 0xe5, 0x26, 0x77, 0x5f, 0xd9, 0xf1, 0x6e, 0x70, - 0xae, 0xe8, 0x6d, 0x58, 0xc7, 0x4e, 0xd7, 0x1a, 0x84, 0x5e, 0x18, 0x44, 0xcb, 0x12, 0x4e, 0xd5, - 0x34, 0x26, 0x3b, 0x78, 0xf8, 0x07, 0x22, 0x22, 0xef, 0xba, 0x3d, 0xf2, 0x13, 0x81, 0x68, 0x2a, - 0x46, 0x9a, 0xa4, 0x9b, 0x70, 0x6e, 0xc2, 0x48, 0xca, 0xe0, 0x69, 0x10, 0x55, 0xca, 0x81, 0xa8, - 0x42, 0x35, 0xca, 0x53, 0xd4, 0xd0, 0xff, 0x5c, 0x82, 0xb5, 0x24, 0xb8, 0x14, 0xfb, 0x0b, 0xd0, - 0x74, 0x14, 0x2d, 0xd0, 0x4a, 0x22, 0x83, 0x25, 0x84, 0x2c, 0x9e, 0x2a, 0xe7, 0xf1, 0xd4, 0x06, - 0xd4, 0x25, 0xdc, 0x55, 0x4b, 0x57, 0xad, 0x8c, 0xca, 0xd5, 0x9c, 0xca, 0x9b, 0x00, 0x41, 0x9c, - 0xe1, 0xb4, 0xba, 0xe8, 0x4d, 0x51, 0x90, 0x0e, 0xcb, 0xf2, 0xf4, 0x35, 0x48, 0x10, 0xda, 0x4c, - 0x5b, 0x14, 0x23, 0x32, 0x34, 0xdd, 0x83, 0xd5, 0xfb, 0x16, 0x5f, 0x43, 0x3f, 0x38, 0x99, 0x70, - 0x78, 0x0f, 0xaa, 0x5c, 0x18, 0x5f, 0x58, 0xd7, 0xc7, 0xae, 0x39, 0x24, 0x91, 0xad, 0xe2, 0x36, - 0x0f, 0x74, 0x86, 0x07, 0x81, 0x56, 0x16, 0x74, 0xf1, 0xad, 0xff, 0xbe, 0x2c, 0x35, 0xdd, 0xa1, - 0x34, 0xf8, 0xf2, 0x21, 0x77, 0x31, 0x08, 0xa8, 0x4c, 0x82, 0x80, 0x9c, 0xca, 0x5f, 0x04, 0x04, - 0xbc, 0xa2, 0x83, 0x4c, 0x0f, 0x61, 0x71, 0x87, 0x52, 0xae, 0x08, 0xba, 0x0e, 0x55, 0x4c, 0xa9, - 0x34, 0x78, 0x2e, 0x67, 0xab, 0x21, 0xfc, 0xbf, 0x52, 0x49, 0x0c, 0x6d, 0xdd, 0x84, 0x66, 0x4c, - 0x7a, 0x99, 0xd8, 0x66, 0x5a, 0xec, 0x16, 0x80, 0x44, 0xb9, 0x77, 0xdd, 0xbe, 0xc7, 0xb7, 0x94, - 0x3b, 0xbb, 0x9a, 0x2a, 0xbe, 0xf5, 0x5b, 0xd1, 0x08, 0xa1, 0xdb, 0xdb, 0x50, 0xb3, 0x18, 0x71, - 0x22, 0xe5, 0x36, 0xd2, 0xca, 0x25, 0x8c, 0x0c, 0x39, 0x48, 0xff, 0x4b, 0x03, 0xce, 0xf3, 0x1d, - 0x7b, 0x24, 0xc2, 0x64, 0x87, 0xd2, 0x8f, 0x09, 0xc3, 0x96, 0x1d, 0x7c, 0x27, 0x24, 0xfe, 0xf8, - 0x35, 0x3b, 0xc6, 0x00, 0xea, 0x32, 0xca, 0x54, 0x46, 0x7c, 0xe5, 0x05, 0x8f, 0x62, 0x9f, 0x54, - 0x39, 0x95, 0xd7, 0x53, 0xe5, 0x14, 0x55, 0x1d, 0xd5, 0x13, 0xaa, 0x3a, 0xa6, 0x17, 0x9e, 0xa9, - 0x72, 0xb6, 0x9e, 0x2d, 0x67, 0x0b, 0xc0, 0xfc, 0xe2, 0x71, 0xc1, 0x7c, 0xa3, 0x10, 0xcc, 0x3b, - 0x85, 0x71, 0xdc, 0x14, 0xe6, 0xfe, 0x56, 0xda, 0x03, 0xa7, 0xfa, 0xda, 0x3c, 0xb0, 0x1e, 0x5e, - 0x2b, 0xac, 0xff, 0x34, 0x03, 0xd3, 0x65, 0xa1, 0xfc, 0xee, 0xf1, 0xd6, 0x34, 0x03, 0xb0, 0x7f, - 0xe5, 0xe0, 0xf5, 0xcf, 0x05, 0xaa, 0xa2, 0x5e, 0x62, 0x83, 0xf8, 0x40, 0xe7, 0xe7, 0x10, 0x3f, - 0x5a, 0x55, 0xd2, 0xe2, 0xdf, 0xe8, 0x1a, 0x54, 0xb9, 0x91, 0x15, 0xec, 0x3d, 0x97, 0xb6, 0x27, - 0xdf, 0x89, 0x1d, 0x4a, 0x1f, 0x51, 0x62, 0x1a, 0x62, 0x10, 0xba, 0x05, 0xcd, 0xd8, 0xf1, 0x55, - 0x64, 0x5d, 0x48, 0xcf, 0x88, 0xe3, 0x24, 0x9a, 0x96, 0x0c, 0xe7, 0x73, 0x7b, 0x96, 0x4f, 0x4c, - 0x01, 0x0a, 0x6b, 0x93, 0x73, 0x3f, 0x8e, 0x3a, 0xe3, 0xb9, 0xf1, 0x70, 0x74, 0x1d, 0xea, 0xf2, - 0x66, 0x41, 0x44, 0xd0, 0xd2, 0xf6, 0xf9, 0xc9, 0x64, 0x1a, 0xcd, 0x52, 0x03, 0xf5, 0x3f, 0x95, - 0xe0, 0xcd, 0xc4, 0x21, 0xa2, 0x68, 0x8a, 0x70, 0xf9, 0x97, 0x7f, 0xe2, 0x5e, 0x86, 0x15, 0x51, - 0x08, 0x24, 0x17, 0x0c, 0xf2, 0xae, 0x2b, 0x47, 0xd5, 0x7f, 0x57, 0x82, 0x4b, 0x93, 0xeb, 0xd8, - 0x1d, 0x62, 0x9f, 0xc5, 0xdb, 0x7b, 0x12, 0x6b, 0x89, 0x0e, 0xbc, 0x72, 0x72, 0xe0, 0x65, 0xd6, - 0x57, 0xc9, 0xae, 0x4f, 0xff, 0x43, 0x19, 0x96, 0x52, 0x0e, 0x54, 0x74, 0x60, 0x72, 0xc0, 0x27, - 0xfc, 0x56, 0x94, 0x7e, 0xe2, 0x50, 0x68, 0x1a, 0x29, 0x0a, 0x1a, 0x01, 0x50, 0xec, 0x63, 0x87, - 0x30, 0xe2, 0xf3, 0x4c, 0xce, 0x23, 0xfe, 0xde, 0xfc, 0xd9, 0xe5, 0x30, 0xe2, 0x69, 0xa4, 0xd8, - 0x73, 0xc4, 0x2a, 0x44, 0x07, 0x2a, 0x7f, 0xab, 0x16, 0xfa, 0x1c, 0x56, 0xfa, 0x96, 0x4d, 0x0e, - 0x13, 0x45, 0xea, 0x42, 0x91, 0x87, 0xf3, 0x2b, 0x72, 0x27, 0xcd, 0xd7, 0xc8, 0x89, 0xd1, 0xaf, - 0xc2, 0x5a, 0x3e, 0x9e, 0xb8, 0x92, 0x96, 0x83, 0x07, 0xb1, 0xb5, 0x54, 0x4b, 0x47, 0xb0, 0x96, - 0x8f, 0x1f, 0xfd, 0x9f, 0x65, 0x38, 0x1b, 0xb3, 0xdb, 0x71, 0x5d, 0x2f, 0x74, 0x4d, 0x71, 0x59, - 0x57, 0xb8, 0x17, 0x67, 0xa0, 0xc6, 0x2c, 0x66, 0xc7, 0xc0, 0x47, 0x34, 0xf8, 0xd9, 0xc5, 0x3c, - 0xcf, 0x66, 0x16, 0x55, 0x1b, 0x1c, 0x35, 0xe5, 0xde, 0x3f, 0x0b, 0x2d, 0x9f, 0xf4, 0x44, 0x26, - 0x68, 0x18, 0x71, 0x9b, 0xf7, 0x71, 0x54, 0x23, 0x60, 0xbc, 0x34, 0x66, 0xdc, 0x16, 0x7e, 0xef, - 0xd9, 0x36, 0x31, 0xb9, 0x39, 0x52, 0x40, 0x3f, 0x47, 0x15, 0x05, 0x04, 0xf3, 0x2d, 0x77, 0xa0, - 0x60, 0xbe, 0x6a, 0x71, 0x3d, 0xb1, 0xef, 0xe3, 0xb1, 0xd6, 0x10, 0x06, 0x90, 0x0d, 0xf4, 0x01, - 0x54, 0x1c, 0x4c, 0xd5, 0x41, 0x77, 0x35, 0x93, 0x1d, 0x8a, 0x2c, 0xd0, 0x3e, 0xc0, 0x54, 0x9e, - 0x04, 0x7c, 0x5a, 0xeb, 0x3d, 0x68, 0x44, 0x84, 0x2f, 0x04, 0x09, 0x3f, 0x83, 0x53, 0x99, 0xe4, - 0x83, 0x9e, 0xc0, 0x46, 0xe2, 0x51, 0x69, 0x81, 0x0a, 0x04, 0xbe, 0xf9, 0x52, 0xcd, 0x8c, 0x29, - 0x0c, 0xf4, 0x67, 0xb0, 0xce, 0x5d, 0x46, 0x04, 0xfe, 0x09, 0x95, 0x36, 0xef, 0x43, 0x33, 0x16, - 0x59, 0xe8, 0x33, 0x2d, 0x68, 0x1c, 0x45, 0x97, 0xa8, 0xb2, 0xb6, 0x89, 0xdb, 0xfa, 0x0e, 0xa0, - 0xb4, 0xbe, 0xea, 0x04, 0xba, 0x96, 0x05, 0xc5, 0x67, 0xf3, 0xc7, 0x8d, 0x18, 0x1e, 0x61, 0xe2, - 0x7f, 0x94, 0x61, 0x75, 0xcf, 0x12, 0xf7, 0x20, 0x27, 0x94, 0xe4, 0xae, 0xc2, 0x5a, 0x10, 0x76, - 0x1d, 0xaf, 0x17, 0xda, 0x44, 0x81, 0x02, 0x75, 0xd2, 0x4f, 0xd0, 0x67, 0x25, 0x3f, 0x6e, 0x2c, - 0x8a, 0xd9, 0x50, 0x55, 0xb8, 0xe2, 0x1b, 0x7d, 0x00, 0xe7, 0x1f, 0x90, 0xcf, 0xd5, 0x7a, 0xf6, - 0x6c, 0xaf, 0xdb, 0xb5, 0xdc, 0x41, 0x24, 0xa4, 0x26, 0x84, 0x4c, 0x1f, 0x50, 0x04, 0x15, 0xeb, - 0xc5, 0x50, 0x31, 0xae, 0x92, 0x77, 0x3d, 0xc7, 0xb1, 0x98, 0x42, 0x94, 0x19, 0x9a, 0xfe, 0xb3, - 0x12, 0xac, 0x25, 0x96, 0x55, 0x7b, 0x73, 0x53, 0xc6, 0x90, 0xdc, 0x99, 0x4b, 0xe9, 0x9d, 0xc9, - 0x0f, 0xfd, 0xef, 0xc3, 0x67, 0x39, 0x1d, 0x3e, 0xbf, 0x2c, 0xc3, 0xd9, 0x3d, 0x8b, 0x45, 0x89, - 0xcb, 0xfa, 0x7f, 0xdb, 0xe5, 0x82, 0x3d, 0xa9, 0x1e, 0x6f, 0x4f, 0x6a, 0x05, 0x7b, 0xd2, 0x86, - 0x8d, 0xbc, 0x31, 0xd4, 0xc6, 0x9c, 0x81, 0x1a, 0xf7, 0xa0, 0xe8, 0x5e, 0x41, 0x36, 0xf4, 0xdf, - 0xd6, 0xe1, 0xe2, 0xa7, 0xb4, 0x87, 0x59, 0x7c, 0x2f, 0x74, 0xc7, 0xf3, 0x0f, 0x79, 0xd7, 0xc9, - 0x58, 0x31, 0xf7, 0x16, 0x57, 0x9e, 0xf9, 0x16, 0x57, 0x99, 0xf1, 0x16, 0x57, 0x3d, 0xd6, 0x5b, - 0x5c, 0xed, 0xc4, 0xde, 0xe2, 0x26, 0x6b, 0xad, 0x7a, 0x61, 0xad, 0xf5, 0x24, 0x53, 0x8f, 0x2c, - 0x8a, 0xb0, 0xf9, 0x66, 0x3a, 0x6c, 0x66, 0xee, 0xce, 0xcc, 0x47, 0x84, 0xdc, 0x13, 0x56, 0xe3, - 0xa5, 0x4f, 0x58, 0xcd, 0xc9, 0x27, 0xac, 0xe2, 0x57, 0x10, 0x98, 0xfa, 0x0a, 0x72, 0x19, 0x56, - 0x82, 0xb1, 0x6b, 0x92, 0x5e, 0x7c, 0x5b, 0xb8, 0x24, 0x97, 0x9d, 0xa5, 0x66, 0x22, 0x62, 0x39, - 0x17, 0x11, 0xb1, 0xa7, 0x9e, 0x4a, 0x79, 0xea, 0xff, 0x4e, 0x69, 0xb4, 0x05, 0x9b, 0xd3, 0xf6, - 0x44, 0x86, 0xda, 0xf6, 0x1f, 0x01, 0xd6, 0x13, 0xb4, 0xcd, 0xff, 0x5a, 0x26, 0x41, 0x0f, 0x61, - 0x6d, 0x4f, 0x3d, 0xa7, 0x47, 0x97, 0xa4, 0x68, 0xd6, 0xbb, 0x44, 0xeb, 0x42, 0x71, 0xa7, 0x14, - 0xa2, 0x2f, 0x20, 0x13, 0xce, 0xe7, 0x19, 0x26, 0x4f, 0x20, 0x5f, 0x9f, 0xc1, 0x39, 0x1e, 0xf5, - 0x32, 0x11, 0x57, 0x4a, 0xe8, 0x09, 0xac, 0x64, 0x2f, 0xea, 0x51, 0x06, 0x7e, 0x14, 0xbe, 0x1d, - 0xb4, 0xf4, 0x59, 0x43, 0x62, 0xfd, 0x9f, 0xf2, 0x0d, 0xcd, 0xdc, 0x49, 0x23, 0x3d, 0x5b, 0x89, - 0x17, 0xdd, 0xea, 0xb7, 0xbe, 0x36, 0x73, 0x4c, 0xcc, 0xfd, 0x7d, 0x68, 0x44, 0x77, 0xb8, 0x59, - 0x33, 0xe7, 0x6e, 0x76, 0x5b, 0x6b, 0x59, 0x7e, 0xfd, 0x40, 0x5f, 0x40, 0x1f, 0xca, 0xc9, 0x3b, - 0x94, 0x16, 0x4c, 0x4e, 0xdd, 0x5c, 0xb6, 0x4e, 0x17, 0xdc, 0x16, 0xea, 0x0b, 0xe8, 0xdb, 0xb0, - 0xc4, 0xbf, 0x0e, 0xd5, 0x43, 0xf6, 0x46, 0x5b, 0xfe, 0x6e, 0xa2, 0x1d, 0xfd, 0x6e, 0xa2, 0x7d, - 0xdb, 0xa1, 0x6c, 0xdc, 0x2a, 0xb8, 0xce, 0x53, 0x0c, 0x9e, 0xc2, 0xa9, 0x3d, 0xc2, 0x92, 0xea, - 0x1b, 0x5d, 0x3a, 0xd6, 0x1d, 0x45, 0x4b, 0xcf, 0x0f, 0x9b, 0x2c, 0xe0, 0xf5, 0x05, 0xf4, 0xab, - 0x12, 0x9c, 0xde, 0x23, 0x2c, 0x5f, 0xcf, 0xa2, 0x77, 0x8a, 0x85, 0x4c, 0xa9, 0x7b, 0x5b, 0x0f, - 0xe6, 0x8d, 0xae, 0x2c, 0x5b, 0x7d, 0x01, 0xfd, 0xba, 0x04, 0xe7, 0x52, 0x8a, 0xa5, 0x0b, 0x54, - 0x74, 0x7d, 0xb6, 0x72, 0x05, 0xc5, 0x6c, 0xeb, 0x93, 0x39, 0x7f, 0x9f, 0x90, 0x62, 0xa9, 0x2f, - 0xa0, 0x43, 0xb1, 0x27, 0x09, 0x1e, 0x45, 0x17, 0x0b, 0x81, 0x67, 0x2c, 0x7d, 0x73, 0x5a, 0x77, - 0xbc, 0x0f, 0x9f, 0xc0, 0xd2, 0x1e, 0x61, 0x11, 0x30, 0xca, 0x7a, 0x5a, 0x0e, 0xb3, 0x66, 0x43, - 0x35, 0x8f, 0xa5, 0x84, 0xc7, 0xac, 0x4b, 0x5e, 0xa9, 0xc3, 0x3f, 0x1b, 0xab, 0x85, 0x28, 0x29, - 0xeb, 0x31, 0xc5, 0xd8, 0x41, 0x5f, 0x40, 0xcf, 0x60, 0xa3, 0x38, 0xe9, 0xa1, 0xb7, 0x8e, 0x7d, - 0x58, 0xb5, 0xae, 0x1e, 0x67, 0x68, 0x24, 0xf2, 0xa3, 0x9d, 0xbf, 0xbe, 0xd8, 0x2c, 0xfd, 0xed, - 0xc5, 0x66, 0xe9, 0x5f, 0x2f, 0x36, 0x4b, 0xdf, 0xbf, 0xf1, 0x92, 0xdf, 0x31, 0xa5, 0x7e, 0x1a, - 0x85, 0xa9, 0x65, 0xda, 0x16, 0x71, 0x59, 0xb7, 0x2e, 0xe2, 0xed, 0xc6, 0x7f, 0x02, 0x00, 0x00, - 0xff, 0xff, 0xb7, 0x8d, 0xc3, 0x0e, 0x39, 0x25, 0x00, 0x00, + // 2352 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x1a, 0x4d, 0x73, 0x1c, 0x47, + 0x55, 0xfb, 0xa9, 0xdd, 0x27, 0xeb, 0xab, 0x6d, 0xcb, 0xe3, 0x8d, 0x2d, 0x94, 0x01, 0xbb, 0x1c, + 0x3b, 0x59, 0x95, 0xe5, 0x4a, 0x0c, 0x4e, 0x08, 0xa5, 0x28, 0xb6, 0xe4, 0xd8, 0xb2, 0xc5, 0xd8, + 0x09, 0x65, 0x30, 0x50, 0xbd, 0xb3, 0xad, 0xd9, 0x89, 0xe6, 0xa3, 0x3d, 0xd3, 0xa3, 0xb0, 0xae, + 0xe2, 0x04, 0xc5, 0x85, 0x3b, 0x07, 0xae, 0xfc, 0x05, 0x28, 0x8e, 0x1c, 0x28, 0x0a, 0x8e, 0x14, + 0x17, 0xaa, 0xb8, 0x40, 0xf9, 0x97, 0x50, 0xfd, 0x31, 0x9f, 0x3b, 0xbb, 0x52, 0x58, 0x59, 0x01, + 0x2e, 0xd2, 0xf4, 0xeb, 0xd7, 0xef, 0xbd, 0x7e, 0x5f, 0xfd, 0x5e, 0xf7, 0xc2, 0xd5, 0x80, 0x50, + 0x3f, 0x24, 0xc1, 0x21, 0x09, 0xd6, 0xc5, 0xa7, 0xcd, 0xfc, 0x60, 0x98, 0xf9, 0xec, 0xd2, 0xc0, + 0x67, 0x3e, 0x82, 0x14, 0xd2, 0x79, 0x68, 0xd9, 0x6c, 0x10, 0xf5, 0xba, 0xa6, 0xef, 0xae, 0xe3, + 0xc0, 0xf2, 0x69, 0xe0, 0x7f, 0x2e, 0x3e, 0xde, 0x31, 0xfb, 0xeb, 0x87, 0x1b, 0xeb, 0xf4, 0xc0, + 0x5a, 0xc7, 0xd4, 0x0e, 0xd7, 0x31, 0xa5, 0x8e, 0x6d, 0x62, 0x66, 0xfb, 0xde, 0xfa, 0xe1, 0x4d, + 0xec, 0xd0, 0x01, 0xbe, 0xb9, 0x6e, 0x11, 0x8f, 0x04, 0x98, 0x91, 0xbe, 0xa4, 0xdc, 0x79, 0xc3, + 0xf2, 0x7d, 0xcb, 0x21, 0xeb, 0x62, 0xd4, 0x8b, 0xf6, 0xd7, 0x89, 0x4b, 0x99, 0x62, 0xab, 0xff, + 0x76, 0x1e, 0x16, 0x77, 0xb1, 0x67, 0xef, 0x93, 0x90, 0x19, 0xe4, 0x45, 0x44, 0x42, 0x86, 0x9e, + 0x43, 0x9d, 0x0b, 0xa3, 0x55, 0xd6, 0x2a, 0xd7, 0xe6, 0x36, 0x76, 0xba, 0xa9, 0x34, 0xdd, 0x58, + 0x1a, 0xf1, 0xf1, 0x63, 0xb3, 0xdf, 0x3d, 0xdc, 0xe8, 0xd2, 0x03, 0xab, 0xcb, 0xa5, 0xe9, 0x66, + 0xa4, 0xe9, 0xc6, 0xd2, 0x74, 0x8d, 0x64, 0x5b, 0x86, 0xa0, 0x8a, 0x3a, 0xd0, 0x0a, 0xc8, 0xa1, + 0x1d, 0xda, 0xbe, 0xa7, 0x55, 0xd7, 0x2a, 0xd7, 0xda, 0x46, 0x32, 0x46, 0x1a, 0xcc, 0x7a, 0xfe, + 0x16, 0x36, 0x07, 0x44, 0xab, 0xad, 0x55, 0xae, 0xb5, 0x8c, 0x78, 0x88, 0xd6, 0x60, 0x0e, 0x53, + 0xfa, 0x10, 0xf7, 0x88, 0xf3, 0x80, 0x0c, 0xb5, 0xba, 0x58, 0x98, 0x05, 0xf1, 0xb5, 0x98, 0xd2, + 0x47, 0xd8, 0x25, 0x5a, 0x43, 0xcc, 0xc6, 0x43, 0x74, 0x09, 0xda, 0x1e, 0x76, 0x49, 0x48, 0xb1, + 0x49, 0xb4, 0x96, 0x98, 0x4b, 0x01, 0xe8, 0xa7, 0xb0, 0x9c, 0x11, 0xfc, 0x89, 0x1f, 0x05, 0x26, + 0xd1, 0x40, 0x6c, 0xfd, 0xf1, 0x74, 0x5b, 0xdf, 0x2c, 0x92, 0x35, 0x46, 0x39, 0xa1, 0x1f, 0x41, + 0x43, 0x58, 0x5e, 0x9b, 0x5b, 0xab, 0x9d, 0xa8, 0xb6, 0x25, 0x59, 0xe4, 0xc1, 0x2c, 0x75, 0x22, + 0xcb, 0xf6, 0x42, 0xed, 0x8c, 0xe0, 0xf0, 0x74, 0x3a, 0x0e, 0x5b, 0xbe, 0xb7, 0x6f, 0x5b, 0xbb, + 0xd8, 0xc3, 0x16, 0x71, 0x89, 0xc7, 0xf6, 0x04, 0x71, 0x23, 0x66, 0x82, 0x5e, 0xc2, 0xd2, 0x41, + 0x14, 0x32, 0xdf, 0xb5, 0x5f, 0x92, 0xc7, 0x94, 0xaf, 0x0d, 0xb5, 0x79, 0xa1, 0xcd, 0x47, 0xd3, + 0x31, 0x7e, 0x50, 0xa0, 0x6a, 0x8c, 0xf0, 0xe1, 0x4e, 0x72, 0x10, 0xf5, 0xc8, 0x67, 0x24, 0x10, + 0xde, 0xb5, 0x20, 0x9d, 0x24, 0x03, 0x92, 0x6e, 0x64, 0xab, 0x51, 0xa8, 0x2d, 0xae, 0xd5, 0xa4, + 0x1b, 0x25, 0x20, 0x74, 0x0d, 0x16, 0x0f, 0x49, 0x60, 0xef, 0x0f, 0x9f, 0xd8, 0x96, 0x87, 0x59, + 0x14, 0x10, 0x6d, 0x49, 0xb8, 0x62, 0x11, 0x8c, 0x5c, 0x98, 0x1f, 0x10, 0xc7, 0xe5, 0x2a, 0xdf, + 0x0a, 0x48, 0x3f, 0xd4, 0x96, 0x85, 0x7e, 0xb7, 0xa7, 0xb7, 0xa0, 0x20, 0x67, 0xe4, 0xa9, 0x73, + 0xc1, 0x3c, 0xdf, 0x50, 0x91, 0x22, 0x63, 0x04, 0x49, 0xc1, 0x0a, 0x60, 0x74, 0x15, 0x16, 0x58, + 0x80, 0xcd, 0x03, 0xdb, 0xb3, 0x76, 0x09, 0x1b, 0xf8, 0x7d, 0xed, 0xac, 0xd0, 0x44, 0x01, 0x8a, + 0x4c, 0x40, 0xc4, 0xc3, 0x3d, 0x87, 0xf4, 0xa5, 0x2f, 0x3e, 0x1d, 0x52, 0x12, 0x6a, 0xe7, 0xc4, + 0x2e, 0x6e, 0x75, 0x33, 0x19, 0xaa, 0x90, 0x20, 0xba, 0x77, 0x47, 0x56, 0xdd, 0xf5, 0x58, 0x30, + 0x34, 0x4a, 0xc8, 0xa1, 0x03, 0x98, 0xe3, 0xfb, 0x88, 0x5d, 0xe1, 0xbc, 0x70, 0x85, 0xfb, 0xd3, + 0xe9, 0x68, 0x27, 0x25, 0x68, 0x64, 0xa9, 0xa3, 0x2e, 0xa0, 0x01, 0x0e, 0x77, 0x23, 0x87, 0xd9, + 0xd4, 0x21, 0x52, 0x8c, 0x50, 0x5b, 0x11, 0x6a, 0x2a, 0x99, 0x41, 0x0f, 0x00, 0x02, 0xb2, 0x1f, + 0xe3, 0x5d, 0x10, 0x3b, 0xbf, 0x31, 0x69, 0xe7, 0x46, 0x82, 0x2d, 0x77, 0x9c, 0x59, 0xce, 0x99, + 0xf3, 0x6d, 0x10, 0x93, 0xa9, 0x68, 0x17, 0x61, 0xad, 0x09, 0x17, 0x2b, 0x99, 0xe1, 0xbe, 0xa8, + 0xa0, 0x22, 0x69, 0x5d, 0x94, 0xde, 0x9a, 0x01, 0xa1, 0x1d, 0xf8, 0xda, 0xa6, 0xe7, 0xf9, 0x4c, + 0x6c, 0x3f, 0x16, 0x65, 0x5b, 0xa5, 0xf7, 0x3d, 0xcc, 0x06, 0xa1, 0xd6, 0x11, 0xab, 0x8e, 0x42, + 0xeb, 0xdc, 0x85, 0x0b, 0x63, 0x8c, 0x86, 0x96, 0xa0, 0x76, 0x40, 0x86, 0x22, 0xd9, 0xb7, 0x0d, + 0xfe, 0x89, 0xce, 0x41, 0xe3, 0x10, 0x3b, 0x11, 0x11, 0xe9, 0xb9, 0x65, 0xc8, 0xc1, 0x9d, 0xea, + 0x37, 0x2b, 0x9d, 0x5f, 0x54, 0x60, 0xb1, 0xa0, 0x82, 0x92, 0xf5, 0x3f, 0xcc, 0xae, 0x3f, 0x81, + 0x80, 0xd8, 0x7f, 0x8a, 0x03, 0x8b, 0xb0, 0x8c, 0x20, 0xfa, 0xdf, 0x2a, 0xa0, 0x15, 0x6c, 0xf3, + 0x3d, 0x9b, 0x0d, 0xee, 0xd9, 0x0e, 0x09, 0xd1, 0x6d, 0x98, 0x0d, 0x24, 0x4c, 0x1d, 0x61, 0x6f, + 0x4c, 0x30, 0xe9, 0xce, 0x8c, 0x11, 0x63, 0xa3, 0x0f, 0xa1, 0xe5, 0x12, 0x86, 0xfb, 0x98, 0x61, + 0x25, 0xfb, 0x5a, 0xd9, 0x4a, 0xce, 0x65, 0x57, 0xe1, 0xed, 0xcc, 0x18, 0xc9, 0x1a, 0xf4, 0x2e, + 0x34, 0xcc, 0x41, 0xe4, 0x1d, 0x88, 0xc3, 0x6b, 0x6e, 0xe3, 0xf2, 0xb8, 0xc5, 0x5b, 0x1c, 0x69, + 0x67, 0xc6, 0x90, 0xd8, 0x1f, 0x35, 0xa1, 0x4e, 0x71, 0xc0, 0xf4, 0x7b, 0x70, 0xae, 0x8c, 0x05, + 0x3f, 0x31, 0xcd, 0x01, 0x31, 0x0f, 0xc2, 0xc8, 0x55, 0x6a, 0x4e, 0xc6, 0x08, 0x41, 0x3d, 0xb4, + 0x5f, 0x4a, 0x55, 0xd7, 0x0c, 0xf1, 0xad, 0xbf, 0x05, 0xcb, 0x23, 0xdc, 0xb8, 0x51, 0xa5, 0x6c, + 0x9c, 0xc2, 0x19, 0xc5, 0x5a, 0x8f, 0xe0, 0xfc, 0x53, 0xa1, 0x8b, 0xe4, 0xd8, 0x38, 0x8d, 0x1a, + 0x40, 0xdf, 0x81, 0x95, 0x22, 0xdb, 0x90, 0xfa, 0x5e, 0x48, 0x78, 0x10, 0x89, 0x3c, 0x6b, 0x93, + 0x7e, 0x3a, 0x2b, 0xa4, 0x68, 0x19, 0x25, 0x33, 0xfa, 0x6f, 0xaa, 0xb0, 0x62, 0x90, 0xd0, 0x77, + 0x0e, 0x49, 0x9c, 0x04, 0x4f, 0xa7, 0x8c, 0xf9, 0x01, 0xd4, 0x30, 0xa5, 0xca, 0x4d, 0xee, 0x9f, + 0x58, 0xa1, 0x60, 0x70, 0xaa, 0xe8, 0x6d, 0x58, 0xc6, 0x6e, 0xcf, 0xb6, 0x22, 0x3f, 0x0a, 0xe3, + 0x6d, 0x09, 0xa7, 0x6a, 0x1b, 0xa3, 0x13, 0x3c, 0x91, 0x84, 0x22, 0x22, 0xef, 0x7b, 0x7d, 0xf2, + 0x13, 0x51, 0x1b, 0xd5, 0x8c, 0x2c, 0x48, 0x37, 0xe1, 0xc2, 0x88, 0x92, 0x94, 0xc2, 0xb3, 0xe5, + 0x58, 0xa5, 0x50, 0x8e, 0x95, 0x8a, 0x51, 0x1d, 0x23, 0x86, 0xfe, 0xaa, 0x02, 0x4b, 0x69, 0x70, + 0x29, 0xf2, 0x97, 0xa0, 0xed, 0x2a, 0x58, 0xa8, 0x55, 0x44, 0x2e, 0x4c, 0x01, 0xf9, 0xca, 0xac, + 0x5a, 0xac, 0xcc, 0x56, 0xa0, 0x29, 0x0b, 0x67, 0xb5, 0x75, 0x35, 0xca, 0x89, 0x5c, 0x2f, 0x88, + 0xbc, 0x0a, 0x10, 0x26, 0x19, 0x4e, 0x6b, 0x8a, 0xd9, 0x0c, 0x04, 0xe9, 0x70, 0x46, 0x9e, 0xe3, + 0x06, 0x09, 0x23, 0x87, 0x69, 0xb3, 0x02, 0x23, 0x07, 0x13, 0xf1, 0xe6, 0xbb, 0x2e, 0xf6, 0xfa, + 0xa1, 0xd6, 0x12, 0x22, 0x27, 0x63, 0xdd, 0x87, 0xc5, 0x87, 0x36, 0xdf, 0xdf, 0x7e, 0x78, 0x3a, + 0xa1, 0xf2, 0x1e, 0xd4, 0x39, 0x33, 0x2e, 0x54, 0x2f, 0xc0, 0x9e, 0x39, 0x20, 0xb1, 0x1e, 0x93, + 0x31, 0x4f, 0x02, 0x0c, 0x5b, 0xa1, 0x56, 0x15, 0x70, 0xf1, 0xad, 0xff, 0xbe, 0x2a, 0x25, 0xdd, + 0xa4, 0x34, 0xfc, 0xea, 0x0b, 0xfb, 0xf2, 0x52, 0xa3, 0x36, 0x5a, 0x6a, 0x14, 0x44, 0xfe, 0x32, + 0xa5, 0xc6, 0x09, 0x1d, 0x72, 0x7a, 0x04, 0xb3, 0x9b, 0x94, 0x72, 0x41, 0xd0, 0x4d, 0xa8, 0x63, + 0x4a, 0xa5, 0xc2, 0x0b, 0xf9, 0x5c, 0xa1, 0xf0, 0xff, 0x4a, 0x24, 0x81, 0xda, 0xb9, 0x0d, 0xed, + 0x04, 0x74, 0x14, 0xdb, 0x76, 0x96, 0xed, 0x1a, 0x80, 0xac, 0xa5, 0xef, 0x7b, 0xfb, 0x3e, 0x37, + 0x29, 0x0f, 0x04, 0xb5, 0x54, 0x7c, 0xeb, 0x77, 0x62, 0x0c, 0x21, 0xdb, 0xdb, 0xd0, 0xb0, 0x19, + 0x71, 0x63, 0xe1, 0x56, 0xb2, 0xc2, 0xa5, 0x84, 0x0c, 0x89, 0xa4, 0xff, 0xb9, 0x05, 0x17, 0xb9, + 0xc5, 0x9e, 0x88, 0x10, 0xda, 0xa4, 0xf4, 0x63, 0xc2, 0xb0, 0xed, 0x84, 0xdf, 0x8d, 0x48, 0x30, + 0x7c, 0xcd, 0x8e, 0x61, 0x41, 0x53, 0x46, 0xa0, 0xca, 0x96, 0x27, 0xde, 0x56, 0x29, 0xf2, 0x69, + 0x2f, 0x55, 0x7b, 0x3d, 0xbd, 0x54, 0x59, 0x6f, 0x53, 0x3f, 0xa5, 0xde, 0x66, 0x7c, 0x7b, 0x9b, + 0x69, 0x9a, 0x9b, 0xf9, 0xa6, 0xb9, 0xa4, 0x65, 0x98, 0x3d, 0x6e, 0xcb, 0xd0, 0x2a, 0x6d, 0x19, + 0xdc, 0xd2, 0x38, 0x6e, 0x0b, 0x75, 0x7f, 0x3b, 0xeb, 0x81, 0x63, 0x7d, 0x6d, 0x9a, 0xe6, 0x01, + 0x5e, 0x6b, 0xf3, 0xf0, 0x69, 0xae, 0x19, 0x90, 0xed, 0xf8, 0xbb, 0xc7, 0xdb, 0xd3, 0x84, 0xb6, + 0xe0, 0xff, 0xae, 0xf4, 0xfe, 0xb9, 0xa8, 0xb8, 0xa8, 0x9f, 0xea, 0x20, 0x39, 0xec, 0xf9, 0x39, + 0xc4, 0x8f, 0x5d, 0x95, 0xb4, 0xf8, 0x37, 0xba, 0x01, 0x75, 0xae, 0x64, 0x55, 0x12, 0x5f, 0xc8, + 0xea, 0x93, 0x5b, 0x62, 0x93, 0xd2, 0x27, 0x94, 0x98, 0x86, 0x40, 0x42, 0x77, 0xa0, 0x9d, 0x38, + 0xbe, 0x8a, 0xac, 0x4b, 0xd9, 0x15, 0x49, 0x9c, 0xc4, 0xcb, 0x52, 0x74, 0xbe, 0xb6, 0x6f, 0x07, + 0xc4, 0x14, 0x05, 0x63, 0x63, 0x74, 0xed, 0xc7, 0xf1, 0x64, 0xb2, 0x36, 0x41, 0x47, 0x37, 0xa1, + 0x29, 0xef, 0x2f, 0x44, 0x04, 0xcd, 0x6d, 0x5c, 0x1c, 0x4d, 0xa6, 0xf1, 0x2a, 0x85, 0xa8, 0xff, + 0xa9, 0x02, 0x6f, 0xa6, 0x0e, 0x11, 0x47, 0x53, 0x5c, 0xb3, 0x7f, 0xf5, 0x27, 0xee, 0x55, 0x58, + 0x10, 0x4d, 0x42, 0x7a, 0x8d, 0x21, 0x6f, 0xd4, 0x0a, 0x50, 0xfd, 0x77, 0x15, 0xb8, 0x32, 0xba, + 0x8f, 0xad, 0x01, 0x0e, 0x58, 0x62, 0xde, 0xd3, 0xd8, 0x4b, 0x7c, 0xe0, 0x55, 0xd3, 0x03, 0x2f, + 0xb7, 0xbf, 0x5a, 0x7e, 0x7f, 0xfa, 0x1f, 0xaa, 0x30, 0x97, 0x71, 0xa0, 0xb2, 0x03, 0x93, 0x17, + 0x83, 0xc2, 0x6f, 0x45, 0x5b, 0x28, 0x0e, 0x85, 0xb6, 0x91, 0x81, 0xa0, 0x03, 0x00, 0x8a, 0x03, + 0xec, 0x12, 0x46, 0x02, 0x9e, 0xc9, 0x79, 0xc4, 0x3f, 0x98, 0x3e, 0xbb, 0xec, 0xc5, 0x34, 0x8d, + 0x0c, 0x79, 0x5e, 0xcd, 0x0a, 0xd6, 0xa1, 0xca, 0xdf, 0x6a, 0x84, 0xbe, 0x80, 0x85, 0x7d, 0xdb, + 0x21, 0x7b, 0xa9, 0x20, 0x4d, 0x21, 0xc8, 0xe3, 0xe9, 0x05, 0xb9, 0x97, 0xa5, 0x6b, 0x14, 0xd8, + 0xe8, 0xd7, 0x61, 0xa9, 0x18, 0x4f, 0x5c, 0x48, 0xdb, 0xc5, 0x56, 0xa2, 0x2d, 0x35, 0xd2, 0x11, + 0x2c, 0x15, 0xe3, 0x47, 0xff, 0x67, 0x15, 0xce, 0x27, 0xe4, 0x36, 0x3d, 0xcf, 0x8f, 0x3c, 0x53, + 0x5c, 0x09, 0x96, 0xda, 0xe2, 0x1c, 0x34, 0x98, 0xcd, 0x9c, 0xa4, 0xf0, 0x11, 0x03, 0x7e, 0x76, + 0x31, 0xdf, 0x77, 0x98, 0x4d, 0x95, 0x81, 0xe3, 0xa1, 0xb4, 0xfd, 0x8b, 0xc8, 0x0e, 0x48, 0x5f, + 0x64, 0x82, 0x96, 0x91, 0x8c, 0xf9, 0x1c, 0xaf, 0x6a, 0x44, 0x89, 0x2f, 0x95, 0x99, 0x8c, 0x85, + 0xdf, 0xfb, 0x8e, 0x43, 0x4c, 0xae, 0x8e, 0x4c, 0x13, 0x50, 0x80, 0x8a, 0xe6, 0x82, 0x05, 0xb6, + 0x67, 0xa9, 0x16, 0x40, 0x8d, 0xb8, 0x9c, 0x38, 0x08, 0xf0, 0x50, 0x55, 0xfe, 0x72, 0x80, 0x3e, + 0x80, 0x9a, 0x8b, 0xa9, 0x3a, 0xe8, 0xae, 0xe7, 0xb2, 0x43, 0x99, 0x06, 0xba, 0xbb, 0x98, 0xca, + 0x93, 0x80, 0x2f, 0xeb, 0xbc, 0x07, 0xad, 0x18, 0xf0, 0xa5, 0x4a, 0xc2, 0xcf, 0x61, 0x3e, 0x97, + 0x7c, 0xd0, 0x33, 0x58, 0x49, 0x3d, 0x2a, 0xcb, 0x50, 0x15, 0x81, 0x6f, 0x1e, 0x29, 0x99, 0x31, + 0x86, 0x80, 0xfe, 0x02, 0x96, 0xb9, 0xcb, 0x88, 0xc0, 0x3f, 0xa5, 0xd6, 0xe6, 0x7d, 0x68, 0x27, + 0x2c, 0x4b, 0x7d, 0xa6, 0x03, 0xad, 0xc3, 0xf8, 0xaa, 0x56, 0xf6, 0x36, 0xc9, 0x58, 0xdf, 0x04, + 0x94, 0x95, 0x57, 0x9d, 0x40, 0x37, 0xf2, 0x45, 0xf1, 0xf9, 0xe2, 0x71, 0x23, 0xd0, 0xe3, 0x9a, + 0xf8, 0xef, 0x55, 0x58, 0xdc, 0xb6, 0xc5, 0x1d, 0xc9, 0x29, 0x25, 0xb9, 0xeb, 0xb0, 0x14, 0x46, + 0x3d, 0xd7, 0xef, 0x47, 0x0e, 0x51, 0x45, 0x81, 0x3a, 0xe9, 0x47, 0xe0, 0x93, 0x92, 0x1f, 0x57, + 0x16, 0xc5, 0x6c, 0xa0, 0xba, 0x5f, 0xf1, 0x8d, 0x3e, 0x80, 0x8b, 0x8f, 0xc8, 0x17, 0x6a, 0x3f, + 0xdb, 0x8e, 0xdf, 0xeb, 0xd9, 0x9e, 0x15, 0x33, 0x69, 0x08, 0x26, 0xe3, 0x11, 0xca, 0x4a, 0xc5, + 0x66, 0x79, 0xa9, 0x98, 0x74, 0xd0, 0x5b, 0xbe, 0xeb, 0xda, 0x4c, 0x55, 0x94, 0x39, 0x98, 0xfe, + 0xb3, 0x0a, 0x2c, 0xa5, 0x9a, 0x55, 0xb6, 0xb9, 0x2d, 0x63, 0x48, 0x5a, 0xe6, 0x4a, 0xd6, 0x32, + 0x45, 0xd4, 0xff, 0x3c, 0x7c, 0xce, 0x64, 0xc3, 0xe7, 0x97, 0x55, 0x38, 0xbf, 0x6d, 0xb3, 0x38, + 0x71, 0xd9, 0xff, 0x6b, 0x56, 0x2e, 0xb1, 0x49, 0xfd, 0x78, 0x36, 0x69, 0x94, 0xd8, 0xa4, 0x0b, + 0x2b, 0x45, 0x65, 0x28, 0xc3, 0x9c, 0x83, 0x06, 0x15, 0x97, 0xc9, 0xf2, 0x5e, 0x41, 0x0e, 0xf4, + 0x7f, 0x34, 0xe1, 0xf2, 0xa7, 0xb4, 0x8f, 0x59, 0x72, 0x67, 0x74, 0xcf, 0x0f, 0xc4, 0x6d, 0xf2, + 0xe9, 0x68, 0xb1, 0xf0, 0xe2, 0x57, 0x9d, 0xf8, 0xe2, 0x57, 0x9b, 0xf0, 0xe2, 0x57, 0x3f, 0xd6, + 0x8b, 0x5f, 0xe3, 0xd4, 0x5e, 0xfc, 0x46, 0x7b, 0xad, 0x66, 0x69, 0xaf, 0xf5, 0x2c, 0xd7, 0x8f, + 0xcc, 0x8a, 0xb0, 0xf9, 0x56, 0x36, 0x6c, 0x26, 0x5a, 0x67, 0xe2, 0x53, 0x45, 0xe1, 0xa1, 0xac, + 0x75, 0xe4, 0x43, 0x59, 0x7b, 0xf4, 0xa1, 0xac, 0xfc, 0xad, 0x05, 0xc6, 0xbe, 0xb5, 0x5c, 0x85, + 0x85, 0x70, 0xe8, 0x99, 0xa4, 0x9f, 0xdc, 0x24, 0xce, 0xc9, 0x6d, 0xe7, 0xa1, 0xb9, 0x88, 0x38, + 0x53, 0x88, 0x88, 0xc4, 0x53, 0xe7, 0x33, 0x9e, 0x5a, 0x16, 0x27, 0x0b, 0xa5, 0x71, 0xf2, 0xdf, + 0xd3, 0x44, 0x7d, 0x06, 0xab, 0xe3, 0xac, 0xa7, 0x82, 0x52, 0x83, 0x59, 0x73, 0x80, 0x3d, 0x4b, + 0x5c, 0xf7, 0x89, 0xae, 0x5e, 0x0d, 0x27, 0x55, 0xfd, 0x1b, 0x7f, 0x04, 0x58, 0x4e, 0xab, 0x79, + 0xfe, 0xd7, 0x36, 0x09, 0x7a, 0x0c, 0x4b, 0xf1, 0x73, 0x50, 0x7c, 0x41, 0x8b, 0x26, 0xbd, 0x89, + 0x74, 0x2e, 0x95, 0x4f, 0x4a, 0xd1, 0xf4, 0x19, 0x64, 0xc2, 0xc5, 0x22, 0xc1, 0xf4, 0xf9, 0xe5, + 0x1b, 0x13, 0x28, 0x27, 0x58, 0x47, 0xb1, 0xb8, 0x56, 0x41, 0xcf, 0x60, 0x21, 0xff, 0x48, 0x80, + 0x72, 0xe5, 0x4d, 0xe9, 0xbb, 0x45, 0x47, 0x9f, 0x84, 0x92, 0xc8, 0xff, 0x9c, 0xbb, 0x41, 0xee, + 0x3e, 0x1c, 0xe9, 0xf9, 0x4e, 0xbf, 0xec, 0x45, 0xa1, 0xf3, 0xf5, 0x89, 0x38, 0x09, 0xf5, 0xf7, + 0xa1, 0x15, 0xdf, 0x11, 0xe7, 0xd5, 0x5c, 0xb8, 0x39, 0xee, 0x2c, 0xe5, 0xe9, 0xed, 0x87, 0xfa, + 0x0c, 0xfa, 0x50, 0x2e, 0xde, 0xa4, 0xb4, 0x64, 0x71, 0xe6, 0x66, 0xb4, 0x73, 0xb6, 0xe4, 0x36, + 0x52, 0x9f, 0x41, 0xdf, 0x81, 0x39, 0xfe, 0xb5, 0xa7, 0x9e, 0xe3, 0x57, 0xba, 0xf2, 0xd7, 0x1f, + 0xdd, 0xf8, 0xd7, 0x1f, 0xdd, 0xbb, 0x2e, 0x65, 0xc3, 0x4e, 0xc9, 0x75, 0xa1, 0x22, 0xf0, 0x1c, + 0xe6, 0xb7, 0x09, 0x4b, 0xbb, 0x7b, 0x74, 0xe5, 0x58, 0x77, 0x20, 0x1d, 0xbd, 0x88, 0x36, 0x7a, + 0x41, 0xa0, 0xcf, 0xa0, 0x5f, 0x55, 0xe0, 0xec, 0x36, 0x61, 0xc5, 0x7e, 0x19, 0xbd, 0x53, 0xce, + 0x64, 0x4c, 0x5f, 0xdd, 0x79, 0x34, 0x6d, 0x4c, 0xe6, 0xc9, 0xea, 0x33, 0xe8, 0xd7, 0x15, 0xb8, + 0x90, 0x11, 0x2c, 0xdb, 0x00, 0xa3, 0x9b, 0x93, 0x85, 0x2b, 0x69, 0x96, 0x3b, 0x9f, 0x4c, 0xf9, + 0x2b, 0x8b, 0x0c, 0x49, 0x7d, 0x06, 0xed, 0x09, 0x9b, 0xa4, 0xf5, 0x2e, 0xba, 0x5c, 0x5a, 0xd8, + 0x26, 0xdc, 0x57, 0xc7, 0x4d, 0x27, 0x76, 0xf8, 0x04, 0xe6, 0xb6, 0x09, 0x8b, 0x0b, 0xaf, 0xbc, + 0xa7, 0x15, 0x6a, 0xe2, 0x7c, 0xa8, 0x16, 0x6b, 0x35, 0xe1, 0x31, 0xcb, 0x92, 0x56, 0xa6, 0xb8, + 0xc8, 0xc7, 0x6a, 0x69, 0x15, 0x96, 0xf7, 0x98, 0xf2, 0xda, 0x44, 0x9f, 0x41, 0x2f, 0x60, 0xa5, + 0x3c, 0x55, 0xa2, 0xb7, 0x8e, 0x7d, 0x18, 0x76, 0xae, 0x1f, 0x07, 0x35, 0x66, 0xf9, 0xd1, 0xe6, + 0x5f, 0x5e, 0xad, 0x56, 0xfe, 0xfa, 0x6a, 0xb5, 0xf2, 0xaf, 0x57, 0xab, 0x95, 0xef, 0xdf, 0x3a, + 0xe2, 0xd7, 0x58, 0x99, 0x1f, 0x78, 0x61, 0x6a, 0x9b, 0x8e, 0x4d, 0x3c, 0xd6, 0x6b, 0x8a, 0x78, + 0xbb, 0xf5, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xed, 0x52, 0xaa, 0xcc, 0xff, 0x25, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3196,6 +3243,15 @@ func (m *ManifestRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.AnnotationManifestGeneratePaths) > 0 { + i -= len(m.AnnotationManifestGeneratePaths) + copy(dAtA[i:], m.AnnotationManifestGeneratePaths) + i = encodeVarintRepository(dAtA, i, uint64(len(m.AnnotationManifestGeneratePaths))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xd2 + } if len(m.ProjectName) > 0 { i -= len(m.ProjectName) copy(dAtA[i:], m.ProjectName) @@ -3840,6 +3896,15 @@ func (m *ManifestResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.Commands) > 0 { + for iNdEx := len(m.Commands) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Commands[iNdEx]) + copy(dAtA[i:], m.Commands[iNdEx]) + i = encodeVarintRepository(dAtA, i, uint64(len(m.Commands[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } if len(m.VerifyResult) > 0 { i -= len(m.VerifyResult) copy(dAtA[i:], m.VerifyResult) @@ -5211,6 +5276,16 @@ func (m *UpdateRevisionForPathsRequest) MarshalToSizedBuffer(dAtA []byte) (int, i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.NoRevisionCache { + i-- + if m.NoRevisionCache { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x70 + } if len(m.Paths) > 0 { for iNdEx := len(m.Paths) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Paths[iNdEx]) @@ -5365,6 +5440,23 @@ func (m *UpdateRevisionForPathsResponse) MarshalToSizedBuffer(dAtA []byte) (int, i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.Revision) > 0 { + i -= len(m.Revision) + copy(dAtA[i:], m.Revision) + i = encodeVarintRepository(dAtA, i, uint64(len(m.Revision))) + i-- + dAtA[i] = 0x12 + } + if m.Changes { + i-- + if m.Changes { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } @@ -5492,6 +5584,10 @@ func (m *ManifestRequest) Size() (n int) { if l > 0 { n += 2 + l + sovRepository(uint64(l)) } + l = len(m.AnnotationManifestGeneratePaths) + if l > 0 { + n += 2 + l + sovRepository(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -5694,6 +5790,12 @@ func (m *ManifestResponse) Size() (n int) { if l > 0 { n += 1 + l + sovRepository(uint64(l)) } + if len(m.Commands) > 0 { + for _, s := range m.Commands { + l = len(s) + n += 1 + l + sovRepository(uint64(l)) + } + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6342,6 +6444,9 @@ func (m *UpdateRevisionForPathsRequest) Size() (n int) { n += 1 + l + sovRepository(uint64(l)) } } + if m.NoRevisionCache { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6354,6 +6459,13 @@ func (m *UpdateRevisionForPathsResponse) Size() (n int) { } var l int _ = l + if m.Changes { + n += 2 + } + l = len(m.Revision) + if l > 0 { + n += 1 + l + sovRepository(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -7253,6 +7365,38 @@ func (m *ManifestRequest) Unmarshal(dAtA []byte) error { } m.ProjectName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 26: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AnnotationManifestGeneratePaths", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AnnotationManifestGeneratePaths = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) @@ -8286,6 +8430,38 @@ func (m *ManifestResponse) Unmarshal(dAtA []byte) error { } m.VerifyResult = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Commands", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 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.Commands = append(m.Commands, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) @@ -12537,6 +12713,26 @@ func (m *UpdateRevisionForPathsRequest) Unmarshal(dAtA []byte) error { } m.Paths = append(m.Paths, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 14: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NoRevisionCache", 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.NoRevisionCache = bool(v != 0) default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) @@ -12588,6 +12784,58 @@ func (m *UpdateRevisionForPathsResponse) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: UpdateRevisionForPathsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Changes", 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.Changes = bool(v != 0) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Revision", 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.Revision = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) diff --git a/reposerver/askpass/common.go b/reposerver/askpass/common.go index 8af7e79245fa3..c9757f5878956 100644 --- a/reposerver/askpass/common.go +++ b/reposerver/askpass/common.go @@ -6,8 +6,15 @@ import ( var SocketPath = "/tmp/reposerver-ask-pass.sock" +const ( + // ASKPASS_NONCE_ENV is the environment variable that is used to pass the nonce to the askpass script + ASKPASS_NONCE_ENV = "ARGOCD_GIT_ASKPASS_NONCE" + // AKSPASS_SOCKET_PATH_ENV is the environment variable that is used to pass the socket path to the askpass script + AKSPASS_SOCKET_PATH_ENV = "ARGOCD_ASK_PASS_SOCK" +) + func init() { - SocketPath = env.StringFromEnv("ARGOCD_ASK_PASS_SOCK", SocketPath) + SocketPath = env.StringFromEnv(AKSPASS_SOCKET_PATH_ENV, SocketPath) } type Creds struct { diff --git a/reposerver/askpass/server.go b/reposerver/askpass/server.go index c34e3c332890d..2eb9f89869776 100644 --- a/reposerver/askpass/server.go +++ b/reposerver/askpass/server.go @@ -2,6 +2,7 @@ package askpass import ( "context" + "fmt" "net" "os" "sync" @@ -22,14 +23,16 @@ type Server interface { } type server struct { - lock sync.Mutex - creds map[string]Creds + lock sync.Mutex + creds map[string]Creds + socketPath string } // NewServer returns a new server -func NewServer() *server { +func NewServer(socketPath string) *server { return &server{ - creds: make(map[string]Creds), + creds: make(map[string]Creds), + socketPath: socketPath, } } @@ -58,8 +61,8 @@ func (s *server) Start(path string) (io.Closer, error) { return io.NewCloser(listener.Close), nil } -func (s *server) Run(path string) error { - _, err := s.Start(path) +func (s *server) Run() error { + _, err := s.Start(s.socketPath) return err } @@ -88,3 +91,14 @@ func (s *server) getCreds(id string) (*Creds, bool) { creds, ok := s.creds[id] return &creds, ok } + +// Environ returns the environment variables that should be set when invoking git. +func (s *server) Environ(id string) []string { + return []string{ + "GIT_ASKPASS=argocd", + fmt.Sprintf("%s=%s", ASKPASS_NONCE_ENV, id), + "GIT_TERMINAL_PROMPT=0", + "ARGOCD_BINARY_NAME=argocd-git-ask-pass", + fmt.Sprintf("%s=%s", AKSPASS_SOCKET_PATH_ENV, s.socketPath), + } +} diff --git a/reposerver/askpass/server_test.go b/reposerver/askpass/server_test.go index 311592d7f0aa7..980575a669670 100644 --- a/reposerver/askpass/server_test.go +++ b/reposerver/askpass/server_test.go @@ -7,7 +7,7 @@ import ( ) func TestAdd(t *testing.T) { - s := NewServer() + s := NewServer(SocketPath) nonce := s.Add("foo", "bar") assert.Equal(t, "foo", s.creds[nonce].Username) @@ -15,7 +15,7 @@ func TestAdd(t *testing.T) { } func TestRemove(t *testing.T) { - s := NewServer() + s := NewServer(SocketPath) s.creds["some-id"] = Creds{Username: "foo"} s.Remove("some-id") diff --git a/reposerver/cache/cache_test.go b/reposerver/cache/cache_test.go index 6cc0a3f53333a..82e7fd556ad16 100644 --- a/reposerver/cache/cache_test.go +++ b/reposerver/cache/cache_test.go @@ -4,7 +4,6 @@ import ( "encoding/json" "errors" "fmt" - "strings" "testing" "time" @@ -12,6 +11,7 @@ import ( "github.com/spf13/cobra" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" @@ -48,7 +48,7 @@ func TestCache_GetRevisionMetadata(t *testing.T) { mockCache.RedisClient.AssertCalled(t, "Get", mock.Anything, mock.Anything) // populate cache err = cache.SetRevisionMetadata("my-repo-url", "my-revision", &RevisionMetadata{Message: "my-message"}) - assert.NoError(t, err) + require.NoError(t, err) // cache miss _, err = cache.GetRevisionMetadata("other-repo-url", "my-revision") assert.Equal(t, ErrCacheMiss, err) @@ -57,7 +57,7 @@ func TestCache_GetRevisionMetadata(t *testing.T) { assert.Equal(t, ErrCacheMiss, err) // cache hit value, err := cache.GetRevisionMetadata("my-repo-url", "my-revision") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, &RevisionMetadata{Message: "my-message"}, value) mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 4}) } @@ -72,7 +72,7 @@ func TestCache_ListApps(t *testing.T) { assert.Equal(t, ErrCacheMiss, err) // populate cache err = cache.SetApps("my-repo-url", "my-revision", map[string]string{"foo": "bar"}) - assert.NoError(t, err) + require.NoError(t, err) // cache miss _, err = cache.ListApps("other-repo-url", "my-revision") assert.Equal(t, ErrCacheMiss, err) @@ -81,7 +81,7 @@ func TestCache_ListApps(t *testing.T) { assert.Equal(t, ErrCacheMiss, err) // cache hit value, err := cache.ListApps("my-repo-url", "my-revision") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, map[string]string{"foo": "bar"}, value) mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 4}) } @@ -99,7 +99,7 @@ func TestCache_GetManifests(t *testing.T) { // populate cache res := &CachedManifestResponse{ManifestResponse: &apiclient.ManifestResponse{SourceType: "my-source-type"}} err = cache.SetManifests("my-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", res, nil) - assert.NoError(t, err) + require.NoError(t, err) t.Run("expect cache miss because of changed revision", func(t *testing.T) { err = cache.GetManifests("other-revision", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil) assert.Equal(t, ErrCacheMiss, err) @@ -128,10 +128,10 @@ func TestCache_GetManifests(t *testing.T) { err = cache.SetManifests( "my-revision1", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", &CachedManifestResponse{ManifestResponse: &apiclient.ManifestResponse{SourceType: "my-source-type", Revision: "my-revision2"}}, nil) - assert.NoError(t, err) + require.NoError(t, err) err = cache.GetManifests("my-revision1", &ApplicationSource{}, q.RefSources, q, "my-namespace", "", "my-app-label-key", "my-app-label-value", value, nil) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "my-source-type", value.ManifestResponse.SourceType) assert.Equal(t, "my-revision1", value.ManifestResponse.Revision) @@ -151,7 +151,7 @@ func TestCache_GetAppDetails(t *testing.T) { assert.Equal(t, ErrCacheMiss, err) res := &apiclient.RepoAppDetailsResponse{Type: "my-type"} err = cache.SetAppDetails("my-revision", &ApplicationSource{}, emptyRefSources, res, "", nil) - assert.NoError(t, err) + require.NoError(t, err) // cache miss err = cache.GetAppDetails("other-revision", &ApplicationSource{}, emptyRefSources, value, "", nil) assert.Equal(t, ErrCacheMiss, err) @@ -160,14 +160,14 @@ func TestCache_GetAppDetails(t *testing.T) { assert.Equal(t, ErrCacheMiss, err) // cache hit err = cache.GetAppDetails("my-revision", &ApplicationSource{}, emptyRefSources, value, "", nil) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, &apiclient.RepoAppDetailsResponse{Type: "my-type"}, value) mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 4}) } func TestAddCacheFlagsToCmd(t *testing.T) { cache, err := AddCacheFlagsToCmd(&cobra.Command{})() - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, 24*time.Hour, cache.repoCacheExpiration) } @@ -336,7 +336,7 @@ func TestCachedManifestResponse_ShallowCopyExpectedFields(t *testing.T) { // go do that first :) for _, expectedField := range expectedFields { - assert.Truef(t, strings.Contains(string(str), "\""+expectedField+"\""), "Missing field: %s", expectedField) + assert.Containsf(t, string(str), "\""+expectedField+"\"", "Missing field: %s", expectedField) } } @@ -347,7 +347,7 @@ func TestGetGitReferences(t *testing.T) { cache := fixtures.cache var references []*plumbing.Reference lockOwner, err := cache.GetGitReferences("test-repo", &references) - assert.NoError(t, err, "Error is cache miss handled inside function") + require.NoError(t, err, "Error is cache miss handled inside function") assert.Equal(t, "", lockOwner, "Lock owner should be empty") assert.Nil(t, references) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1}) @@ -359,7 +359,7 @@ func TestGetGitReferences(t *testing.T) { cache := fixtures.cache var references []*plumbing.Reference lockOwner, err := cache.GetGitReferences("test-repo", &references) - assert.NoError(t, err, "Error is cache miss handled inside function") + require.NoError(t, err, "Error is cache miss handled inside function") assert.Equal(t, "", lockOwner, "Lock owner should be empty") assert.Nil(t, references) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1}) @@ -370,10 +370,10 @@ func TestGetGitReferences(t *testing.T) { t.Cleanup(fixtures.mockCache.StopRedisCallback) cache := fixtures.cache err := cache.SetGitReferences("test-repo", *GitRefCacheItemToReferences([][2]string{{"test-repo", "ref: test"}})) - assert.NoError(t, err) + require.NoError(t, err) var references []*plumbing.Reference lockOwner, err := cache.GetGitReferences("test-repo", &references) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "", lockOwner, "Lock owner should be empty") assert.Len(t, references, 1) assert.Equal(t, "test", (references)[0].Target().String()) @@ -389,7 +389,7 @@ func TestGetGitReferences(t *testing.T) { fixtures.mockCache.RedisClient.On("Get", mock.Anything, mock.Anything).Return(errors.New("test cache error")) var references []*plumbing.Reference lockOwner, err := cache.GetGitReferences("test-repo", &references) - assert.ErrorContains(t, err, "test cache error", "Error should be propagated") + require.ErrorContains(t, err, "test cache error", "Error should be propagated") assert.Equal(t, "", lockOwner, "Lock owner should be empty") assert.Nil(t, references) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1}) @@ -428,32 +428,32 @@ func TestTryLockGitRefCache_OwnershipFlows(t *testing.T) { // Test setting the lock _, err := cache.TryLockGitRefCache("my-repo-url", "my-lock-id", &references) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 1}) - assert.NoError(t, err) + require.NoError(t, err) var output [][2]string key := fmt.Sprintf("git-refs|%s", "my-repo-url") err = utilCache.GetItem(key, &output) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 2}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "locked", output[0][0], "The lock should be set") assert.Equal(t, "my-lock-id", output[0][1], "The lock should be set to the provided lock id") // Test not being able to overwrite the lock _, err = cache.TryLockGitRefCache("my-repo-url", "other-lock-id", &references) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 2, ExternalGets: 3}) - assert.NoError(t, err) + require.NoError(t, err) err = utilCache.GetItem(key, &output) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 2, ExternalGets: 4}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "locked", output[0][0], "The lock should not have changed") assert.Equal(t, "my-lock-id", output[0][1], "The lock should not have changed") // Test can overwrite once there is nothing set err = utilCache.SetItem(key, [][2]string{}, &cacheutil.CacheActionOpts{Expiration: 0, Delete: true}) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 2, ExternalGets: 4, ExternalDeletes: 1}) - assert.NoError(t, err) + require.NoError(t, err) _, err = cache.TryLockGitRefCache("my-repo-url", "other-lock-id", &references) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 3, ExternalGets: 5, ExternalDeletes: 1}) - assert.NoError(t, err) + require.NoError(t, err) err = utilCache.GetItem(key, &output) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "locked", output[0][0], "The lock should be set") assert.Equal(t, "other-lock-id", output[0][1], "The lock id should have changed to other-lock-id") fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 3, ExternalGets: 6, ExternalDeletes: 1}) @@ -466,7 +466,7 @@ func TestGetOrLockGitReferences(t *testing.T) { cache := fixtures.cache var references []*plumbing.Reference lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "test-lock-id", lockId) assert.NotEqual(t, "", lockId, "Lock id should be set") fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1, ExternalGets: 2}) @@ -477,10 +477,10 @@ func TestGetOrLockGitReferences(t *testing.T) { t.Cleanup(fixtures.mockCache.StopRedisCallback) cache := fixtures.cache err := cache.SetGitReferences("test-repo", *GitRefCacheItemToReferences([][2]string{{"test-repo", "ref: test"}})) - assert.NoError(t, err) + require.NoError(t, err) var references []*plumbing.Reference lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) - assert.NoError(t, err) + require.NoError(t, err) assert.NotEqual(t, "test-lock-id", lockId) assert.Equal(t, "", lockId, "Lock id should not be set") assert.Equal(t, "test-repo", references[0].Name().String()) @@ -498,10 +498,10 @@ func TestGetOrLockGitReferences(t *testing.T) { &cacheutil.CacheActionOpts{ Expiration: 30 * time.Second, }) - assert.NoError(t, err) + require.NoError(t, err) var references []*plumbing.Reference lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) - assert.NoError(t, err) + require.NoError(t, err) assert.NotEqual(t, "test-lock-id", lockId) assert.Equal(t, "", lockId, "Lock id should not be set") assert.Equal(t, "test-repo", references[0].Name().String()) @@ -518,11 +518,11 @@ func TestGetOrLockGitReferences(t *testing.T) { 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(args mock.Arguments) { err := cache.SetGitReferences("test-repo", *GitRefCacheItemToReferences([][2]string{{"test-repo", "ref: test"}})) - assert.NoError(t, err) + require.NoError(t, err) }).On("Get", mock.Anything, mock.Anything).Return(nil) var references []*plumbing.Reference lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) - assert.NoError(t, err) + require.NoError(t, err) assert.NotEqual(t, "test-lock-id", lockId) assert.Equal(t, "", lockId, "Lock id should not be set") fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 2, ExternalGets: 2}) @@ -534,11 +534,11 @@ func TestGetOrLockGitReferences(t *testing.T) { cache := fixtures.cache // Create conditions for cache hit, which would result in false on updateCache if we weren't reaching the timeout err := cache.SetGitReferences("test-repo", *GitRefCacheItemToReferences([][2]string{{"test-repo", "ref: test"}})) - assert.NoError(t, err) + require.NoError(t, err) cache.revisionCacheLockTimeout = -1 * time.Second var references []*plumbing.Reference lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "test-lock-id", lockId) assert.NotEqual(t, "", lockId, "Lock id should be set") cache.revisionCacheLockTimeout = 10 * time.Second @@ -555,7 +555,7 @@ func TestGetOrLockGitReferences(t *testing.T) { On("Set", mock.Anything).Return(nil) var references []*plumbing.Reference lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "test-lock-id", lockId) assert.NotEqual(t, "", lockId, "Lock id should be set") fixtures.mockCache.RedisClient.AssertNumberOfCalls(t, "Set", 2) @@ -570,7 +570,7 @@ func TestUnlockGitReferences(t *testing.T) { t.Run("Test not locked", func(t *testing.T) { err := cache.UnlockGitReferences("test-repo", "") - assert.Error(t, err) + require.Error(t, err) assert.Contains(t, err.Error(), "key is missing") }) @@ -578,12 +578,12 @@ func TestUnlockGitReferences(t *testing.T) { // Get lock var references []*plumbing.Reference lockId, err := cache.GetOrLockGitReferences("test-repo", "test-lock-id", &references) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "test-lock-id", lockId) assert.NotEqual(t, "", lockId, "Lock id should be set") // Release lock err = cache.UnlockGitReferences("test-repo", lockId) - assert.NoError(t, err) + require.NoError(t, err) }) } @@ -592,17 +592,17 @@ func TestSetHelmIndex(t *testing.T) { fixtures := newFixtures() t.Cleanup(fixtures.mockCache.StopRedisCallback) err := fixtures.cache.SetHelmIndex("test-repo", []byte("test-data")) - assert.NoError(t, err) + require.NoError(t, err) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalSets: 1}) }) t.Run("SetHelmIndex with nil", func(t *testing.T) { fixtures := newFixtures() t.Cleanup(fixtures.mockCache.StopRedisCallback) err := fixtures.cache.SetHelmIndex("test-repo", nil) - assert.Error(t, err, "nil data should not be cached") + require.Error(t, err, "nil data should not be cached") var indexData []byte err = fixtures.cache.GetHelmIndex("test-repo", &indexData) - assert.Error(t, err) + require.Error(t, err) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1}) }) } @@ -612,7 +612,7 @@ func TestRevisionChartDetails(t *testing.T) { fixtures := newFixtures() t.Cleanup(fixtures.mockCache.StopRedisCallback) details, err := fixtures.cache.GetRevisionChartDetails("test-repo", "test-revision", "v1.0.0") - assert.ErrorAs(t, err, &ErrCacheMiss) + require.ErrorIs(t, err, ErrCacheMiss) assert.Equal(t, &appv1.ChartDetails{}, details) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1}) }) @@ -629,9 +629,9 @@ func TestRevisionChartDetails(t *testing.T) { revisionChartDetailsKey("test-repo", "test-revision", "v1.0.0"), expectedItem, &cacheutil.CacheActionOpts{Expiration: 30 * time.Second}) - assert.NoError(t, err) + require.NoError(t, err) details, err := fixtures.cache.GetRevisionChartDetails("test-repo", "test-revision", "v1.0.0") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedItem, details) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1, ExternalSets: 1}) }) @@ -649,9 +649,9 @@ func TestRevisionChartDetails(t *testing.T) { revisionChartDetailsKey("test-repo", "test-revision", "v1.0.0"), expectedItem, &cacheutil.CacheActionOpts{Expiration: 30 * time.Second}) - assert.NoError(t, err) + require.NoError(t, err) details, err := fixtures.cache.GetRevisionChartDetails("test-repo", "test-revision", "v1.0.0") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedItem, details) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1, ExternalSets: 1}) }) @@ -665,9 +665,9 @@ func TestRevisionChartDetails(t *testing.T) { Maintainers: []string{"test-maintainer"}, } err := fixtures.cache.SetRevisionChartDetails("test-repo", "test-revision", "v1.0.0", expectedItem) - assert.NoError(t, err) + require.NoError(t, err) details, err := fixtures.cache.GetRevisionChartDetails("test-repo", "test-revision", "v1.0.0") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedItem, details) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1, ExternalSets: 1}) }) @@ -678,7 +678,7 @@ func TestGetGitDirectories(t *testing.T) { fixtures := newFixtures() t.Cleanup(fixtures.mockCache.StopRedisCallback) directories, err := fixtures.cache.GetGitDirectories("test-repo", "test-revision") - assert.ErrorAs(t, err, &ErrCacheMiss) + require.ErrorIs(t, err, ErrCacheMiss) assert.Empty(t, directories) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1}) }) @@ -691,9 +691,9 @@ func TestGetGitDirectories(t *testing.T) { gitDirectoriesKey("test-repo", "test-revision"), expectedItem, &cacheutil.CacheActionOpts{Expiration: 30 * time.Second}) - assert.NoError(t, err) + require.NoError(t, err) directories, err := fixtures.cache.GetGitDirectories("test-repo", "test-revision") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedItem, directories) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1, ExternalSets: 1}) }) @@ -707,9 +707,9 @@ func TestGetGitDirectories(t *testing.T) { gitDirectoriesKey("test-repo", "test-revision"), expectedItem, &cacheutil.CacheActionOpts{Expiration: 30 * time.Second}) - assert.NoError(t, err) + require.NoError(t, err) directories, err := fixtures.cache.GetGitDirectories("test-repo", "test-revision") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedItem, directories) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1, ExternalSets: 1}) }) @@ -719,9 +719,9 @@ func TestGetGitDirectories(t *testing.T) { t.Cleanup(fixtures.mockCache.StopRedisCallback) expectedItem := []string{"test/dir", "test/dir2"} err := fixtures.cache.SetGitDirectories("test-repo", "test-revision", expectedItem) - assert.NoError(t, err) + require.NoError(t, err) directories, err := fixtures.cache.GetGitDirectories("test-repo", "test-revision") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedItem, directories) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1, ExternalSets: 1}) }) @@ -732,7 +732,7 @@ func TestGetGitFiles(t *testing.T) { fixtures := newFixtures() t.Cleanup(fixtures.mockCache.StopRedisCallback) directories, err := fixtures.cache.GetGitFiles("test-repo", "test-revision", "*.json") - assert.ErrorAs(t, err, &ErrCacheMiss) + require.ErrorIs(t, err, ErrCacheMiss) assert.Empty(t, directories) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1}) }) @@ -745,9 +745,9 @@ func TestGetGitFiles(t *testing.T) { gitFilesKey("test-repo", "test-revision", "*.json"), expectedItem, &cacheutil.CacheActionOpts{Expiration: 30 * time.Second}) - assert.NoError(t, err) + require.NoError(t, err) files, err := fixtures.cache.GetGitFiles("test-repo", "test-revision", "*.json") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedItem, files) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1, ExternalSets: 1}) }) @@ -757,9 +757,9 @@ func TestGetGitFiles(t *testing.T) { t.Cleanup(fixtures.mockCache.StopRedisCallback) expectedItem := map[string][]byte{"test/file.json": []byte("\"test\":\"contents\""), "test/file1.json": []byte("\"test1\":\"contents1\"")} err := fixtures.cache.SetGitFiles("test-repo", "test-revision", "*.json", expectedItem) - assert.NoError(t, err) + require.NoError(t, err) files, err := fixtures.cache.GetGitFiles("test-repo", "test-revision", "*.json") - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedItem, files) fixtures.mockCache.AssertCacheCalledTimes(t, &mocks.CacheCallCounts{ExternalGets: 1, ExternalSets: 1}) }) diff --git a/reposerver/repository/chart_test.go b/reposerver/repository/chart_test.go index f948e4bc59e46..3e1bccfa46a07 100644 --- a/reposerver/repository/chart_test.go +++ b/reposerver/repository/chart_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func Test_getChartDetailsNotSet(t *testing.T) { @@ -12,7 +13,7 @@ name: mychart version: 0.0.0` cd, err := getChartDetails(chart1) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "", cd.Description) assert.Equal(t, cd.Maintainers, []string(nil)) assert.Equal(t, "", cd.Home) @@ -30,7 +31,7 @@ maintainers: ` cd, err := getChartDetails(chart1) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "a good chart", cd.Description) assert.Equal(t, []string{"alex "}, cd.Maintainers) assert.Equal(t, "https://example.com", cd.Home) @@ -44,7 +45,7 @@ maintainers: - name: alex ` cd, err = getChartDetails(chart1) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, []string{"alex"}, cd.Maintainers) } @@ -58,6 +59,6 @@ maintainers: alex ` cd, err := getChartDetails(chart1) - assert.Error(t, err) + require.Error(t, err) assert.Nil(t, cd) } diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index 99f6ac64323b2..7115c1bedd9aa 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -91,8 +91,8 @@ type Service struct { parallelismLimitSemaphore *semaphore.Weighted metricsServer *metrics.MetricsServer resourceTracking argo.ResourceTracking - newGitClient func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (git.Client, error) - newHelmClient func(repoURL string, creds helm.Creds, enableOci bool, proxy string, opts ...helm.ClientOpts) helm.Client + newGitClient func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, noProxy string, opts ...git.ClientOpts) (git.Client, error) + newHelmClient func(repoURL string, creds helm.Creds, enableOci bool, proxy string, noProxy string, opts ...helm.ClientOpts) helm.Client initConstants RepoServerInitConstants // now is usually just time.Now, but may be replaced by unit tests for testing purposes now func() time.Time @@ -113,6 +113,7 @@ type RepoServerInitConstants struct { HelmRegistryMaxIndexSize int64 DisableHelmManifestMaxExtractedSize bool IncludeHiddenDirectories bool + CMPUseManifestGeneratePaths bool } // NewService returns a new instance of the Manifest service @@ -131,8 +132,8 @@ func NewService(metricsServer *metrics.MetricsServer, cache *cache.Cache, initCo metricsServer: metricsServer, newGitClient: git.NewClientExt, resourceTracking: resourceTracking, - newHelmClient: func(repoURL string, creds helm.Creds, enableOci bool, proxy string, opts ...helm.ClientOpts) helm.Client { - return helm.NewClientWithLock(repoURL, creds, sync.NewKeyLock(), enableOci, proxy, opts...) + newHelmClient: func(repoURL string, creds helm.Creds, enableOci bool, proxy string, noProxy string, opts ...helm.ClientOpts) helm.Client { + return helm.NewClientWithLock(repoURL, creds, sync.NewKeyLock(), enableOci, proxy, noProxy, opts...) }, initConstants: initConstants, now: time.Now, @@ -472,7 +473,13 @@ func resolveReferencedSources(hasMultipleSources bool, source *v1alpha1.Applicat return repoRefs, nil } - for _, valueFile := range source.ValueFiles { + refFileParams := make([]string, 0) + for _, fileParam := range source.FileParameters { + refFileParams = append(refFileParams, fileParam.Path) + } + refCandidates := append(source.ValueFiles, refFileParams...) + + for _, valueFile := range refCandidates { if strings.HasPrefix(valueFile, "$") { refVar := strings.Split(valueFile, "/")[0] @@ -710,8 +717,14 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, // check whether they should be replicated in resolveReferencedSources. if q.HasMultipleSources { if q.ApplicationSource.Helm != nil { + refFileParams := make([]string, 0) + for _, fileParam := range q.ApplicationSource.Helm.FileParameters { + refFileParams = append(refFileParams, fileParam.Path) + } + refCandidates := append(q.ApplicationSource.Helm.ValueFiles, refFileParams...) + // Checkout every one of the referenced sources to the target revision before generating Manifests - for _, valueFile := range q.ApplicationSource.Helm.ValueFiles { + for _, valueFile := range refCandidates { if strings.HasPrefix(valueFile, "$") { refVar := strings.Split(valueFile, "/")[0] @@ -793,7 +806,7 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, } } - manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, s.initConstants.MaxCombinedDirectoryManifestsSize, s.gitRepoPaths, WithCMPTarDoneChannel(ch.tarDoneCh), WithCMPTarExcludedGlobs(s.initConstants.CMPTarExcludedGlobs)) + manifestGenResult, err = GenerateManifests(ctx, opContext.appPath, repoRoot, commitSHA, q, false, s.gitCredsStore, s.initConstants.MaxCombinedDirectoryManifestsSize, s.gitRepoPaths, WithCMPTarDoneChannel(ch.tarDoneCh), WithCMPTarExcludedGlobs(s.initConstants.CMPTarExcludedGlobs), WithCMPUseManifestGeneratePaths(s.initConstants.CMPUseManifestGeneratePaths)) } refSourceCommitSHAs := make(map[string]string) if len(repoRefs) > 0 { @@ -1090,7 +1103,7 @@ 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 io.TempPaths) ([]*unstructured.Unstructured, 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) @@ -1105,9 +1118,9 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie templateOpts := &helm.TemplateOpts{ Name: appName, - Namespace: q.Namespace, - KubeVersion: text.SemVer(q.KubeVersion), - APIVersions: q.ApiVersions, + Namespace: q.ApplicationSource.GetNamespaceOrDefault(q.Namespace), + KubeVersion: text.SemVer(q.ApplicationSource.GetKubeVersionOrDefault(q.KubeVersion)), + APIVersions: q.ApplicationSource.GetAPIVersionsOrDefault(q.ApiVersions), Set: map[string]string{}, SetString: map[string]string{}, SetFile: map[string]pathutil.ResolvedFilePath{}, @@ -1126,7 +1139,7 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie resolvedValueFiles, err := getResolvedValueFiles(appPath, repoRoot, env, q.GetValuesFileSchemes(), appHelm.ValueFiles, q.RefSources, gitRepoPaths, appHelm.IgnoreMissingValueFiles) if err != nil { - return nil, fmt.Errorf("error resolving helm value files: %w", err) + return nil, "", fmt.Errorf("error resolving helm value files: %w", err) } templateOpts.Values = resolvedValueFiles @@ -1134,7 +1147,7 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie if !appHelm.ValuesIsEmpty() { rand, err := uuid.NewRandom() if err != nil { - return nil, fmt.Errorf("error generating random filename for Helm values file: %w", err) + return nil, "", fmt.Errorf("error generating random filename for Helm values file: %w", err) } p := path.Join(os.TempDir(), rand.String()) defer func() { @@ -1145,9 +1158,9 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie }() err = os.WriteFile(p, appHelm.ValuesYAML(), 0o644) if err != nil { - return nil, fmt.Errorf("error writing helm values file: %w", err) + return nil, "", fmt.Errorf("error writing helm values file: %w", err) } - templateOpts.Values = append(templateOpts.Values, pathutil.ResolvedFilePath(p)) + templateOpts.ExtraValues = pathutil.ResolvedFilePath(p) } for _, p := range appHelm.Parameters { @@ -1158,9 +1171,19 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie } } for _, p := range appHelm.FileParameters { - resolvedPath, _, err := pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, env.Envsubst(p.Path), q.GetValuesFileSchemes()) - if err != nil { - return nil, fmt.Errorf("error resolving helm value file path: %w", err) + var resolvedPath pathutil.ResolvedFilePath + referencedSource := getReferencedSource(p.Path, q.RefSources) + if referencedSource != nil { + // If the $-prefixed path appears to reference another source, do env substitution _after_ resolving the source + resolvedPath, err = getResolvedRefValueFile(p.Path, env, q.GetValuesFileSchemes(), referencedSource.Repo.Repo, gitRepoPaths, referencedSource.Repo.Project) + if err != nil { + return nil, "", fmt.Errorf("error resolving set-file path: %w", err) + } + } else { + resolvedPath, _, err = pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, env.Envsubst(p.Path), q.GetValuesFileSchemes()) + if err != nil { + return nil, "", fmt.Errorf("error resolving helm value file path: %w", err) + } } templateOpts.SetFile[p.Name] = resolvedPath } @@ -1184,24 +1207,20 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie helmRepos, err := getHelmRepos(appPath, q.Repos, q.HelmRepoCreds) if err != nil { - return nil, fmt.Errorf("error getting helm repos: %w", err) + return nil, "", fmt.Errorf("error getting helm repos: %w", err) } - h, err := helm.NewHelmApp(appPath, helmRepos, isLocal, version, proxy, passCredentials) + h, err := helm.NewHelmApp(appPath, helmRepos, isLocal, version, proxy, q.Repo.NoProxy, passCredentials) if err != nil { - return nil, fmt.Errorf("error initializing helm app object: %w", err) + return nil, "", fmt.Errorf("error initializing helm app object: %w", err) } defer h.Dispose() - err = h.Init() - if err != nil { - return nil, fmt.Errorf("error initializing helm app: %w", err) - } - out, err := h.Template(templateOpts) + out, command, err := h.Template(templateOpts) if err != nil { if !helm.IsMissingDependencyErr(err) { - return nil, err + return nil, "", err } if concurrencyAllowed { @@ -1226,18 +1245,39 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie } if len(reposNotPermitted) > 0 { - return nil, status.Errorf(codes.PermissionDenied, "helm repos %s are not permitted in project '%s'", strings.Join(reposNotPermitted, ", "), q.ProjectName) + return nil, "", status.Errorf(codes.PermissionDenied, "helm repos %s are not permitted in project '%s'", strings.Join(reposNotPermitted, ", "), q.ProjectName) } - return nil, err + return nil, "", err } - out, err = h.Template(templateOpts) + out, command, err = h.Template(templateOpts) if err != nil { - return nil, err + return nil, "", err } } - return kube.SplitYAML([]byte(out)) + objs, err := kube.SplitYAML([]byte(out)) + + redactedCommand := redactPaths(command, gitRepoPaths, templateOpts.ExtraValues) + + return objs, redactedCommand, err +} + +// 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 io.TempPaths, extraValuesPath pathutil.ResolvedFilePath) string { + if paths == nil { + return s + } + for _, p := range paths.GetPaths() { + s = strings.ReplaceAll(s, p, ".") + } + if extraValuesPath != "" { + // Replace with a placeholder so that the user knows what this values file was for. + s = strings.ReplaceAll(s, string(extraValuesPath), "") + } + return s } func getResolvedValueFiles( @@ -1337,8 +1377,9 @@ func getRepoCredential(repoCredentials []*v1alpha1.RepoCreds, repoURL string) *v type ( GenerateManifestOpt func(*generateManifestOpt) generateManifestOpt struct { - cmpTarDoneCh chan<- bool - cmpTarExcludedGlobs []string + cmpTarDoneCh chan<- bool + cmpTarExcludedGlobs []string + cmpUseManifestGeneratePaths bool } ) @@ -1367,6 +1408,14 @@ func WithCMPTarExcludedGlobs(excludedGlobs []string) GenerateManifestOpt { } } +// WithCMPUseManifestGeneratePaths enables or disables the use of the +// 'argocd.argoproj.io/manifest-generate-paths' annotation for manifest generation instead of transmit the whole repository. +func WithCMPUseManifestGeneratePaths(enabled bool) GenerateManifestOpt { + return func(o *generateManifestOpt) { + o.cmpUseManifestGeneratePaths = enabled + } +} + // GenerateManifests generates manifests from a path. Overrides are applied as a side effect on the given ApplicationSource. func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, q *apiclient.ManifestRequest, isLocal bool, gitCredsStore git.CredsStore, maxCombinedManifestQuantity resource.Quantity, gitRepoPaths io.TempPaths, opts ...GenerateManifestOpt) (*apiclient.ManifestResponse, error) { opt := newGenerateManifestOpt(opts...) @@ -1385,23 +1434,30 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, repoURL = q.Repo.Repo } + var commands []string + switch appSourceType { case v1alpha1.ApplicationSourceTypeHelm: - targetObjs, err = helmTemplate(appPath, repoRoot, env, q, isLocal, gitRepoPaths) + var command string + targetObjs, command, err = helmTemplate(appPath, repoRoot, env, q, isLocal, gitRepoPaths) + commands = append(commands, command) case v1alpha1.ApplicationSourceTypeKustomize: kustomizeBinary := "" if q.KustomizeOptions != nil { kustomizeBinary = q.KustomizeOptions.BinaryPath } - k := kustomize.NewKustomizeApp(repoRoot, appPath, q.Repo.GetGitCreds(gitCredsStore), repoURL, kustomizeBinary) - targetObjs, _, err = k.Build(q.ApplicationSource.Kustomize, q.KustomizeOptions, env) + k := kustomize.NewKustomizeApp(repoRoot, appPath, q.Repo.GetGitCreds(gitCredsStore), repoURL, kustomizeBinary, q.Repo.Proxy, q.Repo.NoProxy) + targetObjs, _, commands, err = k.Build(q.ApplicationSource.Kustomize, q.KustomizeOptions, env, &kustomize.BuildOpts{ + KubeVersion: text.SemVer(q.ApplicationSource.GetKubeVersionOrDefault(q.KubeVersion)), + APIVersions: q.ApplicationSource.GetAPIVersionsOrDefault(q.ApiVersions), + }) case v1alpha1.ApplicationSourceTypePlugin: pluginName := "" if q.ApplicationSource.Plugin != nil { pluginName = q.ApplicationSource.Plugin.Name } // if pluginName is provided it has to be `-` or just `` if plugin version is empty - targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, pluginName, env, q, opt.cmpTarDoneCh, opt.cmpTarExcludedGlobs) + targetObjs, err = runConfigManagementPluginSidecars(ctx, appPath, repoRoot, pluginName, env, q, opt.cmpTarDoneCh, opt.cmpTarExcludedGlobs, opt.cmpUseManifestGeneratePaths) if err != nil { err = fmt.Errorf("plugin sidecar failed. %s", err.Error()) } @@ -1460,25 +1516,32 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, return &apiclient.ManifestResponse{ Manifests: manifests, SourceType: string(appSourceType), + Commands: commands, }, nil } func newEnv(q *apiclient.ManifestRequest, revision string) *v1alpha1.Env { - shortRevision := revision - if len(shortRevision) > 7 { - shortRevision = shortRevision[:7] - } + shortRevision := shortenRevision(revision, 7) + shortRevision8 := shortenRevision(revision, 8) 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_REVISION", Value: revision}, &v1alpha1.EnvEntry{Name: "ARGOCD_APP_REVISION_SHORT", Value: shortRevision}, + &v1alpha1.EnvEntry{Name: "ARGOCD_APP_REVISION_SHORT_8", Value: shortRevision8}, &v1alpha1.EnvEntry{Name: "ARGOCD_APP_SOURCE_REPO_URL", Value: q.Repo.Repo}, &v1alpha1.EnvEntry{Name: "ARGOCD_APP_SOURCE_PATH", Value: q.ApplicationSource.Path}, &v1alpha1.EnvEntry{Name: "ARGOCD_APP_SOURCE_TARGET_REVISION", Value: q.ApplicationSource.TargetRevision}, } } +func shortenRevision(revision string, length int) string { + if len(revision) > length { + return revision[:length] + } + return revision +} + func newEnvRepoQuery(q *apiclient.RepoServerAppDetailsQuery, revision string) *v1alpha1.Env { return &v1alpha1.Env{ &v1alpha1.EnvEntry{Name: "ARGOCD_APP_NAME", Value: q.AppName}, @@ -1911,7 +1974,7 @@ func getPluginParamEnvs(envVars []string, plugin *v1alpha1.ApplicationSourcePlug return env, nil } -func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, pluginName string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, tarDoneCh chan<- bool, tarExcludedGlobs []string) ([]*unstructured.Unstructured, error) { +func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, pluginName string, envVars *v1alpha1.Env, q *apiclient.ManifestRequest, tarDoneCh chan<- bool, tarExcludedGlobs []string, useManifestGeneratePaths bool) ([]*unstructured.Unstructured, error) { // compute variables. env, err := getPluginEnvs(envVars, q) if err != nil { @@ -1925,8 +1988,15 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, p } defer io.Close(conn) + rootPath := repoPath + if useManifestGeneratePaths { + // Transmit the files under the common root path for all paths related to the manifest generate paths annotation. + rootPath = getApplicationRootPath(q, appPath, repoPath) + log.Debugf("common root path calculated for application %s: %s", q.AppName, rootPath) + } + // generate manifests using commands provided in plugin config file in detected cmp-server sidecar - cmpManifests, err := generateManifestsCMP(ctx, appPath, repoPath, env, cmpClient, tarDoneCh, tarExcludedGlobs) + cmpManifests, err := generateManifestsCMP(ctx, appPath, rootPath, env, cmpClient, tarDoneCh, tarExcludedGlobs) if err != nil { return nil, fmt.Errorf("error generating manifests in cmp: %w", err) } @@ -1949,7 +2019,7 @@ func runConfigManagementPluginSidecars(ctx context.Context, appPath, repoPath, p // generateManifestsCMP will send the appPath files to the cmp-server over a gRPC stream. // The cmp-server will generate the manifests. Returns a response object with the generated // manifests. -func generateManifestsCMP(ctx context.Context, appPath, repoPath string, env []string, cmpClient pluginclient.ConfigManagementPluginServiceClient, tarDoneCh chan<- bool, tarExcludedGlobs []string) (*pluginclient.ManifestResponse, error) { +func generateManifestsCMP(ctx context.Context, appPath, rootPath string, env []string, cmpClient pluginclient.ConfigManagementPluginServiceClient, tarDoneCh chan<- bool, tarExcludedGlobs []string) (*pluginclient.ManifestResponse, error) { generateManifestStream, err := cmpClient.GenerateManifest(ctx, grpc_retry.Disable()) if err != nil { return nil, fmt.Errorf("error getting generateManifestStream: %w", err) @@ -1958,7 +2028,7 @@ func generateManifestsCMP(ctx context.Context, appPath, repoPath string, env []s cmp.WithTarDoneChan(tarDoneCh), } - err = cmp.SendRepoStream(generateManifestStream.Context(), appPath, repoPath, generateManifestStream, env, tarExcludedGlobs, opts...) + err = cmp.SendRepoStream(generateManifestStream.Context(), appPath, rootPath, generateManifestStream, env, tarExcludedGlobs, opts...) if err != nil { return nil, fmt.Errorf("error sending file to cmp-server: %w", err) } @@ -1995,7 +2065,7 @@ func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppD return err } case v1alpha1.ApplicationSourceTypePlugin: - if err := populatePluginAppDetails(ctx, res, opContext.appPath, repoRoot, q, s.gitCredsStore, s.initConstants.CMPTarExcludedGlobs); err != nil { + if err := populatePluginAppDetails(ctx, res, opContext.appPath, repoRoot, q, s.initConstants.CMPTarExcludedGlobs); err != nil { return fmt.Errorf("failed to populate plugin app details: %w", err) } } @@ -2052,15 +2122,11 @@ func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath strin if err != nil { return err } - h, err := helm.NewHelmApp(appPath, helmRepos, false, version, q.Repo.Proxy, passCredentials) + h, err := helm.NewHelmApp(appPath, helmRepos, false, version, q.Repo.Proxy, q.Repo.NoProxy, passCredentials) if err != nil { return err } defer h.Dispose() - err = h.Init() - if err != nil { - return err - } if resolvedValuesPath, _, err := pathutil.ResolveValueFilePathOrUrl(appPath, repoRoot, "values.yaml", []string{}); err == nil { if err := loadFileIntoIfExists(resolvedValuesPath, &res.Helm.Values); err != nil { @@ -2137,7 +2203,7 @@ func populateKustomizeAppDetails(res *apiclient.RepoAppDetailsResponse, q *apicl if q.KustomizeOptions != nil { kustomizeBinary = q.KustomizeOptions.BinaryPath } - k := kustomize.NewKustomizeApp(repoRoot, appPath, q.Repo.GetGitCreds(credsStore), q.Repo.Repo, kustomizeBinary) + k := kustomize.NewKustomizeApp(repoRoot, appPath, q.Repo.GetGitCreds(credsStore), q.Repo.Repo, kustomizeBinary, q.Repo.Proxy, q.Repo.NoProxy) fakeManifestRequest := apiclient.ManifestRequest{ AppName: q.AppName, Namespace: "", // FIXME: omit it for now @@ -2145,7 +2211,7 @@ func populateKustomizeAppDetails(res *apiclient.RepoAppDetailsResponse, q *apicl ApplicationSource: q.Source, } env := newEnv(&fakeManifestRequest, reversion) - _, images, err := k.Build(q.Source.Kustomize, q.KustomizeOptions, env) + _, images, _, err := k.Build(q.Source.Kustomize, q.KustomizeOptions, env, nil) if err != nil { return err } @@ -2153,7 +2219,7 @@ func populateKustomizeAppDetails(res *apiclient.RepoAppDetailsResponse, q *apicl return nil } -func populatePluginAppDetails(ctx context.Context, res *apiclient.RepoAppDetailsResponse, appPath string, repoPath string, q *apiclient.RepoServerAppDetailsQuery, store git.CredsStore, tarExcludedGlobs []string) error { +func populatePluginAppDetails(ctx context.Context, res *apiclient.RepoAppDetailsResponse, appPath string, repoPath string, q *apiclient.RepoServerAppDetailsQuery, tarExcludedGlobs []string) error { res.Plugin = &apiclient.PluginAppSpec{} envVars := []string{ @@ -2298,7 +2364,7 @@ func (s *Service) GetRevisionChartDetails(ctx context.Context, q *apiclient.Repo return nil, fmt.Errorf("error extracting chart: %w", err) } defer io.Close(closer) - helmCmd, err := helm.NewCmdWithVersion(chartPath, helm.HelmV3, q.Repo.EnableOCI, q.Repo.Proxy) + 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) } @@ -2332,7 +2398,7 @@ func (s *Service) newClient(repo *v1alpha1.Repository, opts ...git.ClientOpts) ( return nil, err } opts = append(opts, git.WithEventHandlers(metrics.NewGitClientEventHandlers(s.metricsServer))) - return s.newGitClient(repo.Repo, repoPath, repo.GetGitCreds(s.gitCredsStore), repo.IsInsecure(), repo.EnableLFS, repo.Proxy, opts...) + return s.newGitClient(repo.Repo, repoPath, repo.GetGitCreds(s.gitCredsStore), repo.IsInsecure(), repo.EnableLFS, repo.Proxy, repo.NoProxy, opts...) } // newClientResolveRevision is a helper to perform the common task of instantiating a git client @@ -2352,7 +2418,7 @@ func (s *Service) newClientResolveRevision(repo *v1alpha1.Repository, revision s func (s *Service) newHelmClientResolveRevision(repo *v1alpha1.Repository, revision string, chart string, noRevisionCache bool) (helm.Client, string, error) { enableOCI := repo.EnableOCI || helm.IsHelmOciRepo(repo.Repo) - helmClient := s.newHelmClient(repo.Repo, repo.GetHelmCreds(), enableOCI, repo.Proxy, helm.WithIndexCache(s.cache), helm.WithChartPaths(s.chartPaths)) + helmClient := s.newHelmClient(repo.Repo, repo.GetHelmCreds(), enableOCI, repo.Proxy, repo.NoProxy, helm.WithIndexCache(s.cache), helm.WithChartPaths(s.chartPaths)) if helm.IsVersion(revision) { return helmClient, revision, nil } @@ -2465,7 +2531,7 @@ func checkoutRevision(gitClient git.Client, revision string, submoduleEnabled bo } 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, helm.WithChartPaths(s.chartPaths)).GetIndex(true, s.initConstants.HelmRegistryMaxIndexSize) + 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 } @@ -2490,17 +2556,17 @@ func (s *Service) TestRepository(ctx context.Context, q *apiclient.TestRepositor } checks := map[string]func() error{ "git": func() error { - return git.TestRepo(repo.Repo, repo.GetGitCreds(s.gitCredsStore), repo.IsInsecure(), repo.IsLFSEnabled(), repo.Proxy) + return git.TestRepo(repo.Repo, repo.GetGitCreds(s.gitCredsStore), repo.IsInsecure(), repo.IsLFSEnabled(), repo.Proxy, repo.NoProxy) }, "helm": func() error { if repo.EnableOCI { if !helm.IsHelmOciRepo(repo.Repo) { return errors.New("OCI Helm repository URL should include hostname and port only") } - _, err := helm.NewClient(repo.Repo, repo.GetHelmCreds(), repo.EnableOCI, repo.Proxy).TestHelmOCI() + _, 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).GetIndex(false, s.initConstants.HelmRegistryMaxIndexSize) + _, err := helm.NewClient(repo.Repo, repo.GetHelmCreds(), repo.EnableOCI, repo.Proxy, repo.NoProxy).GetIndex(false, s.initConstants.HelmRegistryMaxIndexSize) return err } }, @@ -2531,7 +2597,7 @@ func (s *Service) ResolveRevision(ctx context.Context, q *apiclient.ResolveRevis 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) + 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 } @@ -2736,7 +2802,7 @@ func (s *Service) UpdateRevisionForPaths(_ context.Context, request *apiclient.U return &apiclient.UpdateRevisionForPathsResponse{}, nil } - gitClientOpts := git.WithCache(s.cache, true) + gitClientOpts := git.WithCache(s.cache, !request.NoRevisionCache) gitClient, revision, err := s.newClientResolveRevision(repo, revision, gitClientOpts) if err != nil { return nil, status.Errorf(codes.Internal, "unable to resolve git revision %s: %v", revision, err) @@ -2750,7 +2816,9 @@ func (s *Service) UpdateRevisionForPaths(_ context.Context, request *apiclient.U // No need to compare if it is the same revision if revision == syncedRevision { - return &apiclient.UpdateRevisionForPathsResponse{}, nil + return &apiclient.UpdateRevisionForPathsResponse{ + Revision: revision, + }, nil } s.metricsServer.IncPendingRepoRequest(repo.Repo) @@ -2769,7 +2837,10 @@ func (s *Service) UpdateRevisionForPaths(_ context.Context, request *apiclient.U return nil, status.Errorf(codes.Internal, "unable to get changed files for repo %s with revision %s: %v", repo.Repo, revision, err) } - changed := apppathutil.AppFilesHaveChanged(refreshPaths, files) + changed := false + if len(files) != 0 { + changed = apppathutil.AppFilesHaveChanged(refreshPaths, files) + } if !changed { logCtx.Debugf("no changes found for application %s in repo %s from revision %s to revision %s", request.AppName, repo.Repo, syncedRevision, revision) @@ -2778,14 +2849,21 @@ func (s *Service) UpdateRevisionForPaths(_ context.Context, request *apiclient.U if err != nil { // Only warn with the error, no need to block anything if there is a caching error. logCtx.Warnf("error updating cached revision for repo %s with revision %s: %v", repo.Repo, revision, err) - return &apiclient.UpdateRevisionForPathsResponse{}, nil + return &apiclient.UpdateRevisionForPathsResponse{ + Revision: revision, + }, nil } - return &apiclient.UpdateRevisionForPathsResponse{}, nil + return &apiclient.UpdateRevisionForPathsResponse{ + Revision: revision, + }, nil } logCtx.Debugf("changes found for application %s in repo %s from revision %s to revision %s", request.AppName, repo.Repo, syncedRevision, revision) - return &apiclient.UpdateRevisionForPathsResponse{}, nil + return &apiclient.UpdateRevisionForPathsResponse{ + Revision: revision, + Changes: true, + }, nil } func (s *Service) updateCachedRevision(logCtx *log.Entry, oldRev string, newRev string, request *apiclient.UpdateRevisionForPathsRequest, gitClientOpts git.ClientOpts) error { diff --git a/reposerver/repository/repository.proto b/reposerver/repository/repository.proto index d0a72d09902a9..631ab2787171a 100644 --- a/reposerver/repository/repository.proto +++ b/reposerver/repository/repository.proto @@ -21,7 +21,9 @@ message ManifestRequest { // Deprecated: use sidecar plugins instead. 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; @@ -36,6 +38,8 @@ message ManifestRequest { repeated string projectSourceRepos = 24; // This is used to surface "source not permitted" errors for Helm repositories string projectName = 25; + // argocd.argoproj.io/manifest-generate-paths annotation value of the Application to allow optimize which resources propagated to cmpserver + string AnnotationManifestGeneratePaths = 26; } message ManifestRequestWithFiles { @@ -92,6 +96,8 @@ message ManifestResponse { string sourceType = 6; // Raw response of git verify-commit operation (always the empty string for Helm) string verifyResult = 7; + // Commands is the list of commands used to hydrate the manifests + repeated string commands = 8; } message ListRefsRequest { @@ -275,9 +281,13 @@ message UpdateRevisionForPathsRequest { string syncedRevision = 11; string revision = 12; repeated string paths = 13; + + bool noRevisionCache = 14; } message UpdateRevisionForPathsResponse { + bool changes = 1; + string revision = 2; } // ManifestService diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go index 38006085fe4d0..0c11553e5d7f4 100644 --- a/reposerver/repository/repository_test.go +++ b/reposerver/repository/repository_test.go @@ -13,6 +13,7 @@ import ( "path" "path/filepath" "regexp" + "slices" "sort" "strings" "sync" @@ -21,6 +22,7 @@ import ( log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/util/intstr" cacheutil "github.com/argoproj/argo-cd/v2/util/cache" @@ -133,6 +135,7 @@ func newServiceWithMocks(t *testing.T, root string, signed bool) (*Service, *git paths.On("Add", mock.Anything, mock.Anything).Return(root, nil) paths.On("GetPath", mock.Anything).Return(root, nil) paths.On("GetPathIfExists", mock.Anything).Return(root, nil) + paths.On("GetPaths").Return(map[string]string{"fake-nonce": root}) }, root) } @@ -145,10 +148,10 @@ 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(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (client git.Client, e error) { + service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, noProxy string, opts ...git.ClientOpts) (client git.Client, e error) { return gitClient, nil } - service.newHelmClient = func(repoURL string, creds helm.Creds, enableOci bool, proxy string, opts ...helm.ClientOpts) helm.Client { + service.newHelmClient = func(repoURL string, creds helm.Creds, enableOci bool, proxy string, noProxy string, opts ...helm.ClientOpts) helm.Client { return helmClient } service.gitRepoInitializer = func(rootPath string) goio.Closer { @@ -188,7 +191,7 @@ func newServiceWithCommitSHA(t *testing.T, root, revision string) *Service { paths.On("GetPathIfExists", mock.Anything).Return(root, nil) }, root) - service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (client git.Client, e error) { + service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, noProxy string, opts ...git.ClientOpts) (client git.Client, e error) { return gitClient, nil } @@ -211,12 +214,12 @@ func TestGenerateYamlManifestInDir(t *testing.T) { res1, err := service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, res1.Manifests, countOfManifests) // this will test concatenated manifests to verify we split YAMLs correctly res2, err := GenerateManifests(context.Background(), "./testdata/concatenated", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, res2.Manifests, 3) } @@ -311,15 +314,15 @@ func TestGenerateManifests_K8SAPIResetCache(t *testing.T) { cachedFakeResponse := &apiclient.ManifestResponse{Manifests: []string{"Fake"}, Revision: mock.Anything} err := service.cache.SetManifests(mock.Anything, &src, q.RefSources, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: cachedFakeResponse}, nil) - assert.NoError(t, err) + require.NoError(t, err) res, err := service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, cachedFakeResponse, res) q.KubeVersion = "v1.17.0" res, err = service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) + require.NoError(t, err) assert.NotEqual(t, cachedFakeResponse, res) assert.Greater(t, len(res.Manifests), 1) } @@ -336,11 +339,11 @@ func TestGenerateManifests_EmptyCache(t *testing.T) { } err := service.cache.SetManifests(mock.Anything, &src, q.RefSources, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: nil}, nil) - assert.NoError(t, err) + require.NoError(t, err) res, err := service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) - assert.Positive(t, len(res.Manifests)) + require.NoError(t, err) + assert.NotEmpty(t, res.Manifests) mockCache.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ ExternalSets: 2, ExternalGets: 2, @@ -360,7 +363,7 @@ func TestGenerateManifest_RefOnlyShortCircuit(t *testing.T) { 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, opts ...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) { 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(repo string) func() { @@ -374,7 +377,7 @@ func TestGenerateManifest_RefOnlyShortCircuit(t *testing.T) { } }, })) - gitClient, err := git.NewClientExt(rawRepoURL, root, creds, insecure, enableLfs, proxy, opts...) + gitClient, err := git.NewClientExt(rawRepoURL, root, creds, insecure, enableLfs, proxy, noProxy, opts...) return gitClient, err } revision := initGitRepo(t, newGitRepoOptions{ @@ -396,14 +399,14 @@ func TestGenerateManifest_RefOnlyShortCircuit(t *testing.T) { ProjectSourceRepos: []string{"*"}, } _, err := service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) + require.NoError(t, err) cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ ExternalSets: 2, ExternalGets: 2, }) assert.True(t, lsremoteCalled, "ls-remote should be called when the source is ref only") var revisions [][2]string - assert.NoError(t, cacheMocks.cacheutilCache.GetItem(fmt.Sprintf("git-refs|%s", 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) } @@ -428,7 +431,7 @@ func TestGenerateManifestsHelmWithRefs_CachedNoLsRemote(t *testing.T) { service := NewService(metrics.NewMetricsServer(), cacheMocks.cache, RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, repopath) var gitClient git.Client var err error - service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (client git.Client, e error) { + 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(repo string) func() { @@ -437,7 +440,7 @@ func TestGenerateManifestsHelmWithRefs_CachedNoLsRemote(t *testing.T) { } }, })) - gitClient, err = git.NewClientExt(rawRepoURL, root, creds, insecure, enableLfs, proxy, opts...) + gitClient, err = git.NewClientExt(rawRepoURL, root, creds, insecure, enableLfs, proxy, noProxy, opts...) return gitClient, err } repoRemote := fmt.Sprintf("file://%s", repopath) @@ -467,9 +470,9 @@ func TestGenerateManifestsHelmWithRefs_CachedNoLsRemote(t *testing.T) { RefSources: map[string]*argoappv1.RefTarget{"$ref": {TargetRevision: "HEAD", Repo: *repo}}, } err = cacheMocks.cacheutilCache.SetItem(fmt.Sprintf("git-refs|%s", repoRemote), [][2]string{{"HEAD", revision}}, nil) - assert.NoError(t, err) + require.NoError(t, err) _, err = service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) + require.NoError(t, err) cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ ExternalSets: 2, ExternalGets: 5, @@ -486,7 +489,7 @@ func TestHelmManifestFromChartRepo(t *testing.T) { ProjectSourceRepos: []string{"*"}, } response, err := service.GenerateManifest(context.Background(), request) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, response) assert.Equal(t, &apiclient.ManifestResponse{ Manifests: []string{"{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"name\":\"my-map\"}}"}, @@ -494,6 +497,7 @@ func TestHelmManifestFromChartRepo(t *testing.T) { Server: "", Revision: "1.1.0", SourceType: "Helm", + Commands: []string{`helm template . --name-template "" --include-crds`}, }, response) mockCache.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ ExternalSets: 1, @@ -523,7 +527,7 @@ func TestHelmChartReferencingExternalValues(t *testing.T) { ProjectSourceRepos: []string{"*"}, } response, err := service.GenerateManifest(context.Background(), request) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, response) assert.Equal(t, &apiclient.ManifestResponse{ Manifests: []string{"{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"name\":\"my-map\"}}"}, @@ -531,6 +535,7 @@ func TestHelmChartReferencingExternalValues(t *testing.T) { Server: "", Revision: "1.1.0", SourceType: "Helm", + Commands: []string{`helm template . --name-template "" --values ./testdata/my-chart/my-chart-values.yaml --include-crds`}, }, response) } @@ -561,7 +566,7 @@ func TestHelmChartReferencingExternalValues_InvalidRefs(t *testing.T) { ProjectSourceRepos: []string{"*"}, } response, err := service.GenerateManifest(context.Background(), request) - assert.Error(t, err) + require.Error(t, err) assert.Nil(t, response) // Invalid ref @@ -576,7 +581,7 @@ func TestHelmChartReferencingExternalValues_InvalidRefs(t *testing.T) { ProjectSourceRepos: []string{"*"}, } response, err = service.GenerateManifest(context.Background(), request) - assert.Error(t, err) + require.Error(t, err) assert.Nil(t, response) // Helm chart as ref (unsupported) @@ -592,7 +597,7 @@ func TestHelmChartReferencingExternalValues_InvalidRefs(t *testing.T) { ProjectSourceRepos: []string{"*"}, } response, err = service.GenerateManifest(context.Background(), request) - assert.Error(t, err) + require.Error(t, err) assert.Nil(t, response) } @@ -610,6 +615,7 @@ func TestHelmChartReferencingExternalValues_OutOfBounds_Symlink(t *testing.T) { err = os.WriteFile("./testdata/oob-symlink/values.yaml", []byte("foo: bar"), 0o644) require.NoError(t, err) spec := argoappv1.ApplicationSpec{ + Project: "default", 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 @@ -627,7 +633,7 @@ func TestHelmChartReferencingExternalValues_OutOfBounds_Symlink(t *testing.T) { require.NoError(t, err) request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true} _, err = service.GenerateManifest(context.Background(), request) - assert.Error(t, err) + require.Error(t, err) } func TestGenerateManifestsUseExactRevision(t *testing.T) { @@ -641,7 +647,7 @@ func TestGenerateManifestsUseExactRevision(t *testing.T) { } res1, err := service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, res1.Manifests, 2) assert.Equal(t, "abc", gitClient.Calls[0].Arguments[0]) } @@ -657,7 +663,7 @@ func TestRecurseManifestsInDir(t *testing.T) { } res1, err := service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, res1.Manifests, 2) } @@ -669,7 +675,7 @@ func TestInvalidManifestsInDir(t *testing.T) { q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src} _, err := service.GenerateManifest(context.Background(), &q) - assert.Error(t, err) + require.Error(t, err) } func TestInvalidMetadata(t *testing.T) { @@ -678,7 +684,7 @@ func TestInvalidMetadata(t *testing.T) { src := argoappv1.ApplicationSource{Path: "./testdata/invalid-metadata", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, AppLabelKey: "test", AppName: "invalid-metadata", TrackingMethod: "annotation+label"} _, err := service.GenerateManifest(context.Background(), &q) - assert.Error(t, err) + require.Error(t, err) assert.Contains(t, err.Error(), "contains non-string value in the map under key \"invalid\"") } @@ -689,7 +695,7 @@ func TestNilMetadataAccessors(t *testing.T) { 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) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, res.Manifests, 1) assert.Equal(t, expected, res.Manifests[0]) } @@ -713,7 +719,7 @@ func TestGenerateJsonnetManifestInDir(t *testing.T) { ProjectSourceRepos: []string{"*"}, } res1, err := service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, res1.Manifests, 2) } @@ -736,7 +742,7 @@ func TestGenerateJsonnetManifestInRootDir(t *testing.T) { ProjectSourceRepos: []string{"*"}, } res1, err := service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, res1.Manifests, 2) } @@ -769,7 +775,7 @@ func TestManifestGenErrorCacheByNumRequests(t *testing.T) { cachedManifestResponse := &cache.CachedManifestResponse{} err := service.cache.GetManifests(mock.Anything, manifestRequest.ApplicationSource, manifestRequest.RefSources, manifestRequest, manifestRequest.Namespace, "", manifestRequest.AppLabelKey, manifestRequest.AppName, cachedManifestResponse, nil) - assert.NoError(t, err) + require.NoError(t, err) return cachedManifestResponse } @@ -905,17 +911,17 @@ func TestManifestGenErrorCacheFileContentsChange(t *testing.T) { // Ensure that the target directory will succeed or fail, so we can verify the cache correctly handles it err := os.RemoveAll(tmpDir) - assert.NoError(t, err) + require.NoError(t, err) err = os.MkdirAll(tmpDir, 0o777) - assert.NoError(t, err) + require.NoError(t, err) if errorExpected { // Copy invalid helm chart into temporary directory, ensuring manifest generation will fail err = fileutil.CopyDir("./testdata/invalid-helm", tmpDir) - assert.NoError(t, err) + require.NoError(t, err) } else { // Copy valid helm chart into temporary directory, ensuring generation will succeed err = fileutil.CopyDir("./testdata/my-chart", tmpDir) - assert.NoError(t, err) + require.NoError(t, err) } res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ @@ -934,16 +940,16 @@ func TestManifestGenErrorCacheFileContentsChange(t *testing.T) { if step < 2 { if errorExpected { - assert.Error(t, err, "error return value and error expected did not match") + require.Error(t, err, "error return value and error expected did not match") assert.Nil(t, res, "GenerateManifest return value and expected value did not match") } else { - assert.NoError(t, err, "error return value and error expected did not match") + require.NoError(t, err, "error return value and error expected did not match") assert.NotNil(t, res, "GenerateManifest return value and expected value did not match") } } if step == 2 { - assert.NoError(t, err, "error ret val was non-nil on step 3") + require.NoError(t, err, "error ret val was non-nil on step 3") assert.NotNil(t, res, "GenerateManifest ret val was nil on step 3") } } @@ -1097,18 +1103,18 @@ func TestGenerateHelmWithValues(t *testing.T) { ProjectSourceRepos: []string{"*"}, }) - assert.NoError(t, err) + require.NoError(t, err) replicasVerified := false for _, src := range res.Manifests { obj := unstructured.Unstructured{} err = json.Unmarshal([]byte(src), &obj) - assert.NoError(t, err) + require.NoError(t, err) if obj.GetKind() == "Deployment" && obj.GetName() == "test-redis-slave" { var dep v1.Deployment err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &dep) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, int32(2), *dep.Spec.Replicas) replicasVerified = true } @@ -1135,13 +1141,13 @@ func TestHelmWithMissingValueFiles(t *testing.T) { // Should fail since we're passing a non-existent values file, and error should indicate that _, err := service.GenerateManifest(context.Background(), req) - assert.Error(t, err) + require.Error(t, err) assert.Contains(t, err.Error(), 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(context.Background(), req) - assert.NoError(t, err) + require.NoError(t, err) } func TestGenerateHelmWithEnvVars(t *testing.T) { @@ -1160,18 +1166,18 @@ func TestGenerateHelmWithEnvVars(t *testing.T) { ProjectSourceRepos: []string{"*"}, }) - assert.NoError(t, err) + require.NoError(t, err) replicasVerified := false for _, src := range res.Manifests { obj := unstructured.Unstructured{} err = json.Unmarshal([]byte(src), &obj) - assert.NoError(t, err) + require.NoError(t, err) if obj.GetKind() == "Deployment" && obj.GetName() == "production-redis-slave" { var dep v1.Deployment err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &dep) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, int32(3), *dep.Spec.Replicas) replicasVerified = true } @@ -1196,7 +1202,7 @@ func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.NoError(t, err) + require.NoError(t, err) // Test the case where the path is "." service = newService(t, "./testdata") @@ -1209,7 +1215,7 @@ func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.NoError(t, err) + require.NoError(t, err) } func TestChartRepoWithOutOfBoundsSymlink(t *testing.T) { @@ -1239,7 +1245,7 @@ func TestHelmManifestFromChartRepoWithValueFile(t *testing.T) { ProjectSourceRepos: []string{"*"}, } response, err := service.GenerateManifest(context.Background(), request) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, response) assert.Equal(t, &apiclient.ManifestResponse{ Manifests: []string{"{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"name\":\"my-map\"}}"}, @@ -1247,6 +1253,7 @@ func TestHelmManifestFromChartRepoWithValueFile(t *testing.T) { Server: "", Revision: "1.1.0", SourceType: "Helm", + Commands: []string{`helm template . --name-template "" --values ./testdata/my-chart/my-chart-values.yaml --include-crds`}, }, response) } @@ -1263,7 +1270,7 @@ func TestHelmManifestFromChartRepoWithValueFileOutsideRepo(t *testing.T) { } request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true} _, err := service.GenerateManifest(context.Background(), request) - assert.Error(t, err) + require.Error(t, err) } func TestHelmManifestFromChartRepoWithValueFileLinks(t *testing.T) { @@ -1281,7 +1288,7 @@ func TestHelmManifestFromChartRepoWithValueFileLinks(t *testing.T) { ProjectSourceRepos: []string{"*"}, } _, err := service.GenerateManifest(context.Background(), request) - assert.NoError(t, err) + require.NoError(t, err) }) } @@ -1302,7 +1309,7 @@ func TestGenerateHelmWithURL(t *testing.T) { ProjectSourceRepos: []string{"*"}, HelmOptions: &argoappv1.HelmOptions{ValuesFileSchemes: []string{"https"}}, }) - assert.NoError(t, err) + require.NoError(t, err) } // The requested value file (`../minio/values.yaml`) is outside the repo directory @@ -1323,7 +1330,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.Error(t, err) + require.Error(t, err) assert.Contains(t, err.Error(), "outside repository root") }) @@ -1342,7 +1349,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("Values file with absolute path stays within repo root", func(t *testing.T) { @@ -1360,7 +1367,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("Values file with absolute path using back-references outside repo root", func(t *testing.T) { @@ -1378,7 +1385,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.Error(t, err) + require.Error(t, err) assert.Contains(t, err.Error(), "outside repository root") }) @@ -1397,7 +1404,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.Error(t, err) + require.Error(t, err) assert.Contains(t, err.Error(), "is not allowed") }) @@ -1416,7 +1423,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.Error(t, err) + require.Error(t, err) assert.Contains(t, err.Error(), "s3://my-bucket/my-chart-values.yaml: no such file or directory") }) } @@ -1426,13 +1433,13 @@ func TestGenerateHelmWithAbsoluteFileParameter(t *testing.T) { service := newService(t, "../..") file, err := os.CreateTemp("", "external-secret.txt") - assert.NoError(t, err) + require.NoError(t, err) externalSecretPath := file.Name() defer func() { _ = os.RemoveAll(externalSecretPath) }() expectedFileContent, err := os.ReadFile("../../util/helm/testdata/external/external-secret.txt") - assert.NoError(t, err) + require.NoError(t, err) err = os.WriteFile(externalSecretPath, expectedFileContent, 0o644) - assert.NoError(t, err) + require.NoError(t, err) defer func() { if err = file.Close(); err != nil { panic(err) @@ -1456,7 +1463,7 @@ func TestGenerateHelmWithAbsoluteFileParameter(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.Error(t, err) + require.Error(t, err) } // The requested file parameter (`../external/external-secret.txt`) is outside the app path @@ -1484,7 +1491,7 @@ func TestGenerateHelmWithFileParameter(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Contains(t, res.Manifests[6], `"replicas":2`, "ValuesObject should override Values") } @@ -1499,7 +1506,7 @@ func TestGenerateNullList(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, res1.Manifests, 1) assert.Contains(t, res1.Manifests[0], "prometheus-operator-operator") }) @@ -1512,7 +1519,7 @@ func TestGenerateNullList(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, res1.Manifests, 1) assert.Contains(t, res1.Manifests[0], "prometheus-operator-operator") }) @@ -1525,22 +1532,22 @@ func TestGenerateNullList(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, res1.Manifests, 2) }) } func TestIdentifyAppSourceTypeByAppDirWithKustomizations(t *testing.T) { sourceType, err := GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yaml", "./testdata", "testapp", map[string]bool{}, []string{}, []string{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType) sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/kustomization_yml", "./testdata", "testapp", map[string]bool{}, []string{}, []string{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType) sourceType, err = GetAppSourceType(context.Background(), &argoappv1.ApplicationSource{}, "./testdata/Kustomization", "./testdata", "testapp", map[string]bool{}, []string{}, []string{}) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, argoappv1.ApplicationSourceTypeKustomize, sourceType) } @@ -1552,7 +1559,7 @@ func TestGenerateFromUTF16(t *testing.T) { ProjectSourceRepos: []string{"*"}, } res1, err := GenerateManifests(context.Background(), "./testdata/utf-16", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, res1.Manifests, 2) } @@ -1560,7 +1567,7 @@ func TestListApps(t *testing.T) { service := newService(t, "./testdata") res, err := service.ListApps(context.Background(), &apiclient.ListAppsRequest{Repo: &argoappv1.Repository{}}) - assert.NoError(t, err) + require.NoError(t, err) expectedApps := map[string]string{ "Kustomization": "Kustomize", @@ -1580,6 +1587,8 @@ func TestListApps(t *testing.T) { "values-files": "Helm", "helm-with-dependencies": "Helm", "helm-with-dependencies-alias": "Helm", + "helm-with-local-dependency": "Helm", + "simple-chart": "Helm", } assert.Equal(t, expectedApps, res.Apps) } @@ -1594,7 +1603,7 @@ func TestGetAppDetailsHelm(t *testing.T) { }, }) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, res.Helm) assert.Equal(t, "Helm", res.Type) @@ -1611,7 +1620,7 @@ func TestGetAppDetailsHelmUsesCache(t *testing.T) { }, }) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, res.Helm) assert.Equal(t, "Helm", res.Type) @@ -1628,7 +1637,7 @@ func TestGetAppDetailsHelm_WithNoValuesFile(t *testing.T) { }, }) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, res.Helm) assert.Equal(t, "Helm", res.Type) @@ -1646,7 +1655,7 @@ func TestGetAppDetailsKustomize(t *testing.T) { }, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "Kustomize", res.Type) assert.NotNil(t, res.Kustomize) @@ -1662,7 +1671,7 @@ func TestGetHelmCharts(t *testing.T) { return res.Items[i].Name < res.Items[j].Name }) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, res.Items, 2) item := res.Items[0] @@ -1691,7 +1700,7 @@ func TestGetRevisionMetadata(t *testing.T) { CheckSignature: true, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "test", res.Message) assert.Equal(t, now, res.Date.Time) assert.Equal(t, "author", res.Author) @@ -1705,7 +1714,7 @@ func TestGetRevisionMetadata(t *testing.T) { CheckSignature: true, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "test", res.Message) assert.Equal(t, now, res.Date.Time) assert.Equal(t, "author", res.Author) @@ -1718,7 +1727,7 @@ func TestGetRevisionMetadata(t *testing.T) { Revision: "c0b400fc458875d925171398f9ba9eabd5529923", CheckSignature: false, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Empty(t, res.SignatureInfo) // Enforce cache miss - signature info should not be in result @@ -1727,7 +1736,7 @@ func TestGetRevisionMetadata(t *testing.T) { Revision: "da52afd3b2df1ec49470603d8bbb46954dab1091", CheckSignature: false, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Empty(t, res.SignatureInfo) // Cache hit on previous entry that did not have signature info @@ -1736,7 +1745,7 @@ func TestGetRevisionMetadata(t *testing.T) { Revision: "da52afd3b2df1ec49470603d8bbb46954dab1091", CheckSignature: true, }) - assert.NoError(t, err) + require.NoError(t, err) assert.NotEmpty(t, res.SignatureInfo) } @@ -1755,7 +1764,7 @@ func TestGetSignatureVerificationResult(t *testing.T) { } res, err := service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, testSignature, res.VerifyResult) } // Commit with signature and verification not requested @@ -1769,7 +1778,7 @@ func TestGetSignatureVerificationResult(t *testing.T) { } res, err := service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) + require.NoError(t, err) assert.Empty(t, res.VerifyResult) } // Commit without signature and verification requested @@ -1783,7 +1792,7 @@ func TestGetSignatureVerificationResult(t *testing.T) { } res, err := service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) + require.NoError(t, err) assert.Empty(t, res.VerifyResult) } // Commit without signature and verification not requested @@ -1797,7 +1806,7 @@ func TestGetSignatureVerificationResult(t *testing.T) { } res, err := service.GenerateManifest(context.Background(), &q) - assert.NoError(t, err) + require.NoError(t, err) assert.Empty(t, res.VerifyResult) } } @@ -1808,6 +1817,7 @@ func Test_newEnv(t *testing.T) { &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"}, @@ -1915,7 +1925,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { }, AppName: "broken", }) - assert.Error(t, err) + require.Error(t, err) }) }) } @@ -1962,9 +1972,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { for _, manifest := range manifests.Manifests { var un unstructured.Unstructured err := yaml.Unmarshal([]byte(manifest), &un) - if !assert.NoError(t, err) { - return - } + require.NoError(t, err) resourceByKindName[fmt.Sprintf("%s/%s", un.GetKind(), un.GetName())] = &un } deployment, ok := resourceByKindName["Deployment/guestbook-ui"] @@ -1993,9 +2001,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { for _, manifest := range manifests.Manifests { var un unstructured.Unstructured err := yaml.Unmarshal([]byte(manifest), &un) - if !assert.NoError(t, err) { - return - } + require.NoError(t, err) resourceByKindName[fmt.Sprintf("%s/%s", un.GetKind(), un.GetName())] = &un } deployment, ok := resourceByKindName["Deployment/guestbook-ui"] @@ -2025,9 +2031,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { for _, manifest := range manifests.Manifests { var un unstructured.Unstructured err := yaml.Unmarshal([]byte(manifest), &un) - if !assert.NoError(t, err) { - return - } + require.NoError(t, err) resourceByKindName[fmt.Sprintf("%s/%s", un.GetKind(), un.GetName())] = &un } deployment, ok := resourceByKindName["Deployment/guestbook-ui"] @@ -2055,7 +2059,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { ProjectSourceRepos: []string{"*"}, HasMultipleSources: true, }) - assert.NoError(t, err) + require.NoError(t, err) assert.Empty(t, manifests.Manifests) assert.NotEmpty(t, manifests.Revision) }) @@ -2078,9 +2082,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { for _, manifest := range manifests.Manifests { var un unstructured.Unstructured err := yaml.Unmarshal([]byte(manifest), &un) - if !assert.NoError(t, err) { - return - } + require.NoError(t, err) resourceByKindName[fmt.Sprintf("%s/%s", un.GetKind(), un.GetName())] = &un } deployment, ok := resourceByKindName["Deployment/guestbook-ui"] @@ -2107,13 +2109,13 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { ProjectName: "something", ProjectSourceRepos: []string{"*"}, }) - assert.NoError(t, err) + require.NoError(t, err) res := &cache.CachedManifestResponse{} // Try to pull from the cache with a `source` that does not include any overrides. Overrides should not be // part of the cache key, because you can't get the overrides without a repo operation. And avoiding repo // operations is the point of the cache. err = service.cache.GetManifests(mock.Anything, source, argoappv1.RefTargetRevisionMapping{}, &argoappv1.ClusterInfo{}, "", "", "", "test", res, nil) - assert.NoError(t, err) + require.NoError(t, err) }) }) } @@ -2235,6 +2237,72 @@ func TestGenerateManifestWithAnnotatedTagsAndMultiSourceApp(t *testing.T) { } } +func TestGenerateMultiSourceHelmWithFileParameter(t *testing.T) { + expectedFileContent, err := os.ReadFile("../../util/helm/testdata/external/external-secret.txt") + require.NoError(t, err) + + service := newService(t, "../../util/helm/testdata") + + testCases := []struct { + name string + refSources map[string]*argoappv1.RefTarget + expectedContent string + expectedErr bool + }{{ + name: "Successfully resolve multi-source ref for helm set-file", + refSources: map[string]*argoappv1.RefTarget{ + "$global": { + TargetRevision: "HEAD", + }, + }, + expectedContent: string(expectedFileContent), + expectedErr: false, + }, { + name: "Failed to resolve multi-source ref for helm set-file", + refSources: map[string]*argoappv1.RefTarget{}, + expectedContent: "DOES-NOT-EXIST", + expectedErr: true, + }} + + for i := range testCases { + tc := testCases[i] + t.Run(tc.name, func(t *testing.T) { + manifestRequest := &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ + Ref: "$global", + Path: "./redis", + TargetRevision: "HEAD", + Helm: &argoappv1.ApplicationSourceHelm{ + ValueFiles: []string{"$global/redis/values-production.yaml"}, + FileParameters: []argoappv1.HelmFileParameter{{ + Name: "passwordContent", + Path: "$global/external/external-secret.txt", + }}, + }, + }, + HasMultipleSources: true, + NoCache: true, + RefSources: tc.refSources, + } + + res, err := service.GenerateManifest(context.Background(), manifestRequest) + + if !tc.expectedErr { + require.NoError(t, err) + + // Check that any of the manifests contains the secret + idx := slices.IndexFunc(res.Manifests, func(content string) bool { + return strings.Contains(content, tc.expectedContent) + }) + assert.GreaterOrEqual(t, idx, 0, "No manifest contains the value set with the helm fileParameters") + } else { + assert.Error(t, err) + } + }) + } +} + func TestFindResources(t *testing.T) { testCases := []struct { name string @@ -2274,9 +2342,7 @@ func TestFindResources(t *testing.T) { Include: tc.include, Exclude: tc.exclude, }, map[string]bool{}, resource.MustParse("0")) - if !assert.NoError(t, err) { - return - } + require.NoError(t, err) var names []string for i := range objs { names = append(names, objs[i].GetName()) @@ -2292,9 +2358,8 @@ func TestFindManifests_Exclude(t *testing.T) { Exclude: "subdir/deploymentSub.yaml", }, map[string]bool{}, resource.MustParse("0")) - if !assert.NoError(t, err) || !assert.Len(t, objs, 1) { - return - } + require.NoError(t, err) + require.Len(t, objs, 1) assert.Equal(t, "nginx-deployment", objs[0].GetName()) } @@ -2305,9 +2370,8 @@ func TestFindManifests_Exclude_NothingMatches(t *testing.T) { Exclude: "nothing.yaml", }, map[string]bool{}, resource.MustParse("0")) - if !assert.NoError(t, err) || !assert.Len(t, objs, 2) { - return - } + require.NoError(t, err) + require.Len(t, objs, 2) assert.ElementsMatch(t, []string{"nginx-deployment", "nginx-deployment-sub"}, []string{objs[0].GetName(), objs[1].GetName()}) @@ -2360,7 +2424,7 @@ func Test_getPotentiallyValidManifestFile(t *testing.T) { realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(filePath, info, appDir, appDir, "", "") assert.Nil(t, realFileInfo) assert.Empty(t, ignoreMessage) - assert.NoError(t, err) + require.NoError(t, err) }) }) @@ -2394,7 +2458,7 @@ func Test_getPotentiallyValidManifestFile(t *testing.T) { realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(aPath, info, appDir, appDir, "", "") assert.Nil(t, realFileInfo) assert.NotEmpty(t, ignoreMessage) - assert.NoError(t, err) + require.NoError(t, err) }) }) @@ -2427,7 +2491,7 @@ func Test_getPotentiallyValidManifestFile(t *testing.T) { realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(linkPath, info, appDir, appDir, "", "") assert.Nil(t, realFileInfo) assert.Contains(t, ignoreMessage, "non-regular file") - assert.NoError(t, err) + require.NoError(t, err) }) }) @@ -2444,7 +2508,7 @@ func Test_getPotentiallyValidManifestFile(t *testing.T) { realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(filePath, info, appDir, appDir, "*.json", "") assert.Nil(t, realFileInfo) assert.Empty(t, ignoreMessage) - assert.NoError(t, err) + require.NoError(t, err) }) }) @@ -2461,7 +2525,7 @@ func Test_getPotentiallyValidManifestFile(t *testing.T) { realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(filePath, info, appDir, appDir, "", "excluded.*") assert.Nil(t, realFileInfo) assert.Empty(t, ignoreMessage) - assert.NoError(t, err) + require.NoError(t, err) }) }) @@ -2482,7 +2546,7 @@ func Test_getPotentiallyValidManifestFile(t *testing.T) { realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(linkPath, info, appDir, appDir, "", "") assert.NotNil(t, realFileInfo) assert.Empty(t, ignoreMessage) - assert.NoError(t, err) + require.NoError(t, err) }) }) @@ -2499,7 +2563,7 @@ func Test_getPotentiallyValidManifestFile(t *testing.T) { realFileInfo, ignoreMessage, err := getPotentiallyValidManifestFile(filePath, info, appDir, appDir, "", "") assert.NotNil(t, realFileInfo) assert.Empty(t, ignoreMessage) - assert.NoError(t, err) + require.NoError(t, err) }) }) @@ -2521,7 +2585,7 @@ func Test_getPotentiallyValidManifestFile(t *testing.T) { assert.NotNil(t, realFileInfo) assert.Equal(t, filepath.Base(filePath), realFileInfo.Name()) assert.Empty(t, ignoreMessage) - assert.NoError(t, err) + require.NoError(t, err) }) }) } @@ -2542,7 +2606,7 @@ func Test_getPotentiallyValidManifests(t *testing.T) { manifests, err := getPotentiallyValidManifests(logCtx, appDir, appDir, false, "", "", resource.MustParse("0")) assert.Empty(t, manifests) - assert.Error(t, err) + require.Error(t, err) // allow cleanup err = os.Chmod(appDir, 0o777) @@ -2554,19 +2618,19 @@ func Test_getPotentiallyValidManifests(t *testing.T) { t.Run("no recursion when recursion is disabled", func(t *testing.T) { manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/recurse", "./testdata/recurse", false, "", "", resource.MustParse("0")) assert.Len(t, manifests, 1) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("recursion when recursion is enabled", func(t *testing.T) { manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/recurse", "./testdata/recurse", true, "", "", resource.MustParse("0")) assert.Len(t, manifests, 2) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("non-JSON/YAML is skipped", func(t *testing.T) { manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/non-manifest-file", "./testdata/non-manifest-file", false, "", "", resource.MustParse("0")) assert.Empty(t, manifests) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("circular link should throw an error", func(t *testing.T) { @@ -2578,14 +2642,14 @@ func Test_getPotentiallyValidManifests(t *testing.T) { defer os.Remove(path.Join(testDir, "b.json")) manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/circular-link", "./testdata/circular-link", false, "", "", resource.MustParse("0")) assert.Empty(t, manifests) - assert.Error(t, err) + require.Error(t, err) }) t.Run("out-of-bounds symlink should throw an error", func(t *testing.T) { require.DirExists(t, "./testdata/out-of-bounds-link") manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/out-of-bounds-link", "./testdata/out-of-bounds-link", false, "", "", resource.MustParse("0")) assert.Empty(t, manifests) - assert.Error(t, err) + require.Error(t, err) }) t.Run("symlink to a regular file works", func(t *testing.T) { @@ -2595,13 +2659,13 @@ func Test_getPotentiallyValidManifests(t *testing.T) { require.NoError(t, err) manifests, err := getPotentiallyValidManifests(logCtx, appPath, repoRoot, false, "", "", resource.MustParse("0")) assert.Len(t, manifests, 1) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("symlink to nowhere should be ignored", func(t *testing.T) { manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/link-to-nowhere", "./testdata/link-to-nowhere", false, "", "", resource.MustParse("0")) assert.Empty(t, manifests) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("link to over-sized manifest fails", func(t *testing.T) { @@ -2619,7 +2683,7 @@ func Test_getPotentiallyValidManifests(t *testing.T) { // There is a total of 10 files, ech file being 10 bytes. manifests, err := getPotentiallyValidManifests(logCtx, "./testdata/several-files", "./testdata/several-files", false, "", "", resource.MustParse("365")) assert.Len(t, manifests, 10) - assert.NoError(t, err) + require.NoError(t, err) manifests, err = getPotentiallyValidManifests(logCtx, "./testdata/several-files", "./testdata/several-files", false, "", "", resource.MustParse("100")) assert.Empty(t, manifests) @@ -2641,7 +2705,7 @@ func Test_findManifests(t *testing.T) { manifests, err := findManifests(logCtx, appDir, appDir, nil, noRecurse, nil, resource.MustParse("0")) assert.Empty(t, manifests) - assert.Error(t, err) + require.Error(t, err) // allow cleanup err = os.Chmod(appDir, 0o777) @@ -2653,20 +2717,20 @@ func Test_findManifests(t *testing.T) { t.Run("no recursion when recursion is disabled", func(t *testing.T) { manifests, err := findManifests(logCtx, "./testdata/recurse", "./testdata/recurse", nil, noRecurse, nil, resource.MustParse("0")) assert.Len(t, manifests, 2) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("recursion when recursion is enabled", func(t *testing.T) { recurse := argoappv1.ApplicationSourceDirectory{Recurse: true} manifests, err := findManifests(logCtx, "./testdata/recurse", "./testdata/recurse", nil, recurse, nil, resource.MustParse("0")) assert.Len(t, manifests, 4) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("non-JSON/YAML is skipped", func(t *testing.T) { manifests, err := findManifests(logCtx, "./testdata/non-manifest-file", "./testdata/non-manifest-file", nil, noRecurse, nil, resource.MustParse("0")) assert.Empty(t, manifests) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("circular link should throw an error", func(t *testing.T) { @@ -2678,14 +2742,14 @@ func Test_findManifests(t *testing.T) { defer os.Remove(path.Join(testDir, "b.json")) manifests, err := findManifests(logCtx, "./testdata/circular-link", "./testdata/circular-link", nil, noRecurse, nil, resource.MustParse("0")) assert.Empty(t, manifests) - assert.Error(t, err) + require.Error(t, err) }) t.Run("out-of-bounds symlink should throw an error", func(t *testing.T) { require.DirExists(t, "./testdata/out-of-bounds-link") manifests, err := findManifests(logCtx, "./testdata/out-of-bounds-link", "./testdata/out-of-bounds-link", nil, noRecurse, nil, resource.MustParse("0")) assert.Empty(t, manifests) - assert.Error(t, err) + require.Error(t, err) }) t.Run("symlink to a regular file works", func(t *testing.T) { @@ -2695,13 +2759,13 @@ func Test_findManifests(t *testing.T) { require.NoError(t, err) manifests, err := findManifests(logCtx, appPath, repoRoot, nil, noRecurse, nil, resource.MustParse("0")) assert.Len(t, manifests, 1) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("symlink to nowhere should be ignored", func(t *testing.T) { manifests, err := findManifests(logCtx, "./testdata/link-to-nowhere", "./testdata/link-to-nowhere", nil, noRecurse, nil, resource.MustParse("0")) assert.Empty(t, manifests) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("link to over-sized manifest fails", func(t *testing.T) { @@ -2719,7 +2783,7 @@ func Test_findManifests(t *testing.T) { // There is a total of 10 files, each file being 10 bytes. manifests, err := findManifests(logCtx, "./testdata/several-files", "./testdata/several-files", nil, noRecurse, nil, resource.MustParse("365")) assert.Len(t, manifests, 10) - assert.NoError(t, err) + require.NoError(t, err) manifests, err = findManifests(logCtx, "./testdata/several-files", "./testdata/several-files", nil, noRecurse, nil, resource.MustParse("364")) assert.Empty(t, manifests) @@ -2730,7 +2794,7 @@ func Test_findManifests(t *testing.T) { // Each file is 36 bytes. Only the 36-byte json file should be counted against the limit. manifests, err := findManifests(logCtx, "./testdata/jsonnet-and-json", "./testdata/jsonnet-and-json", nil, noRecurse, nil, resource.MustParse("36")) assert.Len(t, manifests, 2) - assert.NoError(t, err) + require.NoError(t, err) manifests, err = findManifests(logCtx, "./testdata/jsonnet-and-json", "./testdata/jsonnet-and-json", nil, noRecurse, nil, resource.MustParse("35")) assert.Empty(t, manifests) @@ -2741,46 +2805,46 @@ func Test_findManifests(t *testing.T) { require.DirExists(t, "./testdata/partially-valid-yaml") manifests, err := findManifests(logCtx, "./testdata/partially-valid-yaml", "./testdata/partially-valid-yaml", nil, noRecurse, nil, resource.MustParse("0")) assert.Empty(t, manifests) - assert.Error(t, err) + require.Error(t, err) }) t.Run("invalid manifest throws an error", func(t *testing.T) { require.DirExists(t, "./testdata/invalid-manifests") manifests, err := findManifests(logCtx, "./testdata/invalid-manifests", "./testdata/invalid-manifests", nil, noRecurse, nil, resource.MustParse("0")) assert.Empty(t, manifests) - assert.Error(t, err) + require.Error(t, err) }) t.Run("irrelevant YAML gets skipped, relevant YAML gets parsed", func(t *testing.T) { manifests, err := findManifests(logCtx, "./testdata/irrelevant-yaml", "./testdata/irrelevant-yaml", nil, noRecurse, nil, resource.MustParse("0")) assert.Len(t, manifests, 1) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("multiple JSON objects in one file throws an error", func(t *testing.T) { require.DirExists(t, "./testdata/json-list") manifests, err := findManifests(logCtx, "./testdata/json-list", "./testdata/json-list", nil, noRecurse, nil, resource.MustParse("0")) assert.Empty(t, manifests) - assert.Error(t, err) + require.Error(t, err) }) t.Run("invalid JSON throws an error", func(t *testing.T) { require.DirExists(t, "./testdata/invalid-json") manifests, err := findManifests(logCtx, "./testdata/invalid-json", "./testdata/invalid-json", nil, noRecurse, nil, resource.MustParse("0")) assert.Empty(t, manifests) - assert.Error(t, err) + require.Error(t, err) }) t.Run("valid JSON returns manifest and no error", func(t *testing.T) { manifests, err := findManifests(logCtx, "./testdata/valid-json", "./testdata/valid-json", nil, noRecurse, nil, resource.MustParse("0")) assert.Len(t, manifests, 1) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("YAML with an empty document doesn't throw an error", func(t *testing.T) { manifests, err := findManifests(logCtx, "./testdata/yaml-with-empty-document", "./testdata/yaml-with-empty-document", nil, noRecurse, nil, resource.MustParse("0")) assert.Len(t, manifests, 1) - assert.NoError(t, err) + require.NoError(t, err) }) } @@ -2802,7 +2866,7 @@ func Test_getHelmDependencyRepos(t *testing.T) { repo2 := "https://eventstore.github.io/EventStore.Charts" repos, err := getHelmDependencyRepos("../../util/helm/testdata/dependency") - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, repos, 2) assert.Equal(t, repos[0].Repo, repo1) assert.Equal(t, repos[1].Repo, repo2) @@ -2824,7 +2888,7 @@ func TestResolveRevision(t *testing.T) { } assert.NotNil(t, resolveRevisionResponse.Revision) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedResolveRevisionResponse, resolveRevisionResponse) } @@ -2844,7 +2908,7 @@ func TestResolveRevisionNegativeScenarios(t *testing.T) { } assert.NotNil(t, resolveRevisionResponse.Revision) - assert.Error(t, err) + require.Error(t, err) assert.Equal(t, expectedResolveRevisionResponse, resolveRevisionResponse) } @@ -2856,7 +2920,7 @@ func TestDirectoryPermissionInitializer(t *testing.T) { io.Close(file) // remove read permissions - assert.NoError(t, os.Chmod(dir, 0o000)) + require.NoError(t, os.Chmod(dir, 0o000)) // Remember to restore permissions when the test finishes so dir can // be removed properly. @@ -2877,42 +2941,42 @@ func TestDirectoryPermissionInitializer(t *testing.T) { func addHelmToGitRepo(t *testing.T, options newGitRepoOptions) { err := os.WriteFile(filepath.Join(options.path, "Chart.yaml"), []byte("name: test\nversion: v1.0.0"), 0o777) - assert.NoError(t, err) + require.NoError(t, err) for valuesFileName, values := range options.helmChartOptions.valuesFiles { valuesFileContents, err := yaml.Marshal(values) - assert.NoError(t, err) + require.NoError(t, err) err = os.WriteFile(filepath.Join(options.path, valuesFileName), valuesFileContents, 0o777) - assert.NoError(t, err) + require.NoError(t, err) } - assert.NoError(t, err) + require.NoError(t, err) cmd := exec.Command("git", "add", "-A") cmd.Dir = options.path - assert.NoError(t, cmd.Run()) + require.NoError(t, cmd.Run()) cmd = exec.Command("git", "commit", "-m", "Initial commit") cmd.Dir = options.path - assert.NoError(t, cmd.Run()) + require.NoError(t, cmd.Run()) } func initGitRepo(t *testing.T, options newGitRepoOptions) (revision string) { if options.createPath { - assert.NoError(t, os.Mkdir(options.path, 0o755)) + require.NoError(t, os.Mkdir(options.path, 0o755)) } cmd := exec.Command("git", "init", "-b", "main", options.path) cmd.Dir = options.path - assert.NoError(t, cmd.Run()) + require.NoError(t, cmd.Run()) if options.remote != "" { cmd = exec.Command("git", "remote", "add", "origin", options.path) cmd.Dir = options.path - assert.NoError(t, cmd.Run()) + require.NoError(t, cmd.Run()) } commitAdded := options.addEmptyCommit || options.helmChartOptions.chartName != "" if options.addEmptyCommit { cmd = exec.Command("git", "commit", "-m", "Initial commit", "--allow-empty") cmd.Dir = options.path - assert.NoError(t, cmd.Run()) + require.NoError(t, cmd.Run()) } else if options.helmChartOptions.chartName != "" { addHelmToGitRepo(t, options) } @@ -2922,7 +2986,7 @@ func initGitRepo(t *testing.T, options newGitRepoOptions) (revision string) { cmd = exec.Command("git", "rev-parse", "HEAD", options.path) cmd.Dir = options.path cmd.Stdout = &revB - assert.NoError(t, cmd.Run()) + require.NoError(t, cmd.Run()) revision = strings.Split(revB.String(), "\n")[0] } return revision @@ -2973,17 +3037,17 @@ func TestCheckoutRevisionCanGetNonstandardRefs(t *testing.T) { destRepoPath, err := os.MkdirTemp(rootPath, "") require.NoError(t, err) - gitClient, err := git.NewClientExt("file://"+sourceRepoPath, destRepoPath, &git.NopCreds{}, true, false, "") + gitClient, err := git.NewClientExt("file://"+sourceRepoPath, destRepoPath, &git.NopCreds{}, true, false, "", "") require.NoError(t, err) pullSha, err := gitClient.LsRemote("refs/pull/123/head") require.NoError(t, err) err = checkoutRevision(gitClient, "does-not-exist", false) - assert.Error(t, err) + require.Error(t, err) err = checkoutRevision(gitClient, pullSha, false) - assert.NoError(t, err) + require.NoError(t, err) } func TestCheckoutRevisionPresentSkipFetch(t *testing.T) { @@ -2995,7 +3059,7 @@ func TestCheckoutRevisionPresentSkipFetch(t *testing.T) { gitClient.On("Checkout", revision, mock.Anything).Return(nil) err := checkoutRevision(gitClient, revision, false) - assert.NoError(t, err) + require.NoError(t, err) } func TestCheckoutRevisionNotPresentCallFetch(t *testing.T) { @@ -3008,7 +3072,7 @@ func TestCheckoutRevisionNotPresentCallFetch(t *testing.T) { gitClient.On("Checkout", revision, mock.Anything).Return(nil) err := checkoutRevision(gitClient, revision, false) - assert.NoError(t, err) + require.NoError(t, err) } // runGit runs a git command in the given working directory. If the command succeeds, it returns the combined standard @@ -3027,14 +3091,14 @@ func Test_walkHelmValueFilesInPath(t *testing.T) { var files []string root := "/obviously/does/not/exist" err := filepath.Walk(root, walkHelmValueFilesInPath(root, &files)) - assert.Error(t, err) + require.Error(t, err) assert.Empty(t, files) }) t.Run("values files", func(t *testing.T) { var files []string root := "./testdata/values-files" err := filepath.Walk(root, walkHelmValueFilesInPath(root, &files)) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, files, 5) }) t.Run("unrelated root", func(t *testing.T) { @@ -3042,7 +3106,7 @@ func Test_walkHelmValueFilesInPath(t *testing.T) { root := "./testdata/values-files" unrelated_root := "/different/root/path" err := filepath.Walk(root, walkHelmValueFilesInPath(unrelated_root, &files)) - assert.Error(t, err) + require.Error(t, err) }) } @@ -3091,7 +3155,7 @@ func TestGetHelmRepos_OCIDependenciesWithHelmRepo(t *testing.T) { }} helmRepos, err := getHelmRepos("./testdata/oci-dependencies", q.Repos, q.HelmRepoCreds) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, helmRepos, 1) assert.Equal(t, "test", helmRepos[0].Username) @@ -3104,7 +3168,7 @@ func TestGetHelmRepos_OCIDependenciesWithRepo(t *testing.T) { 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) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, helmRepos, 1) assert.Equal(t, "test", helmRepos[0].Username) @@ -3121,7 +3185,7 @@ func TestGetHelmRepo_NamedRepos(t *testing.T) { }}} helmRepos, err := getHelmRepos("./testdata/helm-with-dependencies", q.Repos, q.HelmRepoCreds) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, helmRepos, 1) assert.Equal(t, "test", helmRepos[0].Username) @@ -3137,7 +3201,7 @@ func TestGetHelmRepo_NamedReposAlias(t *testing.T) { }}} helmRepos, err := getHelmRepos("./testdata/helm-with-dependencies-alias", q.Repos, q.HelmRepoCreds) - assert.NoError(t, err) + require.NoError(t, err) assert.Len(t, helmRepos, 1) assert.Equal(t, "test-alias", helmRepos[0].Username) @@ -3291,11 +3355,11 @@ func Test_getResolvedValueFiles(t *testing.T) { t.Parallel() resolvedPaths, err := getResolvedValueFiles(path.Join(tempDir, "main-repo"), path.Join(tempDir, "main-repo"), tcc.env, []string{}, []string{tcc.rawPath}, tcc.refSources, paths, false) if !tcc.expectedErr { - assert.NoError(t, err) + require.NoError(t, err) require.Len(t, resolvedPaths, 1) assert.Equal(t, tcc.expectedPath, string(resolvedPaths[0])) } else { - assert.Error(t, err) + require.Error(t, err) assert.Empty(t, resolvedPaths) } }) @@ -3396,13 +3460,13 @@ func TestGetGitDirectories(t *testing.T) { Revision: "HEAD", } directories, err := s.GetGitDirectories(context.TODO(), dirRequest) - assert.NoError(t, err) + 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(context.TODO(), dirRequest) - assert.NoError(t, err) + 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{ ExternalSets: 1, @@ -3430,13 +3494,13 @@ func TestGetGitDirectoriesWithHiddenDirSupported(t *testing.T) { Revision: "HEAD", } directories, err := s.GetGitDirectories(context.TODO(), dirRequest) - assert.NoError(t, err) + 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(context.TODO(), dirRequest) - assert.NoError(t, err) + 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{ ExternalSets: 1, @@ -3528,18 +3592,18 @@ func TestGetGitFiles(t *testing.T) { expected := make(map[string][]byte) for _, filePath := range files { fileContents, err := os.ReadFile(filePath) - assert.NoError(t, err) + require.NoError(t, err) expected[filePath] = fileContents } fileResponse, err := s.GetGitFiles(context.TODO(), filesRequest) - assert.NoError(t, err) + 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(context.TODO(), filesRequest) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expected, fileResponse.GetMap()) cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ ExternalSets: 1, @@ -3679,7 +3743,9 @@ func TestUpdateRevisionForPaths(t *testing.T) { SyncedRevision: "SYNCEDHEAD", Paths: []string{"."}, }, - }, want: &apiclient.UpdateRevisionForPathsResponse{}, wantErr: assert.NoError}, + }, want: &apiclient.UpdateRevisionForPathsResponse{ + Revision: "632039659e542ed7de0c170a4fcc1c571b288fc0", + }, wantErr: assert.NoError}, {name: "ChangedFilesDoNothing", fields: func() fields { s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) @@ -3705,7 +3771,10 @@ func TestUpdateRevisionForPaths(t *testing.T) { SyncedRevision: "SYNCEDHEAD", Paths: []string{"."}, }, - }, want: &apiclient.UpdateRevisionForPathsResponse{}, wantErr: assert.NoError}, + }, want: &apiclient.UpdateRevisionForPathsResponse{ + Revision: "632039659e542ed7de0c170a4fcc1c571b288fc0", + Changes: true, + }, wantErr: assert.NoError}, {name: "NoChangesUpdateCache", fields: func() fields { s, _, c := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) @@ -3738,7 +3807,9 @@ func TestUpdateRevisionForPaths(t *testing.T) { ApplicationSource: &argoappv1.ApplicationSource{Path: "."}, KubeVersion: "v1.16.0", }, - }, want: &apiclient.UpdateRevisionForPathsResponse{}, wantErr: assert.NoError, cacheHit: &cacheHit{ + }, want: &apiclient.UpdateRevisionForPathsResponse{ + Revision: "632039659e542ed7de0c170a4fcc1c571b288fc0", + }, wantErr: assert.NoError, cacheHit: &cacheHit{ previousRevision: "1e67a504d03def3a6a1125d934cb511680f72555", revision: "632039659e542ed7de0c170a4fcc1c571b288fc0", }}, @@ -3776,7 +3847,9 @@ func TestUpdateRevisionForPaths(t *testing.T) { HasMultipleSources: true, }, - }, want: &apiclient.UpdateRevisionForPathsResponse{}, wantErr: assert.NoError, cacheHit: &cacheHit{ + }, want: &apiclient.UpdateRevisionForPathsResponse{ + Revision: "632039659e542ed7de0c170a4fcc1c571b288fc0", + }, wantErr: assert.NoError, cacheHit: &cacheHit{ previousRevision: "1e67a504d03def3a6a1125d934cb511680f72555", revision: "632039659e542ed7de0c170a4fcc1c571b288fc0", }}, @@ -3836,10 +3909,10 @@ func TestGetRefs_CacheWithLockDisabled(t *testing.T) { wg.Add(1) go func() { defer wg.Done() - client, err := git.NewClient(fmt.Sprintf("file://%s", 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() - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, refs) assert.NotEmpty(t, refs.Branches, "Expected branches to be populated") assert.NotEmpty(t, refs.Branches[0]) @@ -3863,10 +3936,10 @@ func TestGetRefs_CacheDisabled(t *testing.T) { }) cacheMocks := newCacheMocks() t.Cleanup(cacheMocks.mockCache.StopRedisCallback) - client, err := git.NewClient(fmt.Sprintf("file://%s", 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() - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, refs) assert.NotEmpty(t, refs.Branches, "Expected branches to be populated") assert.NotEmpty(t, refs.Branches[0]) @@ -3892,10 +3965,10 @@ func TestGetRefs_CacheWithLock(t *testing.T) { wg.Add(1) go func() { defer wg.Done() - client, err := git.NewClient(fmt.Sprintf("file://%s", 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() - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, refs) assert.NotEmpty(t, refs.Branches, "Expected branches to be populated") assert.NotEmpty(t, refs.Branches[0]) @@ -3921,16 +3994,16 @@ func TestGetRefs_CacheUnlockedOnUpdateFailed(t *testing.T) { cacheMocks := newCacheMocks() t.Cleanup(cacheMocks.mockCache.StopRedisCallback) repoUrl := fmt.Sprintf("file://%s", dir) - 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() - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, refs) 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) - assert.Error(t, err, "Should be a cache miss") + 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) cacheMocks.mockCache.AssertNumberOfCalls(t, "GetOrLockGitReferences", 0) @@ -3952,10 +4025,10 @@ func TestGetRefs_CacheLockTryLockGitRefCacheError(t *testing.T) { 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() - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, refs) } @@ -3984,7 +4057,7 @@ func TestGetRevisionChartDetails(t *testing.T) { Home: "test-home", Maintainers: []string{"test-maintainer"}, }) - assert.NoError(t, err) + require.NoError(t, err) chartDetails, err := service.GetRevisionChartDetails(context.Background(), &apiclient.RepoServerRevisionChartDetailsRequest{ Repo: &v1alpha1.Repository{ Repo: fmt.Sprintf("file://%s", root), @@ -3994,7 +4067,7 @@ func TestGetRevisionChartDetails(t *testing.T) { Name: "my-chart", Revision: "1.1.0", }) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "test-description", chartDetails.Description) assert.Equal(t, "test-home", chartDetails.Home) assert.Equal(t, []string{"test-maintainer"}, chartDetails.Maintainers) @@ -4013,7 +4086,7 @@ func TestVerifyCommitSignature(t *testing.T) { Return(testSignature, nil) err := verifyCommitSignature(true, mockGitClient, "abcd1234", repo) - assert.NoError(t, err) + require.NoError(t, err) }) t.Run("VerifyCommitSignature with invalid signature", func(t *testing.T) { @@ -4023,7 +4096,7 @@ func TestVerifyCommitSignature(t *testing.T) { Return("", nil) err := verifyCommitSignature(true, mockGitClient, "abcd1234", repo) - assert.Error(t, err) + require.Error(t, err) assert.Equal(t, "revision abcd1234 is not signed", err.Error()) }) @@ -4034,7 +4107,7 @@ func TestVerifyCommitSignature(t *testing.T) { Return("", fmt.Errorf("UNKNOWN signature: gpg: Unknown signature from ABCDEFGH")) err := verifyCommitSignature(true, mockGitClient, "abcd1234", repo) - assert.Error(t, err) + require.Error(t, err) assert.Equal(t, "UNKNOWN signature: gpg: Unknown signature from ABCDEFGH", err.Error()) }) @@ -4045,7 +4118,7 @@ func TestVerifyCommitSignature(t *testing.T) { 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.Error(t, err) + 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()) }) @@ -4053,6 +4126,187 @@ func TestVerifyCommitSignature(t *testing.T) { t.Setenv("ARGOCD_GPG_ENABLED", "false") mockGitClient := &gitmocks.Client{} err := verifyCommitSignature(false, mockGitClient, "abcd1234", repo) - assert.NoError(t, err) + require.NoError(t, err) + }) +} + +func Test_GenerateManifests_Commands(t *testing.T) { + t.Run("helm", func(t *testing.T) { + service := newService(t, "testdata/my-chart") + + // 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: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ + Path: ".", + Helm: &argoappv1.ApplicationSourceHelm{ + FileParameters: []argoappv1.HelmFileParameter{ + { + Name: "test-file-param-name", + Path: "test-file-param.yaml", + }, + }, + Parameters: []argoappv1.HelmParameter{ + { + Name: "test-param-name", + // Use build env var to test substitution. + Value: "test-value-$ARGOCD_APP_NAME", + ForceString: true, + }, + { + Name: "test-param-bool-name", + // Use build env var to test substitution. + Value: "false", + }, + }, + PassCredentials: true, + SkipCrds: true, + ValueFiles: []string{ + "my-chart-values.yaml", + }, + Values: "test: values", + }, + }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, + } + + 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) + + t.Run("with overrides", func(t *testing.T) { + // These can be set explicitly instead of using inferred values. Make sure the overrides apply. + q.ApplicationSource.Helm.APIVersions = []string{"v3", "v4"} + q.ApplicationSource.Helm.KubeVersion = "5.6.7" + q.ApplicationSource.Helm.Namespace = "different-namespace" + q.ApplicationSource.Helm.ReleaseName = "different-release-name" + + 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) + }) + }) + + t.Run("helm with dependencies", func(t *testing.T) { + // This test makes sure we still get commands, even if we hit the code path that has to run "helm dependency build." + // We don't actually return the "helm dependency build" command, because we expect that the user is able to read + // the "helm template" and figure out how to fix it. + t.Cleanup(func() { + err := os.Remove("testdata/helm-with-local-dependency/Chart.lock") + require.NoError(t, err) + err = os.RemoveAll("testdata/helm-with-local-dependency/charts") + require.NoError(t, err) + }) + + service := newService(t, "testdata/helm-with-local-dependency") + + q := apiclient.ManifestRequest{ + AppName: "test-app", + Namespace: "test-namespace", + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ + Path: ".", + }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, + } + + 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) + }) + + t.Run("kustomize", func(t *testing.T) { + // Write test files to a temp dir, because the test mutates kustomization.yaml in place. + tempDir := t.TempDir() + err := os.WriteFile(path.Join(tempDir, "kustomization.yaml"), []byte(` +resources: +- guestbook.yaml +`), os.FileMode(0o600)) + require.NoError(t, err) + err = os.WriteFile(path.Join(tempDir, "guestbook.yaml"), []byte(` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: guestbook-ui +`), os.FileMode(0o400)) + require.NoError(t, err) + err = os.Mkdir(path.Join(tempDir, "component"), os.FileMode(0o700)) + require.NoError(t, err) + err = os.WriteFile(path.Join(tempDir, "component", "kustomization.yaml"), []byte(` +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component +images: +- name: old + newName: new +`), os.FileMode(0o400)) + require.NoError(t, err) + + service := newService(t, tempDir) + + // 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: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ + Path: ".", + Kustomize: &argoappv1.ApplicationSourceKustomize{ + APIVersions: []string{"v1", "v2"}, + CommonAnnotations: map[string]string{ + // Use build env var to test substitution. + "test": "annotation-$ARGOCD_APP_NAME", + }, + CommonAnnotationsEnvsubst: true, + CommonLabels: map[string]string{ + "test": "label", + }, + Components: []string{"component"}, + ForceCommonAnnotations: true, + ForceCommonLabels: true, + Images: argoappv1.KustomizeImages{ + "image=override", + }, + 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"), + }, + }, + }, + }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, + } + + res, err := service.GenerateManifest(context.Background(), &q) + + require.NoError(t, err) + assert.Equal(t, []string{ + "kustomize edit set nameprefix -- test-prefix", + "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 test:label", + "kustomize edit add annotation --force test:annotation-test-app", + "kustomize edit set namespace -- override-namespace", + "kustomize edit add component component", + "kustomize build .", + }, res.Commands) }) } diff --git a/reposerver/repository/testdata/helm-with-local-dependency/Chart.yaml b/reposerver/repository/testdata/helm-with-local-dependency/Chart.yaml new file mode 100644 index 0000000000000..5daf5d1d091c9 --- /dev/null +++ b/reposerver/repository/testdata/helm-with-local-dependency/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: helm-with-dependencies +version: v1.0.0 +dependencies: + - name: simple-chart + repository: file://../simple-chart + version: v1.1.0 diff --git a/reposerver/repository/testdata/my-chart/test-file-param.yaml b/reposerver/repository/testdata/my-chart/test-file-param.yaml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/reposerver/repository/testdata/simple-chart/Chart.yaml b/reposerver/repository/testdata/simple-chart/Chart.yaml new file mode 100644 index 0000000000000..00bfbfaf78f3e --- /dev/null +++ b/reposerver/repository/testdata/simple-chart/Chart.yaml @@ -0,0 +1,2 @@ +name: simple-chart +version: 1.1.0 diff --git a/reposerver/repository/testdata/simple-chart/simple-chart-values.yaml b/reposerver/repository/testdata/simple-chart/simple-chart-values.yaml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/reposerver/repository/testdata/simple-chart/templates/my-map.yaml b/reposerver/repository/testdata/simple-chart/templates/my-map.yaml new file mode 100644 index 0000000000000..efbeb3b7b9393 --- /dev/null +++ b/reposerver/repository/testdata/simple-chart/templates/my-map.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: my-map \ No newline at end of file diff --git a/reposerver/repository/utils.go b/reposerver/repository/utils.go new file mode 100644 index 0000000000000..d77bef728d92a --- /dev/null +++ b/reposerver/repository/utils.go @@ -0,0 +1,85 @@ +package repository + +import ( + "path/filepath" + "strings" + + securejoin "github.com/cyphar/filepath-securejoin" + log "github.com/sirupsen/logrus" + + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + "github.com/argoproj/argo-cd/v2/util/io/files" +) + +// getApplicationRootPath returns the common root path (shortest shared structure between all paths) among a +// set of application-related paths for manifest generation. AppPath is the lower possible value +func getApplicationRootPath(q *apiclient.ManifestRequest, appPath, repoPath string) string { + paths := getPaths(q, appPath, repoPath) + + if len(paths) == 0 { + // backward compatibility, by default the root path is the repoPath + return repoPath + } + + // the app path must be the lower possible value + commonParts := strings.Split(appPath, string(filepath.Separator)) + + var disjoint bool + for _, path := range paths { + parts := strings.Split(path, string(filepath.Separator)) + // find the minimum length between the current common parts and the current path + minLen := func(a, b int) int { + if a < b { + return a + } + return b + }(len(commonParts), len(parts)) + + // check if diverge /disjoint in some point + for i := 0; i < minLen; i++ { + if commonParts[i] != parts[i] { + commonParts = commonParts[:i] + disjoint = true + break + } + } + + // for non-disjoint paths + if !disjoint && minLen < len(commonParts) { + commonParts = commonParts[:minLen] + } + } + return string(filepath.Separator) + filepath.Join(commonParts...) +} + +// getPaths retrieves all absolute paths associated with the generation of application manifests. +func getPaths(q *apiclient.ManifestRequest, appPath, repoPath string) []string { + var paths []string + for _, annotationPath := range strings.Split(q.AnnotationManifestGeneratePaths, ";") { + if annotationPath == "" { + continue + } + var err error + var path, unsafePath string + + if filepath.IsAbs(annotationPath) { + unsafePath = filepath.Clean(annotationPath) + } else { + appRelPath, err := files.RelativePath(appPath, repoPath) + if err != nil { + log.Errorf("error building app relative path: %v", err) + continue + } + unsafePath = filepath.Clean(filepath.Join(appRelPath, annotationPath)) + } + + path, err = securejoin.SecureJoin(repoPath, unsafePath) + if err != nil { + log.Errorf("error joining repoPath %q and absolute unsafePath %q: %v", repoPath, unsafePath, err) + continue + } + + paths = append(paths, path) + } + return paths +} diff --git a/reposerver/repository/utils_test.go b/reposerver/repository/utils_test.go new file mode 100644 index 0000000000000..3eb2428f09c03 --- /dev/null +++ b/reposerver/repository/utils_test.go @@ -0,0 +1,46 @@ +package repository + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/argoproj/argo-cd/v2/reposerver/apiclient" +) + +func TestGetCommonRootPath(t *testing.T) { + t.Parallel() + + repoRoot := "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731" + + tests := []struct { + name string + annotation string + appPath string + expectedRootPath string + }{ + {"app path", ".", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld"}, + {"app path and relative", "../../overlays;.", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", repoRoot}, + {"app path and absolute path", "/services;.", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services"}, + {"several relative paths", "../../;..;.", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/team/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services"}, + // backward compatibility test + {"no annotation", "", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", repoRoot}, + // appPath should be the lower calculated root path + {"relative subdir", "./manifests", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/team/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/team/helloworld"}, + // glob pattern + {"glob", "/services/shared/*-secret.yaml", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services"}, + {"relative glob", "../*", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services"}, + {"duplicate slashes", "//services/shared/*-secret.yaml", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services/helloworld", "/tmp/_argocd-repo/7a58c52a-0030-4fd9-8cc5-35b2d8b4e731/services"}, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + req := &apiclient.ManifestRequest{AnnotationManifestGeneratePaths: tt.annotation} + rootPath := getApplicationRootPath(req, tt.appPath, repoRoot) + assert.Equal(t, tt.expectedRootPath, rootPath, "input and output should match") + }) + } +} diff --git a/resource_customizations/apps.kruise.io/DaemonSet/health.lua b/resource_customizations/apps.kruise.io/DaemonSet/health.lua index 7705bcc3325e5..30ccdc85da176 100644 --- a/resource_customizations/apps.kruise.io/DaemonSet/health.lua +++ b/resource_customizations/apps.kruise.io/DaemonSet/health.lua @@ -8,7 +8,7 @@ if obj.status ~= nil then hs.status = "Suspended" hs.message = "Daemonset is paused" return hs - elseif obj.spec.updateStrategy.rollingUpdate.partition ~= 0 and obj.metadata.generation > 1 then + elseif (obj.spec.updateStrategy.rollingUpdate.partition ~= nil) and (obj.spec.updateStrategy.rollingUpdate.partition ~= 0 and obj.metadata.generation > 1) then if obj.status.updatedNumberScheduled > (obj.status.desiredNumberScheduled - obj.spec.updateStrategy.rollingUpdate.partition) then hs.status = "Suspended" hs.message = "Daemonset needs manual intervention" diff --git a/resource_customizations/apps.kruise.io/DaemonSet/health_test.yaml b/resource_customizations/apps.kruise.io/DaemonSet/health_test.yaml index 0a8c8292672f3..a1d2579d2e9f8 100644 --- a/resource_customizations/apps.kruise.io/DaemonSet/health_test.yaml +++ b/resource_customizations/apps.kruise.io/DaemonSet/health_test.yaml @@ -11,6 +11,10 @@ tests: status: Progressing message: "Waiting for initialization" inputPath: testdata/unknown.yaml + - healthStatus: + status: Progressing + message: "Waiting for initialization" + inputPath: testdata/no-update-strategy-partition.yaml - healthStatus: status: Suspended message: "Daemonset is paused" diff --git a/resource_customizations/apps.kruise.io/DaemonSet/testdata/no-update-strategy-partition.yaml b/resource_customizations/apps.kruise.io/DaemonSet/testdata/no-update-strategy-partition.yaml new file mode 100644 index 0000000000000..765378b0c6078 --- /dev/null +++ b/resource_customizations/apps.kruise.io/DaemonSet/testdata/no-update-strategy-partition.yaml @@ -0,0 +1,34 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: DaemonSet +metadata: + name: rdma-device-plugin + namespace: nvidia-gpu + generation: 2 +spec: + selector: + matchLabels: + app-name: rdma-device-plugin-pod + template: + metadata: + labels: + app-name: rdma-device-plugin-pod + spec: + containers: + image: 'my-k8s-rdmaplugin' + imagePullPolicy: IfNotPresent + name: k8s-rdma-device-plugin + hostNetwork: true + updateStrategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 50 + rollingUpdateType: Standard + type: RollingUpdate +status: + currentNumberScheduled: 0 + daemonSetHash: 5998d4d4d7 + desiredNumberScheduled: 0 + numberMisscheduled: 0 + numberReady: 0 + observedGeneration: 2 + updatedNumberScheduled: 0 diff --git a/resource_customizations/batch/CronJob/actions/create-job/action.lua b/resource_customizations/batch/CronJob/actions/create-job/action.lua index a6f3253a5b757..aac90c4bf6719 100644 --- a/resource_customizations/batch/CronJob/actions/create-job/action.lua +++ b/resource_customizations/batch/CronJob/actions/create-job/action.lua @@ -36,7 +36,7 @@ job.metadata = deepCopy(obj.spec.jobTemplate.metadata) if job.metadata == nil then job.metadata = {} end -job.metadata.name = obj.metadata.name .. "-" ..os.date("!%Y%m%d%H%M") +job.metadata.name = obj.metadata.name .. "-" ..os.date("!%y%m%d%H%M") job.metadata.namespace = obj.metadata.namespace if job.metadata.annotations == nil then job.metadata.annotations = {} diff --git a/resource_customizations/cluster.x-k8s.io/MachinePool/health.lua b/resource_customizations/cluster.x-k8s.io/MachinePool/health.lua new file mode 100644 index 0000000000000..521aa9a61161a --- /dev/null +++ b/resource_customizations/cluster.x-k8s.io/MachinePool/health.lua @@ -0,0 +1,48 @@ +-- Reference CRD can be found here: +-- https://doc.crds.dev/github.com/kubernetes-sigs/cluster-api/cluster.x-k8s.io/MachinePool/v1beta1@v1.8.1 + +function getStatusBasedOnPhase(obj, hs) + -- Phases can be found here: + -- 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" then + hs.status = "Healthy" + end + if obj.status.phase == "Failed" or obj.status.phase == "Unknown" then + hs.status = "Degraded" + end + end + return hs +end + +function getConditionStatuses(obj, hs) + local extraInfo = "" + if obj.status ~= nil and obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type ~= nil and condition.status == "False" then + if extraInfo ~= "" then + extraInfo = extraInfo .. ", " + end + extraInfo = extraInfo .. "Not " .. condition.type + if condition.reason ~= nil then + extraInfo = extraInfo .. " (" .. condition.reason .. ")" + end + end + end + end + if extraInfo ~= "" then + hs.message = hs.message .. ": " .. extraInfo + end + + return hs +end + +local hs = {} +hs.status = "Progressing" +hs.message = "" + +getStatusBasedOnPhase(obj, hs) +getConditionStatuses(obj, hs) + +return hs diff --git a/resource_customizations/cluster.x-k8s.io/MachinePool/health_test.yaml b/resource_customizations/cluster.x-k8s.io/MachinePool/health_test.yaml new file mode 100644 index 0000000000000..3ea490456e886 --- /dev/null +++ b/resource_customizations/cluster.x-k8s.io/MachinePool/health_test.yaml @@ -0,0 +1,13 @@ +tests: +- healthStatus: + status: Healthy + message: 'MachinePool is Running' + inputPath: testdata/healthy_provisioned.yaml +- healthStatus: + status: Progressing + message: 'MachinePool is Provisioning: Not Ready (WaitingForInfrastructure), Not InfrastructureReady (WaitingForInfrastructure)' + inputPath: testdata/progressing_provisioning.yaml +- healthStatus: + status: Degraded + message: 'MachinePool is Failed' + inputPath: testdata/degraded_failed.yaml diff --git a/resource_customizations/cluster.x-k8s.io/MachinePool/testdata/degraded_failed.yaml b/resource_customizations/cluster.x-k8s.io/MachinePool/testdata/degraded_failed.yaml new file mode 100644 index 0000000000000..2079ebfdea584 --- /dev/null +++ b/resource_customizations/cluster.x-k8s.io/MachinePool/testdata/degraded_failed.yaml @@ -0,0 +1,25 @@ +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: + phase: Failed diff --git a/resource_customizations/cluster.x-k8s.io/MachinePool/testdata/healthy_provisioned.yaml b/resource_customizations/cluster.x-k8s.io/MachinePool/testdata/healthy_provisioned.yaml new file mode 100644 index 0000000000000..02211d4950014 --- /dev/null +++ b/resource_customizations/cluster.x-k8s.io/MachinePool/testdata/healthy_provisioned.yaml @@ -0,0 +1,57 @@ +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: 3 + 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: Running + readyReplicas: 3 + replicas: 3 diff --git a/resource_customizations/cluster.x-k8s.io/MachinePool/testdata/progressing_provisioning.yaml b/resource_customizations/cluster.x-k8s.io/MachinePool/testdata/progressing_provisioning.yaml new file mode 100644 index 0000000000000..f287555ece532 --- /dev/null +++ b/resource_customizations/cluster.x-k8s.io/MachinePool/testdata/progressing_provisioning.yaml @@ -0,0 +1,44 @@ +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: + bootstrapReady: true + conditions: + - lastTransitionTime: '2024-08-19T20:26:30Z' + reason: WaitingForInfrastructure + severity: Info + status: 'False' + type: Ready + - lastTransitionTime: '2024-08-19T20:26:30Z' + status: 'True' + type: BootstrapReady + - lastTransitionTime: '2024-08-19T20:26:30Z' + reason: WaitingForInfrastructure + severity: Info + status: 'False' + type: InfrastructureReady + - lastTransitionTime: '2024-08-19T20:26:30Z' + status: 'True' + type: ReplicasReady + observedGeneration: 1 + phase: Provisioning diff --git a/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/health.lua b/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/health.lua new file mode 100644 index 0000000000000..4c975b9c21455 --- /dev/null +++ b/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/health.lua @@ -0,0 +1,47 @@ +local health_status = { + status = "Progressing", + message = "Provisioning..." +} + +-- If .status is nil or doesn't have conditions, then the control plane is not ready +if obj.status == nil or obj.status.conditions == nil then + return health_status +end + +-- Accumulator for the error messages (could be multiple conditions in error state) +err_msg = "" + +-- Iterate over the conditions to determine the health status +for i, condition in ipairs(obj.status.conditions) do + -- Check if the Ready condition is True, then the control plane is ready + if condition.type == "Ready" and condition.status == "True" then + health_status.status = "Healthy" + health_status.message = "Control plane is ready" + return health_status + end + + -- If we have a condition that is False and has an Error severity, then the control plane is in a degraded state + if condition.status == "False" and condition.severity == "Error" then + health_status.status = "Degraded" + err_msg = err_msg .. condition.message .. " " + end +end + +-- If we have any error conditions, then the control plane is in a degraded state +if health_status.status == "Degraded" then + health_status.message = err_msg + return health_status +end + +-- If .status.ready is False, then the control plane is not ready +if obj.status.ready == false then + health_status.status = "Progressing" + health_status.message = "Control plane is not ready (.status.ready is false)" + return health_status +end + +-- If we reach this point, then the control plane is not ready and we don't have any error conditions +health_status.status = "Progressing" +health_status.message = "Control plane is not ready" + +return health_status diff --git a/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/health_test.yaml b/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/health_test.yaml new file mode 100644 index 0000000000000..6b076583f1edb --- /dev/null +++ b/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/health_test.yaml @@ -0,0 +1,17 @@ +tests: +- healthStatus: + status: Healthy + message: 'Control plane is ready' + inputPath: testdata/healthy.yaml +- healthStatus: + status: Progressing + message: 'Control plane is not ready (.status.ready is false)' + inputPath: testdata/progressing_ready_false.yaml +- healthStatus: + status: Progressing + message: 'Control plane is not ready' + inputPath: testdata/progressing_ready_true.yaml +- healthStatus: + status: Degraded + message: '7 of 10 completed failed reconciling OIDC provider for cluster: failed to create OIDC provider: error creating provider: LimitExceeded: Cannot exceed quota for OpenIdConnectProvidersPerAccount: 100 ' + inputPath: testdata/degraded.yaml diff --git a/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/testdata/degraded.yaml b/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/testdata/degraded.yaml new file mode 100644 index 0000000000000..5ddd95a6370ce --- /dev/null +++ b/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/testdata/degraded.yaml @@ -0,0 +1,50 @@ +apiVersion: controlplane.cluster.x-k8s.io/v1beta2 +kind: AWSManagedControlPlane +metadata: + name: test + namespace: ns-test + ownerReferences: + - apiVersion: cluster.x-k8s.io/v1beta1 + blockOwnerDeletion: true + controller: true + kind: Cluster + name: test +status: + conditions: + - lastTransitionTime: "2024-07-30T11:10:03Z" + status: "False" + severity: Error + message: "7 of 10 completed" + type: Ready + - lastTransitionTime: "2024-07-26T14:35:48Z" + status: "True" + type: ClusterSecurityGroupsReady + - lastTransitionTime: "2024-07-30T02:20:06Z" + status: "True" + type: EKSAddonsConfigured + - lastTransitionTime: "2024-07-26T14:43:57Z" + reason: created + severity: Info + status: "False" + type: EKSControlPlaneCreating + - lastTransitionTime: "2024-07-25T09:22:46Z" + message: "failed reconciling OIDC provider for cluster: failed to create OIDC provider: error creating provider: LimitExceeded: Cannot exceed quota for OpenIdConnectProvidersPerAccount: 100" + reason: EKSControlPlaneReconciliationFailed + severity: Error + status: "False" + - lastTransitionTime: "2024-07-30T11:10:03Z" + status: "True" + type: EKSControlPlaneReady + - lastTransitionTime: "2024-07-26T15:28:01Z" + status: "True" + type: IAMAuthenticatorConfigured + - lastTransitionTime: "2024-07-26T15:27:58Z" + status: "True" + type: IAMControlPlaneRolesReady + - lastTransitionTime: "2024-07-26T14:35:48Z" + status: "True" + type: SubnetsReady + - lastTransitionTime: "2024-07-26T14:35:46Z" + status: "True" + type: VpcReady + ready: true diff --git a/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/testdata/healthy.yaml b/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/testdata/healthy.yaml new file mode 100644 index 0000000000000..4c27c83cc4cb5 --- /dev/null +++ b/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/testdata/healthy.yaml @@ -0,0 +1,46 @@ +apiVersion: controlplane.cluster.x-k8s.io/v1beta2 +kind: AWSManagedControlPlane +metadata: + name: test + namespace: ns-test + ownerReferences: + - apiVersion: cluster.x-k8s.io/v1beta1 + blockOwnerDeletion: true + controller: true + kind: Cluster + name: test +status: + conditions: + - lastTransitionTime: "2024-07-30T11:10:03Z" + status: "True" + type: Ready + - lastTransitionTime: "2024-07-26T14:35:48Z" + status: "True" + type: ClusterSecurityGroupsReady + - lastTransitionTime: "2024-07-30T02:20:06Z" + status: "True" + type: EKSAddonsConfigured + - lastTransitionTime: "2024-07-26T14:43:57Z" + reason: created + severity: Info + status: "False" + type: EKSControlPlaneCreating + - lastTransitionTime: "2024-07-30T11:10:03Z" + status: "True" + type: EKSControlPlaneReady + - lastTransitionTime: "2024-07-30T13:05:45Z" + status: "True" + type: EKSIdentityProviderConfigured + - lastTransitionTime: "2024-07-26T15:28:01Z" + status: "True" + type: IAMAuthenticatorConfigured + - lastTransitionTime: "2024-07-26T15:27:58Z" + status: "True" + type: IAMControlPlaneRolesReady + - lastTransitionTime: "2024-07-26T14:35:48Z" + status: "True" + type: SubnetsReady + - lastTransitionTime: "2024-07-26T14:35:46Z" + status: "True" + type: VpcReady + ready: true diff --git a/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/testdata/progressing_ready_false.yaml b/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/testdata/progressing_ready_false.yaml new file mode 100644 index 0000000000000..2c6199d55fbc3 --- /dev/null +++ b/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/testdata/progressing_ready_false.yaml @@ -0,0 +1,46 @@ +apiVersion: controlplane.cluster.x-k8s.io/v1beta2 +kind: AWSManagedControlPlane +metadata: + name: test + namespace: ns-test + ownerReferences: + - apiVersion: cluster.x-k8s.io/v1beta1 + blockOwnerDeletion: true + controller: true + kind: Cluster + name: test +status: + conditions: + - lastTransitionTime: "2024-07-30T11:10:03Z" + status: "False" + type: Ready + - lastTransitionTime: "2024-07-26T14:35:48Z" + status: "True" + type: ClusterSecurityGroupsReady + - lastTransitionTime: "2024-07-30T02:20:06Z" + status: "True" + type: EKSAddonsConfigured + - lastTransitionTime: "2024-07-26T14:43:57Z" + reason: created + severity: Info + status: "False" + type: EKSControlPlaneCreating + - lastTransitionTime: "2024-07-30T11:10:03Z" + status: "True" + type: EKSControlPlaneReady + - lastTransitionTime: "2024-07-30T13:05:45Z" + status: "True" + type: EKSIdentityProviderConfigured + - lastTransitionTime: "2024-07-26T15:28:01Z" + status: "True" + type: IAMAuthenticatorConfigured + - lastTransitionTime: "2024-07-26T15:27:58Z" + status: "True" + type: IAMControlPlaneRolesReady + - lastTransitionTime: "2024-07-26T14:35:48Z" + status: "True" + type: SubnetsReady + - lastTransitionTime: "2024-07-26T14:35:46Z" + status: "True" + type: VpcReady + ready: false diff --git a/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/testdata/progressing_ready_true.yaml b/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/testdata/progressing_ready_true.yaml new file mode 100644 index 0000000000000..09179d43e8f49 --- /dev/null +++ b/resource_customizations/controlplane.cluster.x-k8s.io/AWSManagedControlPlane/testdata/progressing_ready_true.yaml @@ -0,0 +1,46 @@ +apiVersion: controlplane.cluster.x-k8s.io/v1beta2 +kind: AWSManagedControlPlane +metadata: + name: test + namespace: ns-test + ownerReferences: + - apiVersion: cluster.x-k8s.io/v1beta1 + blockOwnerDeletion: true + controller: true + kind: Cluster + name: test +status: + conditions: + - lastTransitionTime: "2024-07-30T11:10:03Z" + status: "False" + type: Ready + - lastTransitionTime: "2024-07-26T14:35:48Z" + status: "True" + type: ClusterSecurityGroupsReady + - lastTransitionTime: "2024-07-30T02:20:06Z" + status: "True" + type: EKSAddonsConfigured + - lastTransitionTime: "2024-07-26T14:43:57Z" + reason: created + severity: Info + status: "False" + type: EKSControlPlaneCreating + - lastTransitionTime: "2024-07-30T11:10:03Z" + status: "True" + type: EKSControlPlaneReady + - lastTransitionTime: "2024-07-30T13:05:45Z" + status: "True" + type: EKSIdentityProviderConfigured + - lastTransitionTime: "2024-07-26T15:28:01Z" + status: "True" + type: IAMAuthenticatorConfigured + - lastTransitionTime: "2024-07-26T15:27:58Z" + status: "True" + type: IAMControlPlaneRolesReady + - lastTransitionTime: "2024-07-26T14:35:48Z" + status: "True" + type: SubnetsReady + - lastTransitionTime: "2024-07-26T14:35:46Z" + status: "True" + type: VpcReady + ready: true diff --git a/resource_customizations/gateway.solo.io/Gateway/health.lua b/resource_customizations/gateway.solo.io/Gateway/health.lua new file mode 100644 index 0000000000000..4e0930462f38a --- /dev/null +++ b/resource_customizations/gateway.solo.io/Gateway/health.lua @@ -0,0 +1,54 @@ +hs = { + status = "Progressing", + message = "Update in progress" +} + +function getStatus(status) + -- Accepted + if status.state == "Accepted" or status.state == 1 then + hs.status = "Healthy" + hs.message = "The resource has been validated" + return hs + end + + -- Warning + if status.state == "Warning" or status.state == 3 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + -- Pending + if status.state == "Pending" or status.state == 0 then + hs.status = "Suspended" + hs.message = "The resource has not yet been validated" + return hs + end + + -- Rejected + if status.state == "Rejected" or status.state == 2 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + return hs +end + +if obj.status ~= nil then + -- Namespaced version of status + if obj.status.statuses ~= nil then + for i, namespace in pairs(obj.status.statuses) do + hs = getStatus(namespace) + if hs.status ~= "Progressing" then + return hs + end + end + end + + -- Older non-namespaced version of status + if obj.status.state ~= nil then + hs = getStatus(obj.status) + end +end +return hs diff --git a/resource_customizations/gateway.solo.io/Gateway/health_test.yaml b/resource_customizations/gateway.solo.io/Gateway/health_test.yaml new file mode 100644 index 0000000000000..bd7846b5019f1 --- /dev/null +++ b/resource_customizations/gateway.solo.io/Gateway/health_test.yaml @@ -0,0 +1,37 @@ +tests: +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/gloo-rejected.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/non-namespaced-gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/non-namespaced-gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/non-namespaced-gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/non-namespaced-gloo-rejected.yaml +- healthStatus: + status: Progressing + message: "Update in progress" + inputPath: testdata/gloo-no-status.yaml diff --git a/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-accepted.yaml b/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-accepted.yaml new file mode 100644 index 0000000000000..973516d5e2d52 --- /dev/null +++ b/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-accepted.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: Gateway +status: + statuses: + gloo-system: + reportedBy: gateway + state: Accepted + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Accepted diff --git a/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-no-status.yaml b/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-no-status.yaml new file mode 100644 index 0000000000000..5dc9f8050b830 --- /dev/null +++ b/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-no-status.yaml @@ -0,0 +1,2 @@ +apiVersion: gateway.solo.io/v1 +kind: Gateway diff --git a/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-pending.yaml b/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-pending.yaml new file mode 100644 index 0000000000000..643701b928ae9 --- /dev/null +++ b/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: Gateway +status: + statuses: + gloo-system: + reportedBy: gateway + state: Pending + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Pending diff --git a/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-rejected.yaml b/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-rejected.yaml new file mode 100644 index 0000000000000..8499dd8301dc7 --- /dev/null +++ b/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-rejected.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.solo.io/v1 +kind: Gateway +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: Rejected + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Rejected diff --git a/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-warning.yaml b/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-warning.yaml new file mode 100644 index 0000000000000..76c85c21d3228 --- /dev/null +++ b/resource_customizations/gateway.solo.io/Gateway/testdata/gloo-warning.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.solo.io/v1 +kind: Gateway +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: Warning + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Warning diff --git a/resource_customizations/gateway.solo.io/Gateway/testdata/non-namespaced-gloo-accepted.yaml b/resource_customizations/gateway.solo.io/Gateway/testdata/non-namespaced-gloo-accepted.yaml new file mode 100644 index 0000000000000..aa9d5f0eace9e --- /dev/null +++ b/resource_customizations/gateway.solo.io/Gateway/testdata/non-namespaced-gloo-accepted.yaml @@ -0,0 +1,12 @@ +apiVersion: gateway.solo.io/v1 +kind: Gateway +status: + reportedBy: gateway + state: 1 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 1 diff --git a/resource_customizations/gateway.solo.io/Gateway/testdata/non-namespaced-gloo-pending.yaml b/resource_customizations/gateway.solo.io/Gateway/testdata/non-namespaced-gloo-pending.yaml new file mode 100644 index 0000000000000..4092cb131dbeb --- /dev/null +++ b/resource_customizations/gateway.solo.io/Gateway/testdata/non-namespaced-gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: Gateway +status: + statuses: + gloo-system: + reportedBy: gateway + state: 0 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 0 diff --git a/resource_customizations/gateway.solo.io/Gateway/testdata/non-namespaced-gloo-rejected.yaml b/resource_customizations/gateway.solo.io/Gateway/testdata/non-namespaced-gloo-rejected.yaml new file mode 100644 index 0000000000000..633e115a2b934 --- /dev/null +++ b/resource_customizations/gateway.solo.io/Gateway/testdata/non-namespaced-gloo-rejected.yaml @@ -0,0 +1,13 @@ +apiVersion: gateway.solo.io/v1 +kind: Gateway +status: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: 2 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 2 diff --git a/resource_customizations/gateway.solo.io/Gateway/testdata/non-namespaced-gloo-warning.yaml b/resource_customizations/gateway.solo.io/Gateway/testdata/non-namespaced-gloo-warning.yaml new file mode 100644 index 0000000000000..c1693e9eb8a5d --- /dev/null +++ b/resource_customizations/gateway.solo.io/Gateway/testdata/non-namespaced-gloo-warning.yaml @@ -0,0 +1,13 @@ +apiVersion: gateway.solo.io/v1 +kind: Gateway +status: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: 3 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 3 diff --git a/resource_customizations/gateway.solo.io/MatchableHttpGateway/health.lua b/resource_customizations/gateway.solo.io/MatchableHttpGateway/health.lua new file mode 100644 index 0000000000000..4e0930462f38a --- /dev/null +++ b/resource_customizations/gateway.solo.io/MatchableHttpGateway/health.lua @@ -0,0 +1,54 @@ +hs = { + status = "Progressing", + message = "Update in progress" +} + +function getStatus(status) + -- Accepted + if status.state == "Accepted" or status.state == 1 then + hs.status = "Healthy" + hs.message = "The resource has been validated" + return hs + end + + -- Warning + if status.state == "Warning" or status.state == 3 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + -- Pending + if status.state == "Pending" or status.state == 0 then + hs.status = "Suspended" + hs.message = "The resource has not yet been validated" + return hs + end + + -- Rejected + if status.state == "Rejected" or status.state == 2 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + return hs +end + +if obj.status ~= nil then + -- Namespaced version of status + if obj.status.statuses ~= nil then + for i, namespace in pairs(obj.status.statuses) do + hs = getStatus(namespace) + if hs.status ~= "Progressing" then + return hs + end + end + end + + -- Older non-namespaced version of status + if obj.status.state ~= nil then + hs = getStatus(obj.status) + end +end +return hs diff --git a/resource_customizations/gateway.solo.io/MatchableHttpGateway/health_test.yaml b/resource_customizations/gateway.solo.io/MatchableHttpGateway/health_test.yaml new file mode 100644 index 0000000000000..bd7846b5019f1 --- /dev/null +++ b/resource_customizations/gateway.solo.io/MatchableHttpGateway/health_test.yaml @@ -0,0 +1,37 @@ +tests: +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/gloo-rejected.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/non-namespaced-gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/non-namespaced-gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/non-namespaced-gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/non-namespaced-gloo-rejected.yaml +- healthStatus: + status: Progressing + message: "Update in progress" + inputPath: testdata/gloo-no-status.yaml diff --git a/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-accepted.yaml b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-accepted.yaml new file mode 100644 index 0000000000000..a733e4a76a063 --- /dev/null +++ b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-accepted.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: MatchableHttpGateway +status: + statuses: + gloo-system: + reportedBy: gateway + state: Accepted + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Accepted diff --git a/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-no-status.yaml b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-no-status.yaml new file mode 100644 index 0000000000000..58e3356e93e88 --- /dev/null +++ b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-no-status.yaml @@ -0,0 +1,2 @@ +apiVersion: gateway.solo.io/v1 +kind: MatchableHttpGateway diff --git a/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-pending.yaml b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-pending.yaml new file mode 100644 index 0000000000000..12726ea261f62 --- /dev/null +++ b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: MatchableHttpGateway +status: + statuses: + gloo-system: + reportedBy: gateway + state: Pending + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Pending diff --git a/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-rejected.yaml b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-rejected.yaml new file mode 100644 index 0000000000000..0656c3d0e61c0 --- /dev/null +++ b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-rejected.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.solo.io/v1 +kind: MatchableHttpGateway +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: Rejected + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Rejected diff --git a/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-warning.yaml b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-warning.yaml new file mode 100644 index 0000000000000..eb0bf59fb8857 --- /dev/null +++ b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/gloo-warning.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.solo.io/v1 +kind: MatchableHttpGateway +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: Warning + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Warning diff --git a/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/non-namespaced-gloo-accepted.yaml b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/non-namespaced-gloo-accepted.yaml new file mode 100644 index 0000000000000..29e342a33dcc0 --- /dev/null +++ b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/non-namespaced-gloo-accepted.yaml @@ -0,0 +1,12 @@ +apiVersion: gateway.solo.io/v1 +kind: MatchableHttpGateway +status: + reportedBy: gateway + state: 1 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 1 diff --git a/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/non-namespaced-gloo-pending.yaml b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/non-namespaced-gloo-pending.yaml new file mode 100644 index 0000000000000..f2fb7b99dbe0c --- /dev/null +++ b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/non-namespaced-gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: MatchableHttpGateway +status: + statuses: + gloo-system: + reportedBy: gateway + state: 0 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 0 diff --git a/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/non-namespaced-gloo-rejected.yaml b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/non-namespaced-gloo-rejected.yaml new file mode 100644 index 0000000000000..579e767a2e3b5 --- /dev/null +++ b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/non-namespaced-gloo-rejected.yaml @@ -0,0 +1,13 @@ +apiVersion: gateway.solo.io/v1 +kind: MatchableHttpGateway +status: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: 2 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 2 diff --git a/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/non-namespaced-gloo-warning.yaml b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/non-namespaced-gloo-warning.yaml new file mode 100644 index 0000000000000..f7f430cd4fb58 --- /dev/null +++ b/resource_customizations/gateway.solo.io/MatchableHttpGateway/testdata/non-namespaced-gloo-warning.yaml @@ -0,0 +1,13 @@ +apiVersion: gateway.solo.io/v1 +kind: MatchableHttpGateway +status: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: 3 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 3 diff --git a/resource_customizations/gateway.solo.io/RouteOption/health.lua b/resource_customizations/gateway.solo.io/RouteOption/health.lua new file mode 100644 index 0000000000000..4e0930462f38a --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteOption/health.lua @@ -0,0 +1,54 @@ +hs = { + status = "Progressing", + message = "Update in progress" +} + +function getStatus(status) + -- Accepted + if status.state == "Accepted" or status.state == 1 then + hs.status = "Healthy" + hs.message = "The resource has been validated" + return hs + end + + -- Warning + if status.state == "Warning" or status.state == 3 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + -- Pending + if status.state == "Pending" or status.state == 0 then + hs.status = "Suspended" + hs.message = "The resource has not yet been validated" + return hs + end + + -- Rejected + if status.state == "Rejected" or status.state == 2 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + return hs +end + +if obj.status ~= nil then + -- Namespaced version of status + if obj.status.statuses ~= nil then + for i, namespace in pairs(obj.status.statuses) do + hs = getStatus(namespace) + if hs.status ~= "Progressing" then + return hs + end + end + end + + -- Older non-namespaced version of status + if obj.status.state ~= nil then + hs = getStatus(obj.status) + end +end +return hs diff --git a/resource_customizations/gateway.solo.io/RouteOption/health_test.yaml b/resource_customizations/gateway.solo.io/RouteOption/health_test.yaml new file mode 100644 index 0000000000000..bd7846b5019f1 --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteOption/health_test.yaml @@ -0,0 +1,37 @@ +tests: +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/gloo-rejected.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/non-namespaced-gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/non-namespaced-gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/non-namespaced-gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/non-namespaced-gloo-rejected.yaml +- healthStatus: + status: Progressing + message: "Update in progress" + inputPath: testdata/gloo-no-status.yaml diff --git a/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-accepted.yaml b/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-accepted.yaml new file mode 100644 index 0000000000000..5d352df7fb5e9 --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-accepted.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteOption +status: + statuses: + gloo-system: + reportedBy: gateway + state: Accepted + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Accepted diff --git a/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-no-status.yaml b/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-no-status.yaml new file mode 100644 index 0000000000000..c2bae5789d605 --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-no-status.yaml @@ -0,0 +1,2 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteOption diff --git a/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-pending.yaml b/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-pending.yaml new file mode 100644 index 0000000000000..e7f4cee8f9f0a --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteOption +status: + statuses: + gloo-system: + reportedBy: gateway + state: Pending + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Pending diff --git a/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-rejected.yaml b/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-rejected.yaml new file mode 100644 index 0000000000000..b2398a860adda --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-rejected.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteOption +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: Rejected + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Rejected diff --git a/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-warning.yaml b/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-warning.yaml new file mode 100644 index 0000000000000..19d5a84153551 --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteOption/testdata/gloo-warning.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteOption +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: Warning + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Warning diff --git a/resource_customizations/gateway.solo.io/RouteOption/testdata/non-namespaced-gloo-accepted.yaml b/resource_customizations/gateway.solo.io/RouteOption/testdata/non-namespaced-gloo-accepted.yaml new file mode 100644 index 0000000000000..f39d4d7864ed9 --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteOption/testdata/non-namespaced-gloo-accepted.yaml @@ -0,0 +1,12 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteOption +status: + reportedBy: gateway + state: 1 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 1 diff --git a/resource_customizations/gateway.solo.io/RouteOption/testdata/non-namespaced-gloo-pending.yaml b/resource_customizations/gateway.solo.io/RouteOption/testdata/non-namespaced-gloo-pending.yaml new file mode 100644 index 0000000000000..5743058f17b64 --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteOption/testdata/non-namespaced-gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteOption +status: + statuses: + gloo-system: + reportedBy: gateway + state: 0 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 0 diff --git a/resource_customizations/gateway.solo.io/RouteOption/testdata/non-namespaced-gloo-rejected.yaml b/resource_customizations/gateway.solo.io/RouteOption/testdata/non-namespaced-gloo-rejected.yaml new file mode 100644 index 0000000000000..23742e2d548c3 --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteOption/testdata/non-namespaced-gloo-rejected.yaml @@ -0,0 +1,13 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteOption +status: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: 2 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 2 diff --git a/resource_customizations/gateway.solo.io/RouteOption/testdata/non-namespaced-gloo-warning.yaml b/resource_customizations/gateway.solo.io/RouteOption/testdata/non-namespaced-gloo-warning.yaml new file mode 100644 index 0000000000000..70313101a4b00 --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteOption/testdata/non-namespaced-gloo-warning.yaml @@ -0,0 +1,13 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteOption +status: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: 3 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 3 diff --git a/resource_customizations/gateway.solo.io/RouteTable/health.lua b/resource_customizations/gateway.solo.io/RouteTable/health.lua new file mode 100644 index 0000000000000..4e0930462f38a --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteTable/health.lua @@ -0,0 +1,54 @@ +hs = { + status = "Progressing", + message = "Update in progress" +} + +function getStatus(status) + -- Accepted + if status.state == "Accepted" or status.state == 1 then + hs.status = "Healthy" + hs.message = "The resource has been validated" + return hs + end + + -- Warning + if status.state == "Warning" or status.state == 3 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + -- Pending + if status.state == "Pending" or status.state == 0 then + hs.status = "Suspended" + hs.message = "The resource has not yet been validated" + return hs + end + + -- Rejected + if status.state == "Rejected" or status.state == 2 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + return hs +end + +if obj.status ~= nil then + -- Namespaced version of status + if obj.status.statuses ~= nil then + for i, namespace in pairs(obj.status.statuses) do + hs = getStatus(namespace) + if hs.status ~= "Progressing" then + return hs + end + end + end + + -- Older non-namespaced version of status + if obj.status.state ~= nil then + hs = getStatus(obj.status) + end +end +return hs diff --git a/resource_customizations/gateway.solo.io/RouteTable/health_test.yaml b/resource_customizations/gateway.solo.io/RouteTable/health_test.yaml new file mode 100644 index 0000000000000..bd7846b5019f1 --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteTable/health_test.yaml @@ -0,0 +1,37 @@ +tests: +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/gloo-rejected.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/non-namespaced-gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/non-namespaced-gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/non-namespaced-gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/non-namespaced-gloo-rejected.yaml +- healthStatus: + status: Progressing + message: "Update in progress" + inputPath: testdata/gloo-no-status.yaml diff --git a/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-accepted.yaml b/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-accepted.yaml new file mode 100644 index 0000000000000..3f63118e2a95d --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-accepted.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteTable +status: + statuses: + gloo-system: + reportedBy: gateway + state: Accepted + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Accepted diff --git a/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-no-status.yaml b/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-no-status.yaml new file mode 100644 index 0000000000000..806a4d98d3695 --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-no-status.yaml @@ -0,0 +1,2 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteTable diff --git a/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-pending.yaml b/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-pending.yaml new file mode 100644 index 0000000000000..80b3937d9de4b --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteTable +status: + statuses: + gloo-system: + reportedBy: gateway + state: Pending + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Pending diff --git a/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-rejected.yaml b/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-rejected.yaml new file mode 100644 index 0000000000000..90ff94075c164 --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-rejected.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteTable +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: Rejected + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Rejected diff --git a/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-warning.yaml b/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-warning.yaml new file mode 100644 index 0000000000000..874de924b22de --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteTable/testdata/gloo-warning.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteTable +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: Warning + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Warning diff --git a/resource_customizations/gateway.solo.io/RouteTable/testdata/non-namespaced-gloo-accepted.yaml b/resource_customizations/gateway.solo.io/RouteTable/testdata/non-namespaced-gloo-accepted.yaml new file mode 100644 index 0000000000000..76ab4680fe25d --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteTable/testdata/non-namespaced-gloo-accepted.yaml @@ -0,0 +1,12 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteTable +status: + reportedBy: gateway + state: 1 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 1 diff --git a/resource_customizations/gateway.solo.io/RouteTable/testdata/non-namespaced-gloo-pending.yaml b/resource_customizations/gateway.solo.io/RouteTable/testdata/non-namespaced-gloo-pending.yaml new file mode 100644 index 0000000000000..1acce91498614 --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteTable/testdata/non-namespaced-gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteTable +status: + statuses: + gloo-system: + reportedBy: gateway + state: 0 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 0 diff --git a/resource_customizations/gateway.solo.io/RouteTable/testdata/non-namespaced-gloo-rejected.yaml b/resource_customizations/gateway.solo.io/RouteTable/testdata/non-namespaced-gloo-rejected.yaml new file mode 100644 index 0000000000000..824dd6c808388 --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteTable/testdata/non-namespaced-gloo-rejected.yaml @@ -0,0 +1,13 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteTable +status: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: 2 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 2 diff --git a/resource_customizations/gateway.solo.io/RouteTable/testdata/non-namespaced-gloo-warning.yaml b/resource_customizations/gateway.solo.io/RouteTable/testdata/non-namespaced-gloo-warning.yaml new file mode 100644 index 0000000000000..0399ce71faf7c --- /dev/null +++ b/resource_customizations/gateway.solo.io/RouteTable/testdata/non-namespaced-gloo-warning.yaml @@ -0,0 +1,13 @@ +apiVersion: gateway.solo.io/v1 +kind: RouteTable +status: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: 3 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 3 diff --git a/resource_customizations/gateway.solo.io/VirtualHostOption/health.lua b/resource_customizations/gateway.solo.io/VirtualHostOption/health.lua new file mode 100644 index 0000000000000..4e0930462f38a --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualHostOption/health.lua @@ -0,0 +1,54 @@ +hs = { + status = "Progressing", + message = "Update in progress" +} + +function getStatus(status) + -- Accepted + if status.state == "Accepted" or status.state == 1 then + hs.status = "Healthy" + hs.message = "The resource has been validated" + return hs + end + + -- Warning + if status.state == "Warning" or status.state == 3 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + -- Pending + if status.state == "Pending" or status.state == 0 then + hs.status = "Suspended" + hs.message = "The resource has not yet been validated" + return hs + end + + -- Rejected + if status.state == "Rejected" or status.state == 2 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + return hs +end + +if obj.status ~= nil then + -- Namespaced version of status + if obj.status.statuses ~= nil then + for i, namespace in pairs(obj.status.statuses) do + hs = getStatus(namespace) + if hs.status ~= "Progressing" then + return hs + end + end + end + + -- Older non-namespaced version of status + if obj.status.state ~= nil then + hs = getStatus(obj.status) + end +end +return hs diff --git a/resource_customizations/gateway.solo.io/VirtualHostOption/health_test.yaml b/resource_customizations/gateway.solo.io/VirtualHostOption/health_test.yaml new file mode 100644 index 0000000000000..bd7846b5019f1 --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualHostOption/health_test.yaml @@ -0,0 +1,37 @@ +tests: +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/gloo-rejected.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/non-namespaced-gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/non-namespaced-gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/non-namespaced-gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/non-namespaced-gloo-rejected.yaml +- healthStatus: + status: Progressing + message: "Update in progress" + inputPath: testdata/gloo-no-status.yaml diff --git a/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-accepted.yaml b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-accepted.yaml new file mode 100644 index 0000000000000..1e90fcd65847d --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-accepted.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualHostOption +status: + statuses: + gloo-system: + reportedBy: gateway + state: Accepted + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Accepted diff --git a/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-no-status.yaml b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-no-status.yaml new file mode 100644 index 0000000000000..a2ee1a9c818b6 --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-no-status.yaml @@ -0,0 +1,2 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualHostOption diff --git a/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-pending.yaml b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-pending.yaml new file mode 100644 index 0000000000000..e9c9844a969a7 --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualHostOption +status: + statuses: + gloo-system: + reportedBy: gateway + state: Pending + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Pending diff --git a/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-rejected.yaml b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-rejected.yaml new file mode 100644 index 0000000000000..bcc19457905df --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-rejected.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualHostOption +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: Rejected + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Rejected diff --git a/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-warning.yaml b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-warning.yaml new file mode 100644 index 0000000000000..10c4112a74376 --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/gloo-warning.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualHostOption +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: Warning + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Warning diff --git a/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/non-namespaced-gloo-accepted.yaml b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/non-namespaced-gloo-accepted.yaml new file mode 100644 index 0000000000000..e204609d6c66c --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/non-namespaced-gloo-accepted.yaml @@ -0,0 +1,12 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualHostOption +status: + reportedBy: gateway + state: 1 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 1 diff --git a/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/non-namespaced-gloo-pending.yaml b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/non-namespaced-gloo-pending.yaml new file mode 100644 index 0000000000000..5fa8b8949ef9c --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/non-namespaced-gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualHostOption +status: + statuses: + gloo-system: + reportedBy: gateway + state: 0 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 0 diff --git a/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/non-namespaced-gloo-rejected.yaml b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/non-namespaced-gloo-rejected.yaml new file mode 100644 index 0000000000000..ecfca65272feb --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/non-namespaced-gloo-rejected.yaml @@ -0,0 +1,13 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualHostOption +status: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: 2 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 2 diff --git a/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/non-namespaced-gloo-warning.yaml b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/non-namespaced-gloo-warning.yaml new file mode 100644 index 0000000000000..0b02cb0856938 --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualHostOption/testdata/non-namespaced-gloo-warning.yaml @@ -0,0 +1,13 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualHostOption +status: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: 3 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 3 diff --git a/resource_customizations/gateway.solo.io/VirtualService/health.lua b/resource_customizations/gateway.solo.io/VirtualService/health.lua new file mode 100644 index 0000000000000..4e0930462f38a --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualService/health.lua @@ -0,0 +1,54 @@ +hs = { + status = "Progressing", + message = "Update in progress" +} + +function getStatus(status) + -- Accepted + if status.state == "Accepted" or status.state == 1 then + hs.status = "Healthy" + hs.message = "The resource has been validated" + return hs + end + + -- Warning + if status.state == "Warning" or status.state == 3 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + -- Pending + if status.state == "Pending" or status.state == 0 then + hs.status = "Suspended" + hs.message = "The resource has not yet been validated" + return hs + end + + -- Rejected + if status.state == "Rejected" or status.state == 2 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + return hs +end + +if obj.status ~= nil then + -- Namespaced version of status + if obj.status.statuses ~= nil then + for i, namespace in pairs(obj.status.statuses) do + hs = getStatus(namespace) + if hs.status ~= "Progressing" then + return hs + end + end + end + + -- Older non-namespaced version of status + if obj.status.state ~= nil then + hs = getStatus(obj.status) + end +end +return hs diff --git a/resource_customizations/gateway.solo.io/VirtualService/health_test.yaml b/resource_customizations/gateway.solo.io/VirtualService/health_test.yaml new file mode 100644 index 0000000000000..bd7846b5019f1 --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualService/health_test.yaml @@ -0,0 +1,37 @@ +tests: +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/gloo-rejected.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/non-namespaced-gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/non-namespaced-gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/non-namespaced-gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/non-namespaced-gloo-rejected.yaml +- healthStatus: + status: Progressing + message: "Update in progress" + inputPath: testdata/gloo-no-status.yaml diff --git a/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-accepted.yaml b/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-accepted.yaml new file mode 100644 index 0000000000000..99b339dda7c06 --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-accepted.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualService +status: + statuses: + gloo-system: + reportedBy: gateway + state: Accepted + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Accepted diff --git a/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-no-status.yaml b/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-no-status.yaml new file mode 100644 index 0000000000000..6567086648737 --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-no-status.yaml @@ -0,0 +1,2 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualService diff --git a/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-pending.yaml b/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-pending.yaml new file mode 100644 index 0000000000000..f3a31057d4299 --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualService +status: + statuses: + gloo-system: + reportedBy: gateway + state: Pending + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Pending diff --git a/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-rejected.yaml b/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-rejected.yaml new file mode 100644 index 0000000000000..47575747ac596 --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-rejected.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualService +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: Rejected + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Rejected diff --git a/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-warning.yaml b/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-warning.yaml new file mode 100644 index 0000000000000..27ba16faa5f2c --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualService/testdata/gloo-warning.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualService +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: Warning + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Warning diff --git a/resource_customizations/gateway.solo.io/VirtualService/testdata/non-namespaced-gloo-accepted.yaml b/resource_customizations/gateway.solo.io/VirtualService/testdata/non-namespaced-gloo-accepted.yaml new file mode 100644 index 0000000000000..7606a02c7a1f8 --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualService/testdata/non-namespaced-gloo-accepted.yaml @@ -0,0 +1,12 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualService +status: + reportedBy: gateway + state: 1 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 1 diff --git a/resource_customizations/gateway.solo.io/VirtualService/testdata/non-namespaced-gloo-pending.yaml b/resource_customizations/gateway.solo.io/VirtualService/testdata/non-namespaced-gloo-pending.yaml new file mode 100644 index 0000000000000..1e8f4dc517be4 --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualService/testdata/non-namespaced-gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualService +status: + statuses: + gloo-system: + reportedBy: gateway + state: 0 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 0 diff --git a/resource_customizations/gateway.solo.io/VirtualService/testdata/non-namespaced-gloo-rejected.yaml b/resource_customizations/gateway.solo.io/VirtualService/testdata/non-namespaced-gloo-rejected.yaml new file mode 100644 index 0000000000000..a3f204753a6f2 --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualService/testdata/non-namespaced-gloo-rejected.yaml @@ -0,0 +1,13 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualService +status: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: 2 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 2 diff --git a/resource_customizations/gateway.solo.io/VirtualService/testdata/non-namespaced-gloo-warning.yaml b/resource_customizations/gateway.solo.io/VirtualService/testdata/non-namespaced-gloo-warning.yaml new file mode 100644 index 0000000000000..1c641e62b190d --- /dev/null +++ b/resource_customizations/gateway.solo.io/VirtualService/testdata/non-namespaced-gloo-warning.yaml @@ -0,0 +1,13 @@ +apiVersion: gateway.solo.io/v1 +kind: VirtualService +status: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: 3 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 3 diff --git a/resource_customizations/gloo.solo.io/Proxy/health.lua b/resource_customizations/gloo.solo.io/Proxy/health.lua new file mode 100644 index 0000000000000..4e0930462f38a --- /dev/null +++ b/resource_customizations/gloo.solo.io/Proxy/health.lua @@ -0,0 +1,54 @@ +hs = { + status = "Progressing", + message = "Update in progress" +} + +function getStatus(status) + -- Accepted + if status.state == "Accepted" or status.state == 1 then + hs.status = "Healthy" + hs.message = "The resource has been validated" + return hs + end + + -- Warning + if status.state == "Warning" or status.state == 3 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + -- Pending + if status.state == "Pending" or status.state == 0 then + hs.status = "Suspended" + hs.message = "The resource has not yet been validated" + return hs + end + + -- Rejected + if status.state == "Rejected" or status.state == 2 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + return hs +end + +if obj.status ~= nil then + -- Namespaced version of status + if obj.status.statuses ~= nil then + for i, namespace in pairs(obj.status.statuses) do + hs = getStatus(namespace) + if hs.status ~= "Progressing" then + return hs + end + end + end + + -- Older non-namespaced version of status + if obj.status.state ~= nil then + hs = getStatus(obj.status) + end +end +return hs diff --git a/resource_customizations/gloo.solo.io/Proxy/health_test.yaml b/resource_customizations/gloo.solo.io/Proxy/health_test.yaml new file mode 100644 index 0000000000000..bd7846b5019f1 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Proxy/health_test.yaml @@ -0,0 +1,37 @@ +tests: +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/gloo-rejected.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/non-namespaced-gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/non-namespaced-gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/non-namespaced-gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/non-namespaced-gloo-rejected.yaml +- healthStatus: + status: Progressing + message: "Update in progress" + inputPath: testdata/gloo-no-status.yaml diff --git a/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-accepted.yaml b/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-accepted.yaml new file mode 100644 index 0000000000000..1a33b9dedeb7d --- /dev/null +++ b/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-accepted.yaml @@ -0,0 +1,14 @@ +apiVersion: gloo.solo.io/v1 +kind: Proxy +status: + statuses: + gloo-system: + reportedBy: gateway + state: Accepted + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Accepted diff --git a/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-no-status.yaml b/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-no-status.yaml new file mode 100644 index 0000000000000..5354698cf4acf --- /dev/null +++ b/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-no-status.yaml @@ -0,0 +1,2 @@ +apiVersion: gloo.solo.io/v1 +kind: Proxy diff --git a/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-pending.yaml b/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-pending.yaml new file mode 100644 index 0000000000000..8497064ec18ae --- /dev/null +++ b/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gloo.solo.io/v1 +kind: Proxy +status: + statuses: + gloo-system: + reportedBy: gateway + state: Pending + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Pending diff --git a/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-rejected.yaml b/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-rejected.yaml new file mode 100644 index 0000000000000..e93acfec72c47 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-rejected.yaml @@ -0,0 +1,15 @@ +apiVersion: gloo.solo.io/v1 +kind: Proxy +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: Rejected + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Rejected diff --git a/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-warning.yaml b/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-warning.yaml new file mode 100644 index 0000000000000..a65c3fa4957b1 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Proxy/testdata/gloo-warning.yaml @@ -0,0 +1,15 @@ +apiVersion: gloo.solo.io/v1 +kind: Proxy +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: Warning + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Warning diff --git a/resource_customizations/gloo.solo.io/Proxy/testdata/non-namespaced-gloo-accepted.yaml b/resource_customizations/gloo.solo.io/Proxy/testdata/non-namespaced-gloo-accepted.yaml new file mode 100644 index 0000000000000..dff6082232fa5 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Proxy/testdata/non-namespaced-gloo-accepted.yaml @@ -0,0 +1,12 @@ +apiVersion: gloo.solo.io/v1 +kind: Proxy +status: + reportedBy: gateway + state: 1 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 1 diff --git a/resource_customizations/gloo.solo.io/Proxy/testdata/non-namespaced-gloo-pending.yaml b/resource_customizations/gloo.solo.io/Proxy/testdata/non-namespaced-gloo-pending.yaml new file mode 100644 index 0000000000000..49afeb8e4be83 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Proxy/testdata/non-namespaced-gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gloo.solo.io/v1 +kind: Proxy +status: + statuses: + gloo-system: + reportedBy: gateway + state: 0 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 0 diff --git a/resource_customizations/gloo.solo.io/Proxy/testdata/non-namespaced-gloo-rejected.yaml b/resource_customizations/gloo.solo.io/Proxy/testdata/non-namespaced-gloo-rejected.yaml new file mode 100644 index 0000000000000..0f7ec50212811 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Proxy/testdata/non-namespaced-gloo-rejected.yaml @@ -0,0 +1,13 @@ +apiVersion: gloo.solo.io/v1 +kind: Proxy +status: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: 2 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 2 diff --git a/resource_customizations/gloo.solo.io/Proxy/testdata/non-namespaced-gloo-warning.yaml b/resource_customizations/gloo.solo.io/Proxy/testdata/non-namespaced-gloo-warning.yaml new file mode 100644 index 0000000000000..cabff991640bb --- /dev/null +++ b/resource_customizations/gloo.solo.io/Proxy/testdata/non-namespaced-gloo-warning.yaml @@ -0,0 +1,13 @@ +apiVersion: gloo.solo.io/v1 +kind: Proxy +status: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: 3 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 3 diff --git a/resource_customizations/gloo.solo.io/Settings/health.lua b/resource_customizations/gloo.solo.io/Settings/health.lua new file mode 100644 index 0000000000000..4e0930462f38a --- /dev/null +++ b/resource_customizations/gloo.solo.io/Settings/health.lua @@ -0,0 +1,54 @@ +hs = { + status = "Progressing", + message = "Update in progress" +} + +function getStatus(status) + -- Accepted + if status.state == "Accepted" or status.state == 1 then + hs.status = "Healthy" + hs.message = "The resource has been validated" + return hs + end + + -- Warning + if status.state == "Warning" or status.state == 3 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + -- Pending + if status.state == "Pending" or status.state == 0 then + hs.status = "Suspended" + hs.message = "The resource has not yet been validated" + return hs + end + + -- Rejected + if status.state == "Rejected" or status.state == 2 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + return hs +end + +if obj.status ~= nil then + -- Namespaced version of status + if obj.status.statuses ~= nil then + for i, namespace in pairs(obj.status.statuses) do + hs = getStatus(namespace) + if hs.status ~= "Progressing" then + return hs + end + end + end + + -- Older non-namespaced version of status + if obj.status.state ~= nil then + hs = getStatus(obj.status) + end +end +return hs diff --git a/resource_customizations/gloo.solo.io/Settings/health_test.yaml b/resource_customizations/gloo.solo.io/Settings/health_test.yaml new file mode 100644 index 0000000000000..bd7846b5019f1 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Settings/health_test.yaml @@ -0,0 +1,37 @@ +tests: +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/gloo-rejected.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/non-namespaced-gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/non-namespaced-gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/non-namespaced-gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/non-namespaced-gloo-rejected.yaml +- healthStatus: + status: Progressing + message: "Update in progress" + inputPath: testdata/gloo-no-status.yaml diff --git a/resource_customizations/gloo.solo.io/Settings/testdata/gloo-accepted.yaml b/resource_customizations/gloo.solo.io/Settings/testdata/gloo-accepted.yaml new file mode 100644 index 0000000000000..968a56607561c --- /dev/null +++ b/resource_customizations/gloo.solo.io/Settings/testdata/gloo-accepted.yaml @@ -0,0 +1,14 @@ +apiVersion: gloo.solo.io/v1 +kind: Settings +status: + statuses: + gloo-system: + reportedBy: gateway + state: Accepted + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Accepted diff --git a/resource_customizations/gloo.solo.io/Settings/testdata/gloo-no-status.yaml b/resource_customizations/gloo.solo.io/Settings/testdata/gloo-no-status.yaml new file mode 100644 index 0000000000000..82726a6c3099b --- /dev/null +++ b/resource_customizations/gloo.solo.io/Settings/testdata/gloo-no-status.yaml @@ -0,0 +1,2 @@ +apiVersion: gloo.solo.io/v1 +kind: Settings diff --git a/resource_customizations/gloo.solo.io/Settings/testdata/gloo-pending.yaml b/resource_customizations/gloo.solo.io/Settings/testdata/gloo-pending.yaml new file mode 100644 index 0000000000000..bcfbd8a25a2da --- /dev/null +++ b/resource_customizations/gloo.solo.io/Settings/testdata/gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gloo.solo.io/v1 +kind: Settings +status: + statuses: + gloo-system: + reportedBy: gateway + state: Pending + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Pending diff --git a/resource_customizations/gloo.solo.io/Settings/testdata/gloo-rejected.yaml b/resource_customizations/gloo.solo.io/Settings/testdata/gloo-rejected.yaml new file mode 100644 index 0000000000000..004ecf1ef4b14 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Settings/testdata/gloo-rejected.yaml @@ -0,0 +1,15 @@ +apiVersion: gloo.solo.io/v1 +kind: Settings +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: Rejected + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Rejected diff --git a/resource_customizations/gloo.solo.io/Settings/testdata/gloo-warning.yaml b/resource_customizations/gloo.solo.io/Settings/testdata/gloo-warning.yaml new file mode 100644 index 0000000000000..d42784551beb4 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Settings/testdata/gloo-warning.yaml @@ -0,0 +1,15 @@ +apiVersion: gloo.solo.io/v1 +kind: Settings +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: Warning + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Warning diff --git a/resource_customizations/gloo.solo.io/Settings/testdata/non-namespaced-gloo-accepted.yaml b/resource_customizations/gloo.solo.io/Settings/testdata/non-namespaced-gloo-accepted.yaml new file mode 100644 index 0000000000000..99ff0026b4ade --- /dev/null +++ b/resource_customizations/gloo.solo.io/Settings/testdata/non-namespaced-gloo-accepted.yaml @@ -0,0 +1,12 @@ +apiVersion: gloo.solo.io/v1 +kind: Settings +status: + reportedBy: gateway + state: 1 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 1 diff --git a/resource_customizations/gloo.solo.io/Settings/testdata/non-namespaced-gloo-pending.yaml b/resource_customizations/gloo.solo.io/Settings/testdata/non-namespaced-gloo-pending.yaml new file mode 100644 index 0000000000000..fdec14fa04a6c --- /dev/null +++ b/resource_customizations/gloo.solo.io/Settings/testdata/non-namespaced-gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gloo.solo.io/v1 +kind: Settings +status: + statuses: + gloo-system: + reportedBy: gateway + state: 0 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 0 diff --git a/resource_customizations/gloo.solo.io/Settings/testdata/non-namespaced-gloo-rejected.yaml b/resource_customizations/gloo.solo.io/Settings/testdata/non-namespaced-gloo-rejected.yaml new file mode 100644 index 0000000000000..5e62178cd182d --- /dev/null +++ b/resource_customizations/gloo.solo.io/Settings/testdata/non-namespaced-gloo-rejected.yaml @@ -0,0 +1,13 @@ +apiVersion: gloo.solo.io/v1 +kind: Settings +status: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: 2 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 2 diff --git a/resource_customizations/gloo.solo.io/Settings/testdata/non-namespaced-gloo-warning.yaml b/resource_customizations/gloo.solo.io/Settings/testdata/non-namespaced-gloo-warning.yaml new file mode 100644 index 0000000000000..26ddf57424eea --- /dev/null +++ b/resource_customizations/gloo.solo.io/Settings/testdata/non-namespaced-gloo-warning.yaml @@ -0,0 +1,13 @@ +apiVersion: gloo.solo.io/v1 +kind: Settings +status: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: 3 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 3 diff --git a/resource_customizations/gloo.solo.io/Upstream/health.lua b/resource_customizations/gloo.solo.io/Upstream/health.lua new file mode 100644 index 0000000000000..4e0930462f38a --- /dev/null +++ b/resource_customizations/gloo.solo.io/Upstream/health.lua @@ -0,0 +1,54 @@ +hs = { + status = "Progressing", + message = "Update in progress" +} + +function getStatus(status) + -- Accepted + if status.state == "Accepted" or status.state == 1 then + hs.status = "Healthy" + hs.message = "The resource has been validated" + return hs + end + + -- Warning + if status.state == "Warning" or status.state == 3 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + -- Pending + if status.state == "Pending" or status.state == 0 then + hs.status = "Suspended" + hs.message = "The resource has not yet been validated" + return hs + end + + -- Rejected + if status.state == "Rejected" or status.state == 2 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + return hs +end + +if obj.status ~= nil then + -- Namespaced version of status + if obj.status.statuses ~= nil then + for i, namespace in pairs(obj.status.statuses) do + hs = getStatus(namespace) + if hs.status ~= "Progressing" then + return hs + end + end + end + + -- Older non-namespaced version of status + if obj.status.state ~= nil then + hs = getStatus(obj.status) + end +end +return hs diff --git a/resource_customizations/gloo.solo.io/Upstream/health_test.yaml b/resource_customizations/gloo.solo.io/Upstream/health_test.yaml new file mode 100644 index 0000000000000..bd7846b5019f1 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Upstream/health_test.yaml @@ -0,0 +1,37 @@ +tests: +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/gloo-rejected.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/non-namespaced-gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/non-namespaced-gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/non-namespaced-gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/non-namespaced-gloo-rejected.yaml +- healthStatus: + status: Progressing + message: "Update in progress" + inputPath: testdata/gloo-no-status.yaml diff --git a/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-accepted.yaml b/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-accepted.yaml new file mode 100644 index 0000000000000..b0094f46d8d2a --- /dev/null +++ b/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-accepted.yaml @@ -0,0 +1,14 @@ +apiVersion: gloo.solo.io/v1 +kind: Upstream +status: + statuses: + gloo-system: + reportedBy: gateway + state: Accepted + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Accepted diff --git a/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-no-status.yaml b/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-no-status.yaml new file mode 100644 index 0000000000000..b68a5e16b03be --- /dev/null +++ b/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-no-status.yaml @@ -0,0 +1,2 @@ +apiVersion: gloo.solo.io/v1 +kind: Upstream diff --git a/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-pending.yaml b/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-pending.yaml new file mode 100644 index 0000000000000..bef8b9eef9b88 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gloo.solo.io/v1 +kind: Upstream +status: + statuses: + gloo-system: + reportedBy: gateway + state: Pending + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Pending diff --git a/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-rejected.yaml b/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-rejected.yaml new file mode 100644 index 0000000000000..02cef224d46bd --- /dev/null +++ b/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-rejected.yaml @@ -0,0 +1,15 @@ +apiVersion: gloo.solo.io/v1 +kind: Upstream +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: Rejected + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Rejected diff --git a/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-warning.yaml b/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-warning.yaml new file mode 100644 index 0000000000000..359e27871ba15 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Upstream/testdata/gloo-warning.yaml @@ -0,0 +1,15 @@ +apiVersion: gloo.solo.io/v1 +kind: Upstream +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: Warning + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Warning diff --git a/resource_customizations/gloo.solo.io/Upstream/testdata/non-namespaced-gloo-accepted.yaml b/resource_customizations/gloo.solo.io/Upstream/testdata/non-namespaced-gloo-accepted.yaml new file mode 100644 index 0000000000000..85a792fc0b37f --- /dev/null +++ b/resource_customizations/gloo.solo.io/Upstream/testdata/non-namespaced-gloo-accepted.yaml @@ -0,0 +1,12 @@ +apiVersion: gloo.solo.io/v1 +kind: Upstream +status: + reportedBy: gateway + state: 1 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 1 diff --git a/resource_customizations/gloo.solo.io/Upstream/testdata/non-namespaced-gloo-pending.yaml b/resource_customizations/gloo.solo.io/Upstream/testdata/non-namespaced-gloo-pending.yaml new file mode 100644 index 0000000000000..ec29ff4967bd1 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Upstream/testdata/non-namespaced-gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gloo.solo.io/v1 +kind: Upstream +status: + statuses: + gloo-system: + reportedBy: gateway + state: 0 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 0 diff --git a/resource_customizations/gloo.solo.io/Upstream/testdata/non-namespaced-gloo-rejected.yaml b/resource_customizations/gloo.solo.io/Upstream/testdata/non-namespaced-gloo-rejected.yaml new file mode 100644 index 0000000000000..7779628abf3b9 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Upstream/testdata/non-namespaced-gloo-rejected.yaml @@ -0,0 +1,13 @@ +apiVersion: gloo.solo.io/v1 +kind: Upstream +status: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: 2 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 2 diff --git a/resource_customizations/gloo.solo.io/Upstream/testdata/non-namespaced-gloo-warning.yaml b/resource_customizations/gloo.solo.io/Upstream/testdata/non-namespaced-gloo-warning.yaml new file mode 100644 index 0000000000000..8f170e814adf9 --- /dev/null +++ b/resource_customizations/gloo.solo.io/Upstream/testdata/non-namespaced-gloo-warning.yaml @@ -0,0 +1,13 @@ +apiVersion: gloo.solo.io/v1 +kind: Upstream +status: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: 3 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 3 diff --git a/resource_customizations/gloo.solo.io/UpstreamGroup/health.lua b/resource_customizations/gloo.solo.io/UpstreamGroup/health.lua new file mode 100644 index 0000000000000..4e0930462f38a --- /dev/null +++ b/resource_customizations/gloo.solo.io/UpstreamGroup/health.lua @@ -0,0 +1,54 @@ +hs = { + status = "Progressing", + message = "Update in progress" +} + +function getStatus(status) + -- Accepted + if status.state == "Accepted" or status.state == 1 then + hs.status = "Healthy" + hs.message = "The resource has been validated" + return hs + end + + -- Warning + if status.state == "Warning" or status.state == 3 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + -- Pending + if status.state == "Pending" or status.state == 0 then + hs.status = "Suspended" + hs.message = "The resource has not yet been validated" + return hs + end + + -- Rejected + if status.state == "Rejected" or status.state == 2 then + hs.status = "Degraded" + hs.message = status.reason + return hs + end + + return hs +end + +if obj.status ~= nil then + -- Namespaced version of status + if obj.status.statuses ~= nil then + for i, namespace in pairs(obj.status.statuses) do + hs = getStatus(namespace) + if hs.status ~= "Progressing" then + return hs + end + end + end + + -- Older non-namespaced version of status + if obj.status.state ~= nil then + hs = getStatus(obj.status) + end +end +return hs diff --git a/resource_customizations/gloo.solo.io/UpstreamGroup/health_test.yaml b/resource_customizations/gloo.solo.io/UpstreamGroup/health_test.yaml new file mode 100644 index 0000000000000..bd7846b5019f1 --- /dev/null +++ b/resource_customizations/gloo.solo.io/UpstreamGroup/health_test.yaml @@ -0,0 +1,37 @@ +tests: +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/gloo-rejected.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for warning" + inputPath: testdata/non-namespaced-gloo-warning.yaml +- healthStatus: + status: Suspended + message: "The resource has not yet been validated" + inputPath: testdata/non-namespaced-gloo-pending.yaml +- healthStatus: + status: Healthy + message: "The resource has been validated" + inputPath: testdata/non-namespaced-gloo-accepted.yaml +- healthStatus: + status: Degraded + message: "message that will describe all the reasons for rejection" + inputPath: testdata/non-namespaced-gloo-rejected.yaml +- healthStatus: + status: Progressing + message: "Update in progress" + inputPath: testdata/gloo-no-status.yaml diff --git a/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-accepted.yaml b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-accepted.yaml new file mode 100644 index 0000000000000..90a4023ce60cf --- /dev/null +++ b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-accepted.yaml @@ -0,0 +1,14 @@ +apiVersion: gloo.solo.io/v1 +kind: UpstreamGroup +status: + statuses: + gloo-system: + reportedBy: gateway + state: Accepted + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Accepted diff --git a/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-no-status.yaml b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-no-status.yaml new file mode 100644 index 0000000000000..45f71721283b5 --- /dev/null +++ b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-no-status.yaml @@ -0,0 +1,2 @@ +apiVersion: gloo.solo.io/v1 +kind: UpstreamGroup diff --git a/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-pending.yaml b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-pending.yaml new file mode 100644 index 0000000000000..76f8a8d227567 --- /dev/null +++ b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gloo.solo.io/v1 +kind: UpstreamGroup +status: + statuses: + gloo-system: + reportedBy: gateway + state: Pending + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Pending diff --git a/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-rejected.yaml b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-rejected.yaml new file mode 100644 index 0000000000000..e66fa5a7e67fd --- /dev/null +++ b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-rejected.yaml @@ -0,0 +1,15 @@ +apiVersion: gloo.solo.io/v1 +kind: UpstreamGroup +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: Rejected + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Rejected diff --git a/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-warning.yaml b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-warning.yaml new file mode 100644 index 0000000000000..b7c550394341f --- /dev/null +++ b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/gloo-warning.yaml @@ -0,0 +1,15 @@ +apiVersion: gloo.solo.io/v1 +kind: UpstreamGroup +status: + statuses: + gloo-system: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: Warning + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: Accepted + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: Warning diff --git a/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/non-namespaced-gloo-accepted.yaml b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/non-namespaced-gloo-accepted.yaml new file mode 100644 index 0000000000000..63e8dd8af6bbc --- /dev/null +++ b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/non-namespaced-gloo-accepted.yaml @@ -0,0 +1,12 @@ +apiVersion: gloo.solo.io/v1 +kind: UpstreamGroup +status: + reportedBy: gateway + state: 1 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 1 diff --git a/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/non-namespaced-gloo-pending.yaml b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/non-namespaced-gloo-pending.yaml new file mode 100644 index 0000000000000..b1367f520f824 --- /dev/null +++ b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/non-namespaced-gloo-pending.yaml @@ -0,0 +1,14 @@ +apiVersion: gloo.solo.io/v1 +kind: UpstreamGroup +status: + statuses: + gloo-system: + reportedBy: gateway + state: 0 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 0 diff --git a/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/non-namespaced-gloo-rejected.yaml b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/non-namespaced-gloo-rejected.yaml new file mode 100644 index 0000000000000..7c4312539bc78 --- /dev/null +++ b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/non-namespaced-gloo-rejected.yaml @@ -0,0 +1,13 @@ +apiVersion: gloo.solo.io/v1 +kind: UpstreamGroup +status: + reason: "message that will describe all the reasons for rejection" + reportedBy: gateway + state: 2 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 2 diff --git a/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/non-namespaced-gloo-warning.yaml b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/non-namespaced-gloo-warning.yaml new file mode 100644 index 0000000000000..319e1bc6645b7 --- /dev/null +++ b/resource_customizations/gloo.solo.io/UpstreamGroup/testdata/non-namespaced-gloo-warning.yaml @@ -0,0 +1,13 @@ +apiVersion: gloo.solo.io/v1 +kind: UpstreamGroup +status: + reason: "message that will describe all the reasons for warning" + reportedBy: gateway + state: 3 + subresourceStatuses: + '*v1.Proxy.gateway-proxy_gloo-system': + reportedBy: gloo + state: 1 + '*v1.Proxy.internal-proxy_gloo-system': + reportedBy: gloo + state: 3 diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/action_test.yaml b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/action_test.yaml new file mode 100644 index 0000000000000..1831eb389cb24 --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/action_test.yaml @@ -0,0 +1,35 @@ +discoveryTests: +- inputPath: testdata/initial_helmrelease.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +- inputPath: testdata/suspended_helmrelease.yaml + result: + - name: reconcile + disabled: true + - name: suspend + disabled: true + - name: resume + disabled: false +- inputPath: testdata/resumed_helmrelease.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +actionTests: +- action: reconcile + inputPath: testdata/initial_helmrelease.yaml + expectedOutputPath: testdata/reconciled_helmrelease.yaml +- action: suspend + inputPath: testdata/initial_helmrelease.yaml + expectedOutputPath: testdata/suspended_helmrelease.yaml +- action: resume + inputPath: testdata/suspended_helmrelease.yaml + expectedOutputPath: testdata/resumed_helmrelease.yaml diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/discovery.lua b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/discovery.lua new file mode 100644 index 0000000000000..9000998815515 --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/discovery.lua @@ -0,0 +1,18 @@ +local actions = {} + +actions["reconcile"] = {["disabled"] = true} +actions["suspend"] = {["disabled"] = true} +actions["resume"] = {["disabled"] = true} + +local suspend = false +if obj.spec.suspend ~= nil then + suspend = obj.spec.suspend +end +if suspend then + actions["resume"]["disabled"] = false +else + actions["reconcile"]["disabled"] = false + actions["suspend"]["disabled"] = false +end + +return actions diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/reconcile/action.lua b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/reconcile/action.lua new file mode 100644 index 0000000000000..a534b36fb3ebc --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/reconcile/action.lua @@ -0,0 +1,7 @@ +local os = require("os") +if obj.metadata.annotations == nil then + obj.metadata.annotations = {} +end +obj.metadata.annotations["reconcile.fluxcd.io/requestedAt"] = "By Argo CD at: " .. os.date("!%Y-%m-%dT%X") + +return obj diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/resume/action.lua b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/resume/action.lua new file mode 100644 index 0000000000000..cb41993777699 --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/resume/action.lua @@ -0,0 +1,5 @@ +if obj.spec.suspend ~= nil and obj.spec.suspend then + obj.spec.suspend = false +end + +return obj diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/suspend/action.lua b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/suspend/action.lua new file mode 100644 index 0000000000000..1a338b2ad1361 --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/suspend/action.lua @@ -0,0 +1,3 @@ +obj.spec.suspend = true + +return obj diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/testdata/initial_helmrelease.yaml b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/testdata/initial_helmrelease.yaml new file mode 100644 index 0000000000000..a5be419c51dc7 --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/testdata/initial_helmrelease.yaml @@ -0,0 +1,33 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: podinfo + namespace: default +spec: + interval: 10m + timeout: 5m + chart: + spec: + chart: podinfo + version: '6.5.*' + sourceRef: + kind: HelmRepository + name: podinfo + interval: 5m + releaseName: podinfo + install: + remediation: + retries: 3 + upgrade: + remediation: + retries: 3 + test: + enable: true + driftDetection: + mode: enabled + ignore: + - paths: ["/spec/replicas"] + target: + kind: Deployment + values: + replicaCount: 2 diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/testdata/reconciled_helmrelease.yaml b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/testdata/reconciled_helmrelease.yaml new file mode 100644 index 0000000000000..89eb46c511eb1 --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/testdata/reconciled_helmrelease.yaml @@ -0,0 +1,35 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: podinfo + namespace: default + annotations: + reconcile.fluxcd.io/requestedAt: 'By Argo CD at: 0001-01-01T00:00:00' +spec: + interval: 10m + timeout: 5m + chart: + spec: + chart: podinfo + version: '6.5.*' + sourceRef: + kind: HelmRepository + name: podinfo + interval: 5m + releaseName: podinfo + install: + remediation: + retries: 3 + upgrade: + remediation: + retries: 3 + test: + enable: true + driftDetection: + mode: enabled + ignore: + - paths: ["/spec/replicas"] + target: + kind: Deployment + values: + replicaCount: 2 diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/testdata/resumed_helmrelease.yaml b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/testdata/resumed_helmrelease.yaml new file mode 100644 index 0000000000000..84988820ada9f --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/testdata/resumed_helmrelease.yaml @@ -0,0 +1,34 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: podinfo + namespace: default +spec: + interval: 10m + timeout: 5m + chart: + spec: + chart: podinfo + version: '6.5.*' + sourceRef: + kind: HelmRepository + name: podinfo + interval: 5m + releaseName: podinfo + install: + remediation: + retries: 3 + upgrade: + remediation: + retries: 3 + test: + enable: true + suspend: false + driftDetection: + mode: enabled + ignore: + - paths: ["/spec/replicas"] + target: + kind: Deployment + values: + replicaCount: 2 diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/testdata/suspended_helmrelease.yaml b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/testdata/suspended_helmrelease.yaml new file mode 100644 index 0000000000000..21e46d51751a3 --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/actions/testdata/suspended_helmrelease.yaml @@ -0,0 +1,34 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: podinfo + namespace: default +spec: + interval: 10m + timeout: 5m + chart: + spec: + chart: podinfo + version: '6.5.*' + sourceRef: + kind: HelmRepository + name: podinfo + interval: 5m + releaseName: podinfo + install: + remediation: + retries: 3 + upgrade: + remediation: + retries: 3 + test: + enable: true + suspend: true + driftDetection: + mode: enabled + ignore: + - paths: ["/spec/replicas"] + target: + kind: Deployment + values: + replicaCount: 2 diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/health.lua b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/health.lua new file mode 100644 index 0000000000000..dd062f92e7143 --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/health.lua @@ -0,0 +1,45 @@ +local hs = {} +if obj.spec.suspend ~= nil and obj.spec.suspend == true then + hs.message = obj.kind .. " is suspended" + hs.status = "Suspended" + return hs +end +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local numProgressing = 0 + local numSucceeded = 0 + local message = "" + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + if condition.status == "True" then + numSucceeded = numSucceeded + 1 + elseif condition.status == "Unknown" then + numProgressing = numProgressing + 1 + end + message = condition.reason + elseif condition.type == "Reconciling" and condition.status == "True" then + numProgressing = numProgressing + 1 + elseif condition.type == "Released" or condition.type == "TestSuccess" then + if condition.status == "True" then + numSucceeded = numSucceeded + 1 + end + end + end + if(numProgressing == 2) then + hs.message = message + hs.status = "Progressing" + return hs + elseif(numSucceeded == 2) then + hs.message = message + hs.status = "Healthy" + return hs + else + hs.message = message + hs.status = "Degraded" + return hs + end + end +end +hs.message = "Status unknown" +hs.status = "Progressing" +return hs diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/health_test.yaml b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/health_test.yaml new file mode 100644 index 0000000000000..64fce9951d5ba --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/health_test.yaml @@ -0,0 +1,13 @@ +tests: + - healthStatus: + status: Progressing + message: Progressing + inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: RollbackSucceeded + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: InstallSucceeded + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/testdata/degraded.yaml b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/testdata/degraded.yaml new file mode 100644 index 0000000000000..c5986d6cfc507 --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/testdata/degraded.yaml @@ -0,0 +1,70 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: podinfo + namespace: default +spec: + interval: 10m + timeout: 5m + chart: + spec: + chart: podinfo + version: '6.5.*' + sourceRef: + kind: HelmRepository + name: podinfo + interval: 5m + releaseName: podinfo + install: + remediation: + retries: 3 + upgrade: + remediation: + retries: 3 + test: + enable: true + driftDetection: + mode: enabled + ignore: + - paths: ["/spec/replicas"] + target: + kind: Deployment + values: + replicaCount: 2 +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Helm rollback to previous release default/podinfo.v24 with + chart podinfo@6.5.4 succeeded + observedGeneration: 5 + reason: ProgressingWithRetry + status: "True" + type: Reconciling + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Helm rollback to previous release default/podinfo.v24 with + chart podinfo@6.5.4 succeeded + observedGeneration: 5 + reason: RollbackSucceeded + status: "False" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: "Helm upgrade failed for release default/podinfo with chart + podinfo@6.5.4: cannot patch \"podinfo\" with kind Deployment: admission webhook + \"validate.kyverno.svc-fail\" denied the request: \n\nresource Deployment/default/podinfo + was blocked due to the following policies \n\ndisallow-privilege-escalation:\n + \ autogen-privilege-escalation: 'validation error: Privilege escalation is disallowed.\n + \ The fields spec.containers[*].securityContext.allowPrivilegeEscalation, + spec.initContainers[*].securityContext.allowPrivilegeEscalation,\n and spec.ephemeralContainers[*].securityContext.allowPrivilegeEscalation + must\n be set to `false`. rule autogen-privilege-escalation failed at path + /spec/template/spec/containers/0/securityContext/allowPrivilegeEscalation/'" + observedGeneration: 5 + reason: UpgradeFailed + status: "False" + type: Released + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Helm rollback to previous release default/podinfo.v24 with + chart podinfo@6.5.4 succeeded + observedGeneration: 5 + reason: RollbackSucceeded + status: "True" + type: Remediated diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/testdata/healthy.yaml b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/testdata/healthy.yaml new file mode 100644 index 0000000000000..f76ca38f23a09 --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/testdata/healthy.yaml @@ -0,0 +1,49 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: podinfo + namespace: default +spec: + interval: 10m + timeout: 5m + chart: + spec: + chart: podinfo + version: '6.5.*' + sourceRef: + kind: HelmRepository + name: podinfo + interval: 5m + releaseName: podinfo + install: + remediation: + retries: 3 + upgrade: + remediation: + retries: 3 + test: + enable: true + driftDetection: + mode: enabled + ignore: + - paths: ["/spec/replicas"] + target: + kind: Deployment + values: + replicaCount: 2 +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Helm install succeeded for release default/podinfo.v1 with + chart podinfo@6.5.4 + observedGeneration: 2 + reason: InstallSucceeded + status: "True" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Helm install succeeded for release default/podinfo.v1 with + chart podinfo@6.5.4 + observedGeneration: 1 + reason: InstallSucceeded + status: "True" + type: Released diff --git a/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/testdata/progressing.yaml b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/testdata/progressing.yaml new file mode 100644 index 0000000000000..f6653b2139526 --- /dev/null +++ b/resource_customizations/helm.toolkit.fluxcd.io/HelmRelease/testdata/progressing.yaml @@ -0,0 +1,54 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: podinfo + namespace: default +spec: + interval: 10m + timeout: 5m + chart: + spec: + chart: podinfo + version: '6.5.*' + sourceRef: + kind: HelmRepository + name: podinfo + interval: 5m + releaseName: podinfo + install: + remediation: + retries: 3 + upgrade: + remediation: + retries: 3 + test: + enable: true + driftDetection: + mode: enabled + ignore: + - paths: ["/spec/replicas"] + target: + kind: Deployment + values: + replicaCount: 2 +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Running 'upgrade' action with timeout of 5m0s + observedGeneration: 3 + reason: Progressing + status: "True" + type: Reconciling + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Running 'upgrade' action with timeout of 5m0s + observedGeneration: 3 + reason: Progressing + status: Unknown + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Helm install succeeded for release default/podinfo.v1 with + chart podinfo@6.5.4 + observedGeneration: 1 + reason: InstallSucceeded + status: "True" + type: Released diff --git a/resource_customizations/iam.aws.crossplane.io/Policy/health.lua b/resource_customizations/iam.aws.crossplane.io/Policy/health.lua new file mode 100644 index 0000000000000..70af5cb9570c0 --- /dev/null +++ b/resource_customizations/iam.aws.crossplane.io/Policy/health.lua @@ -0,0 +1,41 @@ +local hs = {} +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local ready = false + local synced = false + local suspended = false + for i, condition in ipairs(obj.status.conditions) do + + if condition.type == "Ready" then + ready = condition.status == "True" + ready_message = condition.reason + elseif condition.type == "Synced" then + synced = condition.status == "True" + if condition.reason == "ReconcileError" then + synced_message = condition.message + elseif condition.reason == "ReconcilePaused" then + suspended = true + suspended_message = condition.reason + end + end + end + if ready and synced then + hs.status = "Healthy" + hs.message = ready_message + elseif synced == false and suspended == true then + hs.status = "Suspended" + hs.message = suspended_message + elseif ready == false and synced == true and suspended == false then + hs.status = "Progressing" + hs.message = "Waiting for Policy to be available" + else + hs.status = "Degraded" + hs.message = synced_message + end + return hs + end +end + +hs.status = "Progressing" +hs.message = "Waiting for Policy to be created" +return hs diff --git a/resource_customizations/iam.aws.crossplane.io/Policy/health_test.yaml b/resource_customizations/iam.aws.crossplane.io/Policy/health_test.yaml new file mode 100644 index 0000000000000..07244a3f5b8eb --- /dev/null +++ b/resource_customizations/iam.aws.crossplane.io/Policy/health_test.yaml @@ -0,0 +1,10 @@ +tests: +- healthStatus: + status: Degraded + message: 'observe failed: cannot check if policy is up to date: invalid character + '']'' looking for beginning of value' + inputPath: testdata/ReconcileError.yaml +- healthStatus: + status: Healthy + message: Available + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/iam.aws.crossplane.io/Policy/testdata/ReconcileError.yaml b/resource_customizations/iam.aws.crossplane.io/Policy/testdata/ReconcileError.yaml new file mode 100644 index 0000000000000..4c00dffe0fdb8 --- /dev/null +++ b/resource_customizations/iam.aws.crossplane.io/Policy/testdata/ReconcileError.yaml @@ -0,0 +1,39 @@ +apiVersion: iam.aws.crossplane.io/v1beta1 +kind: Policy +metadata: + name: example +spec: + deletionPolicy: Delete + forProvider: + description: example + document: "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": + \"Allow\",\n \"Action\": [\n \"s3:*\",\n ], \n \"Resource\": + [\n \"arn:aws:s3:::example\"\n ]\n }\n ]\n}\n" + name: example + tags: + - key: crossplane-name + value: example + - key: crossplane-providerconfig + value: provider-aws + - key: crossplane-kind + value: policy.iam.aws.crossplane.io + providerConfigRef: + name: provider-aws +status: + atProvider: + arn: arn:aws:iam::123:policy/example + attachmentCount: 1 + defaultVersionId: v1 + isAttachable: true + policyId: ABC + conditions: + - lastTransitionTime: "2024-07-11T11:01:01Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2024-07-11T11:01:01Z" + message: 'observe failed: cannot check if policy is up to date: invalid character + '']'' looking for beginning of value' + reason: ReconcileError + status: "False" + type: Synced diff --git a/resource_customizations/iam.aws.crossplane.io/Policy/testdata/healthy.yaml b/resource_customizations/iam.aws.crossplane.io/Policy/testdata/healthy.yaml new file mode 100644 index 0000000000000..04d8dd8cf1aef --- /dev/null +++ b/resource_customizations/iam.aws.crossplane.io/Policy/testdata/healthy.yaml @@ -0,0 +1,45 @@ +apiVersion: iam.aws.crossplane.io/v1beta1 +kind: Policy +metadata: + name: example +spec: + deletionPolicy: Delete + forProvider: + description: example + document: | + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": ["s3:ListBucket"], + "Resource": ["arn:aws:s3:::examples"] + } + ] + } + name: examples-s3-hello-s3 + tags: + - key: crossplane-name + value: example + - key: crossplane-providerconfig + value: provider-aws + - key: crossplane-kind + value: policy.iam.aws.crossplane.io + providerConfigRef: + name: provider-aws +status: + atProvider: + arn: arn:aws:iam::123:policy/examples-s3-hello-s3 + attachmentCount: 1 + defaultVersionId: v2 + isAttachable: true + policyId: 123 + conditions: + - lastTransitionTime: "2024-07-11T08:18:16Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2024-07-11T08:18:07Z" + reason: ReconcileSuccess + status: "True" + type: Synced diff --git a/resource_customizations/iam.aws.crossplane.io/Role/health.lua b/resource_customizations/iam.aws.crossplane.io/Role/health.lua new file mode 100644 index 0000000000000..a264c2049d1b5 --- /dev/null +++ b/resource_customizations/iam.aws.crossplane.io/Role/health.lua @@ -0,0 +1,41 @@ +local hs = {} +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local ready = false + local synced = false + local suspended = false + for i, condition in ipairs(obj.status.conditions) do + + if condition.type == "Ready" then + ready = condition.status == "True" + ready_message = condition.reason + elseif condition.type == "Synced" then + synced = condition.status == "True" + if condition.reason == "ReconcileError" then + synced_message = condition.message + elseif condition.reason == "ReconcilePaused" then + suspended = true + suspended_message = condition.reason + end + end + end + if ready and synced then + hs.status = "Healthy" + hs.message = ready_message + elseif synced == false and suspended == true then + hs.status = "Suspended" + hs.message = suspended_message + elseif ready == false and synced == true and suspended == false then + hs.status = "Progressing" + hs.message = "Waiting for Role to be available" + else + hs.status = "Degraded" + hs.message = synced_message + end + return hs + end +end + +hs.status = "Progressing" +hs.message = "Waiting for Role to be created" +return hs diff --git a/resource_customizations/iam.aws.crossplane.io/Role/health_test.yaml b/resource_customizations/iam.aws.crossplane.io/Role/health_test.yaml new file mode 100644 index 0000000000000..4e4c93684fef3 --- /dev/null +++ b/resource_customizations/iam.aws.crossplane.io/Role/health_test.yaml @@ -0,0 +1,10 @@ +tests: +- healthStatus: + status: Degraded + message: 'connect failed: cannot get referenced Provider: ProviderConfig.aws.crossplane.io + "provider-aws1" not found' + inputPath: testdata/ReconcileError.yaml +- healthStatus: + status: Healthy + message: Available + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/iam.aws.crossplane.io/Role/testdata/ReconcileError.yaml b/resource_customizations/iam.aws.crossplane.io/Role/testdata/ReconcileError.yaml new file mode 100644 index 0000000000000..6a71e20da4628 --- /dev/null +++ b/resource_customizations/iam.aws.crossplane.io/Role/testdata/ReconcileError.yaml @@ -0,0 +1,54 @@ +apiVersion: iam.aws.crossplane.io/v1beta1 +kind: Role +metadata: + name: example +spec: + deletionPolicy: Delete + forProvider: + assumeRolePolicyDocument: | + { + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "", + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam::123:oidc-provider/oidc.eks.eu-north-1.amazonaws.com/id/123ABC" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "oidc.eks.eu-north-1.amazonaws.com/id/123ABC:sub": "system:serviceaccount:ABC:example", + "oidc.eks.eu-north-1.amazonaws.com/id/123ABC:aud": "sts.amazonaws.com" + } + } + } + ] + } + description: example + maxSessionDuration: 3600 + path: / + tags: + - key: crossplane-kind + value: role.iam.aws.crossplane.io + - key: crossplane-name + value: example + - key: crossplane-providerconfig + value: provider-aws + providerConfigRef: + name: provider-aws1 +status: + atProvider: + arn: arn:aws:iam::123:role/examples-s31 + roleID: ABC123 + conditions: + - lastTransitionTime: "2024-07-11T13:51:47Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2024-07-11T13:54:11Z" + message: 'connect failed: cannot get referenced Provider: ProviderConfig.aws.crossplane.io + "provider-aws1" not found' + reason: ReconcileError + status: "False" + type: Synced diff --git a/resource_customizations/iam.aws.crossplane.io/Role/testdata/healthy.yaml b/resource_customizations/iam.aws.crossplane.io/Role/testdata/healthy.yaml new file mode 100644 index 0000000000000..6f4d92cc10af5 --- /dev/null +++ b/resource_customizations/iam.aws.crossplane.io/Role/testdata/healthy.yaml @@ -0,0 +1,52 @@ +apiVersion: iam.aws.crossplane.io/v1beta1 +kind: Role +metadata: + name: example +spec: + deletionPolicy: Delete + forProvider: + assumeRolePolicyDocument: | + { + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "", + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam::123:oidc-provider/oidc.eks.eu-north-1.amazonaws.com/id/123ABC" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "oidc.eks.eu-north-1.amazonaws.com/id/123ABC:sub": "system:serviceaccount:ABC:example", + "oidc.eks.eu-north-1.amazonaws.com/id/123ABC:aud": "sts.amazonaws.com" + } + } + } + ] + } + description: example + maxSessionDuration: 3600 + path: / + tags: + - key: crossplane-kind + value: role.iam.aws.crossplane.io + - key: crossplane-name + value: example + - key: crossplane-providerconfig + value: provider-aws + providerConfigRef: + name: provider-aws +status: + atProvider: + arn: arn:aws:iam::123:role/example + roleID: ABC123 + conditions: + - lastTransitionTime: "2024-07-11T07:49:50Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2024-07-11T07:49:49Z" + reason: ReconcileSuccess + status: "True" + type: Synced diff --git a/resource_customizations/iam.aws.crossplane.io/RolePolicyAttachment/health.lua b/resource_customizations/iam.aws.crossplane.io/RolePolicyAttachment/health.lua new file mode 100644 index 0000000000000..516c30b36c305 --- /dev/null +++ b/resource_customizations/iam.aws.crossplane.io/RolePolicyAttachment/health.lua @@ -0,0 +1,41 @@ +local hs = {} +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local ready = false + local synced = false + local suspended = false + for i, condition in ipairs(obj.status.conditions) do + + if condition.type == "Ready" then + ready = condition.status == "True" + ready_message = condition.reason + elseif condition.type == "Synced" then + synced = condition.status == "True" + if condition.reason == "ReconcileError" then + synced_message = condition.message + elseif condition.reason == "ReconcilePaused" then + suspended = true + suspended_message = condition.reason + end + end + end + if ready and synced then + hs.status = "Healthy" + hs.message = ready_message + elseif synced == false and suspended == true then + hs.status = "Suspended" + hs.message = suspended_message + elseif ready == false and synced == true and suspended == false then + hs.status = "Progressing" + hs.message = "Waiting for RolePolicyAttachment to be available" + else + hs.status = "Degraded" + hs.message = synced_message + end + return hs + end +end + +hs.status = "Progressing" +hs.message = "Waiting for RolePolicyAttachment to be created" +return hs diff --git a/resource_customizations/iam.aws.crossplane.io/RolePolicyAttachment/health_test.yaml b/resource_customizations/iam.aws.crossplane.io/RolePolicyAttachment/health_test.yaml new file mode 100644 index 0000000000000..1ba7ed049cca4 --- /dev/null +++ b/resource_customizations/iam.aws.crossplane.io/RolePolicyAttachment/health_test.yaml @@ -0,0 +1,10 @@ +tests: +- healthStatus: + status: Degraded + message: 'create failed: failed to attach the policy to role: NoSuchEntity: The + role with name example cannot be found.' + inputPath: testdata/ReconcileError.yaml +- healthStatus: + status: Healthy + message: Available + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/iam.aws.crossplane.io/RolePolicyAttachment/testdata/ReconcileError.yaml b/resource_customizations/iam.aws.crossplane.io/RolePolicyAttachment/testdata/ReconcileError.yaml new file mode 100644 index 0000000000000..9249805319225 --- /dev/null +++ b/resource_customizations/iam.aws.crossplane.io/RolePolicyAttachment/testdata/ReconcileError.yaml @@ -0,0 +1,25 @@ +apiVersion: iam.aws.crossplane.io/v1beta1 +kind: RolePolicyAttachment +metadata: + name: example +spec: + deletionPolicy: Delete + forProvider: + policyArn: arn:aws:iam::123:policy/example + roleName: example + providerConfigRef: + name: provider-aws +status: + atProvider: + attachedPolicyArn: "" + conditions: + - lastTransitionTime: "2024-07-11T13:44:28Z" + reason: Creating + status: "False" + type: Ready + - lastTransitionTime: "2024-07-11T13:44:28Z" + message: 'create failed: failed to attach the policy to role: NoSuchEntity: The + role with name example cannot be found.' + reason: ReconcileError + status: "False" + type: Synced diff --git a/resource_customizations/iam.aws.crossplane.io/RolePolicyAttachment/testdata/healthy.yaml b/resource_customizations/iam.aws.crossplane.io/RolePolicyAttachment/testdata/healthy.yaml new file mode 100644 index 0000000000000..41d4d17a9c415 --- /dev/null +++ b/resource_customizations/iam.aws.crossplane.io/RolePolicyAttachment/testdata/healthy.yaml @@ -0,0 +1,23 @@ +apiVersion: iam.aws.crossplane.io/v1beta1 +kind: RolePolicyAttachment +metadata: + name: example +spec: + deletionPolicy: Delete + forProvider: + policyArn: arn:aws:iam::123:policy/example + roleName: example + providerConfigRef: + name: provider-aws +status: + atProvider: + attachedPolicyArn: arn:aws:iam::123:policy/example + conditions: + - lastTransitionTime: "2024-07-11T08:19:17Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2024-07-11T08:18:16Z" + reason: ReconcileSuccess + status: "True" + type: Synced diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/health.lua b/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/health.lua new file mode 100644 index 0000000000000..688d06f0886ad --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/health.lua @@ -0,0 +1,38 @@ +local hs = {} +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local numProgressing = 0 + local numSucceeded = 0 + local message = "" + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + if condition.status == "True" then + numSucceeded = numSucceeded + 1 + elseif condition.status == "False" then + numProgressing = numProgressing + 1 + end + message = condition.reason + elseif condition.type == "Reconciling" and condition.status == "True" then + if condition.reason == "NewGeneration" or condition.reason == "AccessingRepository" or condition.reason == "ApplyingPolicy" then + numProgressing = numProgressing + 1 + end + end + end + if(numProgressing == 2) then + hs.message = message + hs.status = "Progressing" + return hs + elseif(numSucceeded == 1) then + hs.message = message + hs.status = "Healthy" + return hs + else + hs.message = message + hs.status = "Degraded" + return hs + end + end +end +hs.message = "Status unknown" +hs.status = "Progressing" +return hs diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/health_test.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/health_test.yaml new file mode 100644 index 0000000000000..0f8d9c4a64541 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/health_test.yaml @@ -0,0 +1,13 @@ +tests: + # - healthStatus: + # status: Progressing + # message: DependencyNotReady + # inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: DependencyNotReady + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: Succeeded + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/testdata/degraded.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/testdata/degraded.yaml new file mode 100644 index 0000000000000..4fcbc4498c045 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/testdata/degraded.yaml @@ -0,0 +1,26 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImagePolicy +metadata: + name: podinfo + namespace: argocd +spec: + imageRepositoryRef: + name: podinfo-faulty + policy: + semver: + range: x.x.x +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'processing object: new generation 1 -> 2' + observedGeneration: 2 + reason: ProgressingWithRetry + status: "True" + type: Reconciling + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'failed to get the referred ImageRepository: referenced ImageRepository + does not exist: ImageRepository.image.toolkit.fluxcd.io "podinfo-faulty" not found' + observedGeneration: 2 + reason: DependencyNotReady + status: "False" + type: Ready diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/testdata/healthy.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/testdata/healthy.yaml new file mode 100644 index 0000000000000..b1fdf01bedb36 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/testdata/healthy.yaml @@ -0,0 +1,19 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImagePolicy +metadata: + name: podinfo + namespace: argocd +spec: + imageRepositoryRef: + name: podinfo + policy: + semver: + range: x.x.x +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Latest image tag for 'stefanprodan/podinfo' resolved to 5.1.4 + observedGeneration: 1 + reason: Succeeded + status: "True" + type: Ready diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/testdata/progressing.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/testdata/progressing.yaml new file mode 100644 index 0000000000000..90e71223b3837 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImagePolicy/testdata/progressing.yaml @@ -0,0 +1,13 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImagePolicy +metadata: + name: podinfo + namespace: argocd +spec: + imageRepositoryRef: + name: podinfo + policy: + semver: + range: x.x.x +status: + conditions: [] diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/action_test.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/action_test.yaml new file mode 100644 index 0000000000000..69bd3dbb46c06 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/action_test.yaml @@ -0,0 +1,35 @@ +discoveryTests: +- inputPath: testdata/initial_imagerepository.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +- inputPath: testdata/suspended_imagerepository.yaml + result: + - name: reconcile + disabled: true + - name: suspend + disabled: true + - name: resume + disabled: false +- inputPath: testdata/resumed_imagerepository.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +actionTests: +- action: reconcile + inputPath: testdata/initial_imagerepository.yaml + expectedOutputPath: testdata/reconciled_imagerepository.yaml +- action: suspend + inputPath: testdata/initial_imagerepository.yaml + expectedOutputPath: testdata/suspended_imagerepository.yaml +- action: resume + inputPath: testdata/suspended_imagerepository.yaml + expectedOutputPath: testdata/resumed_imagerepository.yaml diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/discovery.lua b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/discovery.lua new file mode 100644 index 0000000000000..9000998815515 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/discovery.lua @@ -0,0 +1,18 @@ +local actions = {} + +actions["reconcile"] = {["disabled"] = true} +actions["suspend"] = {["disabled"] = true} +actions["resume"] = {["disabled"] = true} + +local suspend = false +if obj.spec.suspend ~= nil then + suspend = obj.spec.suspend +end +if suspend then + actions["resume"]["disabled"] = false +else + actions["reconcile"]["disabled"] = false + actions["suspend"]["disabled"] = false +end + +return actions diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/reconcile/action.lua b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/reconcile/action.lua new file mode 100644 index 0000000000000..a534b36fb3ebc --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/reconcile/action.lua @@ -0,0 +1,7 @@ +local os = require("os") +if obj.metadata.annotations == nil then + obj.metadata.annotations = {} +end +obj.metadata.annotations["reconcile.fluxcd.io/requestedAt"] = "By Argo CD at: " .. os.date("!%Y-%m-%dT%X") + +return obj diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/resume/action.lua b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/resume/action.lua new file mode 100644 index 0000000000000..cb41993777699 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/resume/action.lua @@ -0,0 +1,5 @@ +if obj.spec.suspend ~= nil and obj.spec.suspend then + obj.spec.suspend = false +end + +return obj diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/suspend/action.lua b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/suspend/action.lua new file mode 100644 index 0000000000000..1a338b2ad1361 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/suspend/action.lua @@ -0,0 +1,3 @@ +obj.spec.suspend = true + +return obj diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/testdata/initial_imagerepository.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/testdata/initial_imagerepository.yaml new file mode 100644 index 0000000000000..c3491a774ca78 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/testdata/initial_imagerepository.yaml @@ -0,0 +1,9 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageRepository +metadata: + name: podinfo + namespace: default +spec: + image: stefanprodan/podinfo + interval: 1h + provider: generic diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/testdata/reconciled_imagerepository.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/testdata/reconciled_imagerepository.yaml new file mode 100644 index 0000000000000..8d9a0625d67c6 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/testdata/reconciled_imagerepository.yaml @@ -0,0 +1,11 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageRepository +metadata: + name: podinfo + namespace: default + annotations: + reconcile.fluxcd.io/requestedAt: 'By Argo CD at: 0001-01-01T00:00:00' +spec: + image: stefanprodan/podinfo + interval: 1h + provider: generic diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/testdata/resumed_imagerepository.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/testdata/resumed_imagerepository.yaml new file mode 100644 index 0000000000000..1317a1e58007c --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/testdata/resumed_imagerepository.yaml @@ -0,0 +1,10 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageRepository +metadata: + name: podinfo + namespace: default +spec: + image: stefanprodan/podinfo + interval: 1h + provider: generic + suspend: false diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/testdata/suspended_imagerepository.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/testdata/suspended_imagerepository.yaml new file mode 100644 index 0000000000000..b7286cd242438 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/actions/testdata/suspended_imagerepository.yaml @@ -0,0 +1,10 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageRepository +metadata: + name: podinfo + namespace: default +spec: + image: stefanprodan/podinfo + interval: 1h + provider: generic + suspend: true diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/health.lua b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/health.lua new file mode 100644 index 0000000000000..aa65850494c99 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/health.lua @@ -0,0 +1,43 @@ +local hs = {} +if obj.spec.suspend ~= nil and obj.spec.suspend == true then + hs.message = obj.kind .. " is suspended" + hs.status = "Suspended" + return hs +end +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local numProgressing = 0 + local numSucceeded = 0 + local message = "" + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + if condition.status == "True" then + numSucceeded = numSucceeded + 1 + elseif condition.status == "False" then + numProgressing = numProgressing + 1 + end + message = condition.reason + elseif condition.type == "Reconciling" and condition.status == "True" then + if condition.reason == "NewGeneration" or condition.reason == "Scanning" then + numProgressing = numProgressing + 1 + end + end + end + if(numProgressing == 2) then + hs.message = message + hs.status = "Progressing" + return hs + elseif(numSucceeded == 1) then + hs.message = message + hs.status = "Healthy" + return hs + else + hs.message = message + hs.status = "Degraded" + return hs + end + end +end +hs.message = "Status unknown" +hs.status = "Progressing" +return hs diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/health_test.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/health_test.yaml new file mode 100644 index 0000000000000..22170d09007cd --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/health_test.yaml @@ -0,0 +1,13 @@ +tests: + # - healthStatus: + # status: Progressing + # message: ReadOperationFailed + # inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: ReadOperationFailed + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: Succeeded + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/testdata/degraded.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/testdata/degraded.yaml new file mode 100644 index 0000000000000..ddc47923d3a0a --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/testdata/degraded.yaml @@ -0,0 +1,25 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageRepository +metadata: + name: podinfo + namespace: default +spec: + image: stefanprodan/podinfo-faulty + interval: 1h + provider: generic +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'scanning: new image name' + observedGeneration: 2 + reason: ProgressingWithRetry + status: "True" + type: Reconciling + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'scan failed: GET https://index.docker.io/v2/stefanprodan/podinfo-faulty/tags/list?n=1000: + UNAUTHORIZED: authentication required; [map[Action:pull Class: Name:stefanprodan/podinfo-faulty + Type:repository]]' + observedGeneration: 2 + reason: ReadOperationFailed + status: "False" + type: Ready diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/testdata/healthy.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/testdata/healthy.yaml new file mode 100644 index 0000000000000..11ed02af76016 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/testdata/healthy.yaml @@ -0,0 +1,17 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageRepository +metadata: + name: podinfo + namespace: default +spec: + image: stefanprodan/podinfo + interval: 1h + provider: generic +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'successful scan: found 233 tags' + observedGeneration: 1 + reason: Succeeded + status: "True" + type: Ready diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/testdata/progressing.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/testdata/progressing.yaml new file mode 100644 index 0000000000000..a0ac7d4718100 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageRepository/testdata/progressing.yaml @@ -0,0 +1,11 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageRepository +metadata: + name: podinfo + namespace: default +spec: + image: stefanprodan/podinfo + interval: 1h + provider: generic +status: + conditions: [] diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/action_test.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/action_test.yaml new file mode 100644 index 0000000000000..c69e51b26a2e4 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/action_test.yaml @@ -0,0 +1,35 @@ +discoveryTests: +- inputPath: testdata/initial_imageupdateautomation.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +- inputPath: testdata/suspended_imageupdateautomation.yaml + result: + - name: reconcile + disabled: true + - name: suspend + disabled: true + - name: resume + disabled: false +- inputPath: testdata/resumed_imageupdateautomation.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +actionTests: +- action: reconcile + inputPath: testdata/initial_imageupdateautomation.yaml + expectedOutputPath: testdata/reconciled_imageupdateautomation.yaml +- action: suspend + inputPath: testdata/initial_imageupdateautomation.yaml + expectedOutputPath: testdata/suspended_imageupdateautomation.yaml +- action: resume + inputPath: testdata/suspended_imageupdateautomation.yaml + expectedOutputPath: testdata/resumed_imageupdateautomation.yaml diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/discovery.lua b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/discovery.lua new file mode 100644 index 0000000000000..9000998815515 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/discovery.lua @@ -0,0 +1,18 @@ +local actions = {} + +actions["reconcile"] = {["disabled"] = true} +actions["suspend"] = {["disabled"] = true} +actions["resume"] = {["disabled"] = true} + +local suspend = false +if obj.spec.suspend ~= nil then + suspend = obj.spec.suspend +end +if suspend then + actions["resume"]["disabled"] = false +else + actions["reconcile"]["disabled"] = false + actions["suspend"]["disabled"] = false +end + +return actions diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/reconcile/action.lua b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/reconcile/action.lua new file mode 100644 index 0000000000000..a534b36fb3ebc --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/reconcile/action.lua @@ -0,0 +1,7 @@ +local os = require("os") +if obj.metadata.annotations == nil then + obj.metadata.annotations = {} +end +obj.metadata.annotations["reconcile.fluxcd.io/requestedAt"] = "By Argo CD at: " .. os.date("!%Y-%m-%dT%X") + +return obj diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/resume/action.lua b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/resume/action.lua new file mode 100644 index 0000000000000..cb41993777699 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/resume/action.lua @@ -0,0 +1,5 @@ +if obj.spec.suspend ~= nil and obj.spec.suspend then + obj.spec.suspend = false +end + +return obj diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/suspend/action.lua b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/suspend/action.lua new file mode 100644 index 0000000000000..1a338b2ad1361 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/suspend/action.lua @@ -0,0 +1,3 @@ +obj.spec.suspend = true + +return obj diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/testdata/initial_imageupdateautomation.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/testdata/initial_imageupdateautomation.yaml new file mode 100644 index 0000000000000..049b7be69a583 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/testdata/initial_imageupdateautomation.yaml @@ -0,0 +1,19 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageUpdateAutomation +metadata: + name: podinfo-update + namespace: default +spec: + interval: 30m + sourceRef: + kind: GitRepository + name: podinfo + git: + commit: + author: + email: fluxcdbot@users.noreply.github.com + name: fluxcdbot + push: + branch: main + update: + path: ./ diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/testdata/reconciled_imageupdateautomation.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/testdata/reconciled_imageupdateautomation.yaml new file mode 100644 index 0000000000000..9f39dfdaf7dc7 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/testdata/reconciled_imageupdateautomation.yaml @@ -0,0 +1,21 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageUpdateAutomation +metadata: + name: podinfo-update + namespace: default + annotations: + reconcile.fluxcd.io/requestedAt: 'By Argo CD at: 0001-01-01T00:00:00' +spec: + interval: 30m + sourceRef: + kind: GitRepository + name: podinfo + git: + commit: + author: + email: fluxcdbot@users.noreply.github.com + name: fluxcdbot + push: + branch: main + update: + path: ./ diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/testdata/resumed_imageupdateautomation.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/testdata/resumed_imageupdateautomation.yaml new file mode 100644 index 0000000000000..25bb66e190fe5 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/testdata/resumed_imageupdateautomation.yaml @@ -0,0 +1,20 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageUpdateAutomation +metadata: + name: podinfo-update + namespace: default +spec: + interval: 30m + sourceRef: + kind: GitRepository + name: podinfo + git: + commit: + author: + email: fluxcdbot@users.noreply.github.com + name: fluxcdbot + push: + branch: main + suspend: false + update: + path: ./ diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/testdata/suspended_imageupdateautomation.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/testdata/suspended_imageupdateautomation.yaml new file mode 100644 index 0000000000000..9968fddf35e35 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/actions/testdata/suspended_imageupdateautomation.yaml @@ -0,0 +1,20 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageUpdateAutomation +metadata: + name: podinfo-update + namespace: default +spec: + interval: 30m + sourceRef: + kind: GitRepository + name: podinfo + git: + commit: + author: + email: fluxcdbot@users.noreply.github.com + name: fluxcdbot + push: + branch: main + suspend: true + update: + path: ./ diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/health.lua b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/health.lua new file mode 100644 index 0000000000000..b4f27ab073ec2 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/health.lua @@ -0,0 +1,41 @@ +local hs = {} +if obj.spec.suspend ~= nil and obj.spec.suspend == true then + hs.message = obj.kind .. " is suspended" + hs.status = "Suspended" + return hs +end +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local numProgressing = 0 + local numSucceeded = 0 + local message = "" + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + if condition.status == "True" then + numSucceeded = numSucceeded + 1 + elseif condition.status == "Unknown" then + numProgressing = numProgressing + 1 + end + message = condition.reason + elseif condition.type == "Reconciling" and condition.status == "True" then + numProgressing = numProgressing + 1 + end + end + if(numProgressing == 2) then + hs.message = message + hs.status = "Progressing" + return hs + elseif(numSucceeded == 1) then + hs.message = message + hs.status = "Healthy" + return hs + else + hs.message = message + hs.status = "Degraded" + return hs + end + end +end +hs.message = "Status unknown" +hs.status = "Progressing" +return hs diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/health_test.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/health_test.yaml new file mode 100644 index 0000000000000..e9509ef4d8ded --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/health_test.yaml @@ -0,0 +1,13 @@ +tests: + # - healthStatus: + # status: Progressing + # message: Progressing + # inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: ReconciliationFailed + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: ReconciliationSucceeded + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/testdata/degraded.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/testdata/degraded.yaml new file mode 100644 index 0000000000000..8de0cfa46ae10 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/testdata/degraded.yaml @@ -0,0 +1,27 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageUpdateAutomation +metadata: + name: podinfo-update + namespace: default +spec: + interval: 30m + sourceRef: + kind: GitRepository + name: podinfo + git: + commit: + author: + email: fluxcdbot@users.noreply.github.com + name: fluxcdbot + push: + branch: main + update: + path: ./ +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'walking path for files: lstat /tmp/deploy: + no such file or directory' + reason: ReconciliationFailed + status: "False" + type: Ready diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/testdata/healthy.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/testdata/healthy.yaml new file mode 100644 index 0000000000000..970b28a77dbf2 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/testdata/healthy.yaml @@ -0,0 +1,26 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageUpdateAutomation +metadata: + name: podinfo-update + namespace: default +spec: + interval: 30m + sourceRef: + kind: GitRepository + name: podinfo + git: + commit: + author: + email: fluxcdbot@users.noreply.github.com + name: fluxcdbot + push: + branch: main + update: + path: ./ +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: no updates made; last commit a1b24e5 at 2024-07-16T12:00:00Z + reason: ReconciliationSucceeded + status: "True" + type: Ready diff --git a/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/testdata/progressing.yaml b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/testdata/progressing.yaml new file mode 100644 index 0000000000000..72e7e19fd2335 --- /dev/null +++ b/resource_customizations/image.toolkit.fluxcd.io/ImageUpdateAutomation/testdata/progressing.yaml @@ -0,0 +1,21 @@ +apiVersion: image.toolkit.fluxcd.io/v1beta2 +kind: ImageUpdateAutomation +metadata: + name: podinfo-update + namespace: default +spec: + interval: 30m + sourceRef: + kind: GitRepository + name: podinfo + git: + commit: + author: + email: fluxcdbot@users.noreply.github.com + name: fluxcdbot + push: + branch: main + update: + path: ./ +status: + conditions: [] diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/action_test.yaml b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/action_test.yaml new file mode 100644 index 0000000000000..da2b9953274da --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/action_test.yaml @@ -0,0 +1,35 @@ +discoveryTests: +- inputPath: testdata/initial_kustomization.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +- inputPath: testdata/suspended_kustomization.yaml + result: + - name: reconcile + disabled: true + - name: suspend + disabled: true + - name: resume + disabled: false +- inputPath: testdata/resumed_kustomization.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +actionTests: +- action: reconcile + inputPath: testdata/initial_kustomization.yaml + expectedOutputPath: testdata/reconciled_kustomization.yaml +- action: suspend + inputPath: testdata/initial_kustomization.yaml + expectedOutputPath: testdata/suspended_kustomization.yaml +- action: resume + inputPath: testdata/suspended_kustomization.yaml + expectedOutputPath: testdata/resumed_kustomization.yaml diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/discovery.lua b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/discovery.lua new file mode 100644 index 0000000000000..9000998815515 --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/discovery.lua @@ -0,0 +1,18 @@ +local actions = {} + +actions["reconcile"] = {["disabled"] = true} +actions["suspend"] = {["disabled"] = true} +actions["resume"] = {["disabled"] = true} + +local suspend = false +if obj.spec.suspend ~= nil then + suspend = obj.spec.suspend +end +if suspend then + actions["resume"]["disabled"] = false +else + actions["reconcile"]["disabled"] = false + actions["suspend"]["disabled"] = false +end + +return actions diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/reconcile/action.lua b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/reconcile/action.lua new file mode 100644 index 0000000000000..a534b36fb3ebc --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/reconcile/action.lua @@ -0,0 +1,7 @@ +local os = require("os") +if obj.metadata.annotations == nil then + obj.metadata.annotations = {} +end +obj.metadata.annotations["reconcile.fluxcd.io/requestedAt"] = "By Argo CD at: " .. os.date("!%Y-%m-%dT%X") + +return obj diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/resume/action.lua b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/resume/action.lua new file mode 100644 index 0000000000000..cb41993777699 --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/resume/action.lua @@ -0,0 +1,5 @@ +if obj.spec.suspend ~= nil and obj.spec.suspend then + obj.spec.suspend = false +end + +return obj diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/suspend/action.lua b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/suspend/action.lua new file mode 100644 index 0000000000000..1a338b2ad1361 --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/suspend/action.lua @@ -0,0 +1,3 @@ +obj.spec.suspend = true + +return obj diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/testdata/initial_kustomization.yaml b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/testdata/initial_kustomization.yaml new file mode 100644 index 0000000000000..baa2331533a04 --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/testdata/initial_kustomization.yaml @@ -0,0 +1,14 @@ +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: podinfo + namespace: default +spec: + interval: 10m + targetNamespace: default + sourceRef: + kind: GitRepository + name: podinfo + path: "./kustomize" + prune: true + timeout: 1m diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/testdata/reconciled_kustomization.yaml b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/testdata/reconciled_kustomization.yaml new file mode 100644 index 0000000000000..fa3019c176bb2 --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/testdata/reconciled_kustomization.yaml @@ -0,0 +1,16 @@ +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: podinfo + namespace: default + annotations: + reconcile.fluxcd.io/requestedAt: 'By Argo CD at: 0001-01-01T00:00:00' +spec: + interval: 10m + targetNamespace: default + sourceRef: + kind: GitRepository + name: podinfo + path: "./kustomize" + prune: true + timeout: 1m diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/testdata/resumed_kustomization.yaml b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/testdata/resumed_kustomization.yaml new file mode 100644 index 0000000000000..48bc7baffefbb --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/testdata/resumed_kustomization.yaml @@ -0,0 +1,15 @@ +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: podinfo + namespace: default +spec: + interval: 10m + targetNamespace: default + sourceRef: + kind: GitRepository + name: podinfo + path: "./kustomize" + prune: true + suspend: false + timeout: 1m diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/testdata/suspended_kustomization.yaml b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/testdata/suspended_kustomization.yaml new file mode 100644 index 0000000000000..b4684ef2d0d56 --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/actions/testdata/suspended_kustomization.yaml @@ -0,0 +1,15 @@ +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: podinfo + namespace: default +spec: + interval: 10m + targetNamespace: default + sourceRef: + kind: GitRepository + name: podinfo + path: "./kustomize" + prune: true + suspend: true + timeout: 1m diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/health.lua b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/health.lua new file mode 100644 index 0000000000000..b4f27ab073ec2 --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/health.lua @@ -0,0 +1,41 @@ +local hs = {} +if obj.spec.suspend ~= nil and obj.spec.suspend == true then + hs.message = obj.kind .. " is suspended" + hs.status = "Suspended" + return hs +end +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local numProgressing = 0 + local numSucceeded = 0 + local message = "" + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + if condition.status == "True" then + numSucceeded = numSucceeded + 1 + elseif condition.status == "Unknown" then + numProgressing = numProgressing + 1 + end + message = condition.reason + elseif condition.type == "Reconciling" and condition.status == "True" then + numProgressing = numProgressing + 1 + end + end + if(numProgressing == 2) then + hs.message = message + hs.status = "Progressing" + return hs + elseif(numSucceeded == 1) then + hs.message = message + hs.status = "Healthy" + return hs + else + hs.message = message + hs.status = "Degraded" + return hs + end + end +end +hs.message = "Status unknown" +hs.status = "Progressing" +return hs diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/health_test.yaml b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/health_test.yaml new file mode 100644 index 0000000000000..62c520424189c --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/health_test.yaml @@ -0,0 +1,13 @@ +tests: + - healthStatus: + status: Progressing + message: Progressing + inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: ArtifactFailed + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: InstallSucceeded + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/testdata/degraded.yaml b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/testdata/degraded.yaml new file mode 100644 index 0000000000000..6816b329d48e1 --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/testdata/degraded.yaml @@ -0,0 +1,23 @@ +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: podinfo + namespace: default +spec: + interval: 10m + targetNamespace: default + sourceRef: + kind: GitRepository + name: podinfo + path: "./kustomize" + prune: true + timeout: 1m +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: GitRepository.source.toolkit.fluxcd.io "podinfo" not found + observedGeneration: 1 + reason: ArtifactFailed + status: "False" + type: Ready + observedGeneration: -1 diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/testdata/healthy.yaml b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/testdata/healthy.yaml new file mode 100644 index 0000000000000..a6fc2fb02fdc6 --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/testdata/healthy.yaml @@ -0,0 +1,30 @@ +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: podinfo + namespace: default +spec: + interval: 10m + targetNamespace: default + sourceRef: + kind: GitRepository + name: podinfo + path: "./kustomize" + prune: true + timeout: 1m +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Helm install succeeded for release default/podinfo.v1 with + chart podinfo@6.5.4 + observedGeneration: 2 + reason: InstallSucceeded + status: "True" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Helm install succeeded for release default/podinfo.v1 with + chart podinfo@6.5.4 + observedGeneration: 1 + reason: InstallSucceeded + status: "True" + type: Released diff --git a/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/testdata/progressing.yaml b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/testdata/progressing.yaml new file mode 100644 index 0000000000000..3bfa6e4159b09 --- /dev/null +++ b/resource_customizations/kustomize.toolkit.fluxcd.io/Kustomization/testdata/progressing.yaml @@ -0,0 +1,35 @@ +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: podinfo + namespace: default +spec: + interval: 10m + targetNamespace: default + sourceRef: + kind: GitRepository + name: podinfo + path: "./kustomize" + prune: true + timeout: 1m +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Running 'upgrade' action with timeout of 5m0s + observedGeneration: 3 + reason: Progressing + status: "True" + type: Reconciling + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Running 'upgrade' action with timeout of 5m0s + observedGeneration: 3 + reason: Progressing + status: Unknown + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Helm install succeeded for release default/podinfo.v1 with + chart podinfo@6.5.4 + observedGeneration: 1 + reason: InstallSucceeded + status: "True" + type: Released diff --git a/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/health.lua b/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/health.lua new file mode 100644 index 0000000000000..caedc1f309fda --- /dev/null +++ b/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/health.lua @@ -0,0 +1,14 @@ +local hs = {} +if obj.status.status == "Succeeded" then + hs.status = "Healthy" + hs.message = "KeptnWorkloadVersion is healthy" + return hs +end +if obj.status.status == "Failed" then + hs.status = "Degraded" + hs.message = "KeptnWorkloadVersion is degraded" + return hs +end +hs.status = "Progressing" +hs.message = "KeptnWorkloadVersion is progressing" +return hs \ No newline at end of file diff --git a/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/health_test.yaml b/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/health_test.yaml new file mode 100644 index 0000000000000..3fbc2bc524968 --- /dev/null +++ b/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/health_test.yaml @@ -0,0 +1,13 @@ +tests: + - healthStatus: + status: Progressing + message: "KeptnWorkloadVersion is progressing" + inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: "KeptnWorkloadVersion is degraded" + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: "KeptnWorkloadVersion is healthy" + inputPath: testdata/healthy.yaml \ No newline at end of file diff --git a/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/testdata/degraded.yaml b/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/testdata/degraded.yaml new file mode 100644 index 0000000000000..0df7b8ca4fe08 --- /dev/null +++ b/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/testdata/degraded.yaml @@ -0,0 +1,50 @@ +apiVersion: lifecycle.keptn.sh/v1alpha4 +kind: KeptnWorkloadVersion +metadata: + annotations: + traceparent: 00-5050e556a9aaf22814aa689d0518f4d3-cbcff966a6d32c39-01 + creationTimestamp: "2022-12-14T13:17:36Z" + generation: 2 + name: podtato-head-podtato-head-entry-0.2.7 + namespace: podtato-kubectl + ownerReferences: + - apiVersion: lifecycle.keptn.sh/v1alpha2 + blockOwnerDeletion: true + controller: true + kind: KeptnWorkload + name: podtato-head-podtato-head-entry + uid: dcafe814-7f9d-4d50-9a66-f61c81bfe764 + resourceVersion: "226253" + uid: 6987404b-c7b9-40f5-95e9-d5aad55a3f3b +spec: + app: podtato-head + resourceReference: + kind: ReplicaSet + name: podtato-head-entry-6fc8964846 + uid: 2b6e44bf-27e3-4305-a9fb-65d2f412936b + traceId: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-0ae50f2d844888ab-01 + version: 0.2.7 + workloadName: podtato-head-podtato-head-entry +status: + currentPhase: PreDeployTasks + deploymentStatus: Succeeded + phaseTraceIDs: + "": + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-ca249d3f6e024547-01 + WorkloadDeploy: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-3be53185e6024eb4-01 + WorkloadPostDeployEvaluations: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-0dc305a08a0ccf14-01 + WorkloadPostDeployTasks: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-4c7cf78cbbc40e14-01 + WorkloadPreDeployEvaluations: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-5eed0ec5420cfc89-01 + WorkloadPreDeployTasks: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-bef05615fc0138ac-01 + postDeploymentEvaluationStatus: Progressing + postDeploymentStatus: Progressing + preDeploymentEvaluationStatus: Failed + preDeploymentStatus: Failed + startTime: "2022-12-14T13:17:57Z" + status: Failed \ No newline at end of file diff --git a/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/testdata/healthy.yaml b/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/testdata/healthy.yaml new file mode 100644 index 0000000000000..b8879f0b29415 --- /dev/null +++ b/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/testdata/healthy.yaml @@ -0,0 +1,51 @@ +apiVersion: lifecycle.keptn.sh/v1alpha4 +kind: KeptnWorkloadVersion +metadata: + annotations: + traceparent: 00-5050e556a9aaf22814aa689d0518f4d3-cbcff966a6d32c39-01 + creationTimestamp: "2022-12-14T13:17:36Z" + generation: 2 + name: podtato-head-podtato-head-entry-0.2.7 + namespace: podtato-kubectl + ownerReferences: + - apiVersion: lifecycle.keptn.sh/v1alpha2 + blockOwnerDeletion: true + controller: true + kind: KeptnWorkload + name: podtato-head-podtato-head-entry + uid: dcafe814-7f9d-4d50-9a66-f61c81bfe764 + resourceVersion: "226253" + uid: 6987404b-c7b9-40f5-95e9-d5aad55a3f3b +spec: + app: podtato-head + resourceReference: + kind: ReplicaSet + name: podtato-head-entry-6fc8964846 + uid: 2b6e44bf-27e3-4305-a9fb-65d2f412936b + traceId: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-0ae50f2d844888ab-01 + version: 0.2.7 + workloadName: podtato-head-podtato-head-entry +status: + currentPhase: Completed + deploymentStatus: Succeeded + endTime: "2022-12-14T13:18:41Z" + phaseTraceIDs: + "": + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-ca249d3f6e024547-01 + WorkloadDeploy: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-3be53185e6024eb4-01 + WorkloadPostDeployEvaluations: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-0dc305a08a0ccf14-01 + WorkloadPostDeployTasks: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-4c7cf78cbbc40e14-01 + WorkloadPreDeployEvaluations: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-5eed0ec5420cfc89-01 + WorkloadPreDeployTasks: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-bef05615fc0138ac-01 + postDeploymentEvaluationStatus: Succeeded + postDeploymentStatus: Succeeded + preDeploymentEvaluationStatus: Succeeded + preDeploymentStatus: Succeeded + startTime: "2022-12-14T13:17:57Z" + status: Succeeded \ No newline at end of file diff --git a/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/testdata/progressing.yaml b/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/testdata/progressing.yaml new file mode 100644 index 0000000000000..b339bb469a8e6 --- /dev/null +++ b/resource_customizations/lifecycle.keptn.sh/KeptnWorkloadVersion/testdata/progressing.yaml @@ -0,0 +1,50 @@ +apiVersion: lifecycle.keptn.sh/v1alpha4 +kind: KeptnWorkloadVersion +metadata: + annotations: + traceparent: 00-5050e556a9aaf22814aa689d0518f4d3-cbcff966a6d32c39-01 + creationTimestamp: "2022-12-14T13:17:36Z" + generation: 2 + name: podtato-head-podtato-head-entry-0.2.7 + namespace: podtato-kubectl + ownerReferences: + - apiVersion: lifecycle.keptn.sh/v1alpha2 + blockOwnerDeletion: true + controller: true + kind: KeptnWorkload + name: podtato-head-podtato-head-entry + uid: dcafe814-7f9d-4d50-9a66-f61c81bfe764 + resourceVersion: "226253" + uid: 6987404b-c7b9-40f5-95e9-d5aad55a3f3b +spec: + app: podtato-head + resourceReference: + kind: ReplicaSet + name: podtato-head-entry-6fc8964846 + uid: 2b6e44bf-27e3-4305-a9fb-65d2f412936b + traceId: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-0ae50f2d844888ab-01 + version: 0.2.7 + workloadName: podtato-head-podtato-head-entry +status: + currentPhase: Completed + deploymentStatus: Succeeded + phaseTraceIDs: + "": + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-ca249d3f6e024547-01 + WorkloadDeploy: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-3be53185e6024eb4-01 + WorkloadPostDeployEvaluations: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-0dc305a08a0ccf14-01 + WorkloadPostDeployTasks: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-4c7cf78cbbc40e14-01 + WorkloadPreDeployEvaluations: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-5eed0ec5420cfc89-01 + WorkloadPreDeployTasks: + traceparent: 00-ecdd1f5a7e1068ac9b0d044aa165ca4c-bef05615fc0138ac-01 + postDeploymentEvaluationStatus: Progressing + postDeploymentStatus: Progressing + preDeploymentEvaluationStatus: Succeeded + preDeploymentStatus: Succeeded + startTime: "2022-12-14T13:17:57Z" + status: Progressing \ No newline at end of file diff --git a/resource_customizations/metrics.keptn.sh/Analysis/health.lua b/resource_customizations/metrics.keptn.sh/Analysis/health.lua new file mode 100644 index 0000000000000..449ccb3505d4c --- /dev/null +++ b/resource_customizations/metrics.keptn.sh/Analysis/health.lua @@ -0,0 +1,19 @@ +local hs = {} +if obj.status.pass == true then + hs.status = "Healthy" + hs.message = "Analysis is healthy" + return hs +end +if obj.status.warning == true then + hs.status = "Healthy" + hs.message = "Analysis is healthy with warnings" + return hs +end +if obj.status.pass == false then + hs.status = "Degraded" + hs.message = "Analysis is degraded" + return hs +end +hs.status = "Progressing" +hs.message = "Analysis is progressing" +return hs diff --git a/resource_customizations/metrics.keptn.sh/Analysis/health_test.yaml b/resource_customizations/metrics.keptn.sh/Analysis/health_test.yaml new file mode 100644 index 0000000000000..945d2c9058ba4 --- /dev/null +++ b/resource_customizations/metrics.keptn.sh/Analysis/health_test.yaml @@ -0,0 +1,17 @@ +tests: + - healthStatus: + status: Progressing + message: "Analysis is progressing" + inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: "Analysis is degraded" + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: "Analysis is healthy" + inputPath: testdata/healthy_pass.yaml + - healthStatus: + status: Healthy + message: "Analysis is healthy with warnings" + inputPath: testdata/healthy_warning.yaml diff --git a/resource_customizations/metrics.keptn.sh/Analysis/testdata/degraded.yaml b/resource_customizations/metrics.keptn.sh/Analysis/testdata/degraded.yaml new file mode 100644 index 0000000000000..b79dce0184b5e --- /dev/null +++ b/resource_customizations/metrics.keptn.sh/Analysis/testdata/degraded.yaml @@ -0,0 +1,24 @@ +apiVersion: metrics.keptn.sh/v1 +kind: Analysis +metadata: + labels: + app.kubernetes.io/name: analysis + app.kubernetes.io/instance: analysis-sample + app.kubernetes.io/part-of: metrics-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: metrics-operator + name: analysis-sample +spec: + timeframe: + recent: 5m + args: + project: my-project + stage: dev + service: svc1 + nodename: test + analysisDefinition: + name: ad-my-proj-dev-svc1 + namespace: keptn-system +status: + pass: false + state: Completed diff --git a/resource_customizations/metrics.keptn.sh/Analysis/testdata/healthy_pass.yaml b/resource_customizations/metrics.keptn.sh/Analysis/testdata/healthy_pass.yaml new file mode 100644 index 0000000000000..17c04d9e9f265 --- /dev/null +++ b/resource_customizations/metrics.keptn.sh/Analysis/testdata/healthy_pass.yaml @@ -0,0 +1,24 @@ +apiVersion: metrics.keptn.sh/v1 +kind: Analysis +metadata: + labels: + app.kubernetes.io/name: analysis + app.kubernetes.io/instance: analysis-sample + app.kubernetes.io/part-of: metrics-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: metrics-operator + name: analysis-sample +spec: + timeframe: + recent: 5m + args: + project: my-project + stage: dev + service: svc1 + nodename: test + analysisDefinition: + name: ad-my-proj-dev-svc1 + namespace: keptn-system +status: + pass: true + state: Completed diff --git a/resource_customizations/metrics.keptn.sh/Analysis/testdata/healthy_warning.yaml b/resource_customizations/metrics.keptn.sh/Analysis/testdata/healthy_warning.yaml new file mode 100644 index 0000000000000..81eed8af49949 --- /dev/null +++ b/resource_customizations/metrics.keptn.sh/Analysis/testdata/healthy_warning.yaml @@ -0,0 +1,24 @@ +apiVersion: metrics.keptn.sh/v1 +kind: Analysis +metadata: + labels: + app.kubernetes.io/name: analysis + app.kubernetes.io/instance: analysis-sample + app.kubernetes.io/part-of: metrics-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: metrics-operator + name: analysis-sample +spec: + timeframe: + recent: 5m + args: + project: my-project + stage: dev + service: svc1 + nodename: test + analysisDefinition: + name: ad-my-proj-dev-svc1 + namespace: keptn-system +status: + warning: true + state: Completed diff --git a/resource_customizations/metrics.keptn.sh/Analysis/testdata/progressing.yaml b/resource_customizations/metrics.keptn.sh/Analysis/testdata/progressing.yaml new file mode 100644 index 0000000000000..cd42e73b64471 --- /dev/null +++ b/resource_customizations/metrics.keptn.sh/Analysis/testdata/progressing.yaml @@ -0,0 +1,23 @@ +apiVersion: metrics.keptn.sh/v1 +kind: Analysis +metadata: + labels: + app.kubernetes.io/name: analysis + app.kubernetes.io/instance: analysis-sample + app.kubernetes.io/part-of: metrics-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: metrics-operator + name: analysis-sample +spec: + timeframe: + recent: 5m + args: + project: my-project + stage: dev + service: svc1 + nodename: test + analysisDefinition: + name: ad-my-proj-dev-svc1 + namespace: keptn-system +status: + state: Progressing diff --git a/resource_customizations/metrics.keptn.sh/KeptnMetric/health.lua b/resource_customizations/metrics.keptn.sh/KeptnMetric/health.lua new file mode 100644 index 0000000000000..0275f503c4ce2 --- /dev/null +++ b/resource_customizations/metrics.keptn.sh/KeptnMetric/health.lua @@ -0,0 +1,14 @@ +local hs = {} +if (obj.status.errMsg == nil or obj.status.errMsg == "") and obj.status.value ~= nil then + hs.status = "Healthy" + hs.message = "KeptnMetric is healthy" + return hs +end +if obj.status.errMsg ~= nil and obj.status.errMsg ~= "" then + hs.status = "Degraded" + hs.message = "KeptnMetric is degraded" + return hs +end +hs.status = "Progressing" +hs.message = "KeptnMetric is progressing" +return hs diff --git a/resource_customizations/metrics.keptn.sh/KeptnMetric/health_test.yaml b/resource_customizations/metrics.keptn.sh/KeptnMetric/health_test.yaml new file mode 100644 index 0000000000000..0f170f6f5f846 --- /dev/null +++ b/resource_customizations/metrics.keptn.sh/KeptnMetric/health_test.yaml @@ -0,0 +1,17 @@ +tests: + - healthStatus: + status: Progressing + message: "KeptnMetric is progressing" + inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: "KeptnMetric is degraded" + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: "KeptnMetric is healthy" + inputPath: testdata/healthy.yaml + - healthStatus: + status: Healthy + message: "KeptnMetric is healthy" + inputPath: testdata/healthy_empty_error.yaml diff --git a/resource_customizations/metrics.keptn.sh/KeptnMetric/testdata/degraded.yaml b/resource_customizations/metrics.keptn.sh/KeptnMetric/testdata/degraded.yaml new file mode 100644 index 0000000000000..cdd429bb8224b --- /dev/null +++ b/resource_customizations/metrics.keptn.sh/KeptnMetric/testdata/degraded.yaml @@ -0,0 +1,24 @@ +apiVersion: metrics.keptn.sh/v1 +kind: KeptnMetric +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"metrics.keptn.sh/v1","kind":"KeptnMetric","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"podtato-head"},"name":"available-cpus","namespace":"podtato-kubectl"},"spec":{"fetchIntervalSeconds":10,"provider":{"name":"my-provider"},"query":"sum(kube_node_status_capacity{resource='cpu'})"}} + creationTimestamp: '2024-07-16T07:34:42Z' + generation: 1 + labels: + app.kubernetes.io/instance: podtato-head + name: available-cpus + namespace: podtato-kubectl + resourceVersion: '405403' + uid: c448a014-b6b6-45a4-91ff-89949b9d0fce +spec: + fetchIntervalSeconds: 10 + provider: + name: my-provider + query: sum(kube_node_status_capacity{resource='cpu'}) +status: + errMsg: >- + Post "http://prometheus-k8s.monitoring.svc.cluster.local:9090/api/v1/query": + dial tcp: lookup prometheus-k8s.monitoring.svc.cluster.local on + lastUpdated: '2024-07-23T12:49:44Z' diff --git a/resource_customizations/metrics.keptn.sh/KeptnMetric/testdata/healthy.yaml b/resource_customizations/metrics.keptn.sh/KeptnMetric/testdata/healthy.yaml new file mode 100644 index 0000000000000..2c5ecad045350 --- /dev/null +++ b/resource_customizations/metrics.keptn.sh/KeptnMetric/testdata/healthy.yaml @@ -0,0 +1,22 @@ +apiVersion: metrics.keptn.sh/v1 +kind: KeptnMetric +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"metrics.keptn.sh/v1","kind":"KeptnMetric","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"podtato-head"},"name":"available-cpus","namespace":"podtato-kubectl"},"spec":{"fetchIntervalSeconds":10,"provider":{"name":"my-provider"},"query":"sum(kube_node_status_capacity{resource='cpu'})"}} + creationTimestamp: '2024-07-16T07:34:42Z' + generation: 1 + labels: + app.kubernetes.io/instance: podtato-head + name: available-cpus + namespace: podtato-kubectl + resourceVersion: '405403' + uid: c448a014-b6b6-45a4-91ff-89949b9d0fce +spec: + fetchIntervalSeconds: 10 + provider: + name: my-provider + query: sum(kube_node_status_capacity{resource='cpu'}) +status: + value: '100' + lastUpdated: '2024-07-23T12:49:44Z' diff --git a/resource_customizations/metrics.keptn.sh/KeptnMetric/testdata/healthy_empty_error.yaml b/resource_customizations/metrics.keptn.sh/KeptnMetric/testdata/healthy_empty_error.yaml new file mode 100644 index 0000000000000..758ccf9170a2a --- /dev/null +++ b/resource_customizations/metrics.keptn.sh/KeptnMetric/testdata/healthy_empty_error.yaml @@ -0,0 +1,23 @@ +apiVersion: metrics.keptn.sh/v1 +kind: KeptnMetric +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"metrics.keptn.sh/v1","kind":"KeptnMetric","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"podtato-head"},"name":"available-cpus","namespace":"podtato-kubectl"},"spec":{"fetchIntervalSeconds":10,"provider":{"name":"my-provider"},"query":"sum(kube_node_status_capacity{resource='cpu'})"}} + creationTimestamp: '2024-07-16T07:34:42Z' + generation: 1 + labels: + app.kubernetes.io/instance: podtato-head + name: available-cpus + namespace: podtato-kubectl + resourceVersion: '405403' + uid: c448a014-b6b6-45a4-91ff-89949b9d0fce +spec: + fetchIntervalSeconds: 10 + provider: + name: my-provider + query: sum(kube_node_status_capacity{resource='cpu'}) +status: + errMsg: "" + value: 100 + lastUpdated: '2024-07-23T12:49:44Z' diff --git a/resource_customizations/metrics.keptn.sh/KeptnMetric/testdata/progressing.yaml b/resource_customizations/metrics.keptn.sh/KeptnMetric/testdata/progressing.yaml new file mode 100644 index 0000000000000..71f219fbae7b4 --- /dev/null +++ b/resource_customizations/metrics.keptn.sh/KeptnMetric/testdata/progressing.yaml @@ -0,0 +1,21 @@ +apiVersion: metrics.keptn.sh/v1 +kind: KeptnMetric +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"metrics.keptn.sh/v1","kind":"KeptnMetric","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"podtato-head"},"name":"available-cpus","namespace":"podtato-kubectl"},"spec":{"fetchIntervalSeconds":10,"provider":{"name":"my-provider"},"query":"sum(kube_node_status_capacity{resource='cpu'})"}} + creationTimestamp: '2024-07-16T07:34:42Z' + generation: 1 + labels: + app.kubernetes.io/instance: podtato-head + name: available-cpus + namespace: podtato-kubectl + resourceVersion: '405403' + uid: c448a014-b6b6-45a4-91ff-89949b9d0fce +spec: + fetchIntervalSeconds: 10 + provider: + name: my-provider + query: sum(kube_node_status_capacity{resource='cpu'}) +status: + lastUpdated: '2024-07-23T12:49:44Z' diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/action_test.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/action_test.yaml new file mode 100644 index 0000000000000..acb19fbfce785 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/action_test.yaml @@ -0,0 +1,26 @@ +discoveryTests: +- inputPath: testdata/initial_alert.yaml + result: + - name: suspend + disabled: false + - name: resume + disabled: true +- inputPath: testdata/suspended_alert.yaml + result: + - name: suspend + disabled: true + - name: resume + disabled: false +- inputPath: testdata/resumed_alert.yaml + result: + - name: suspend + disabled: false + - name: resume + disabled: true +actionTests: +- action: suspend + inputPath: testdata/initial_alert.yaml + expectedOutputPath: testdata/suspended_alert.yaml +- action: resume + inputPath: testdata/suspended_alert.yaml + expectedOutputPath: testdata/resumed_alert.yaml diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/discovery.lua b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/discovery.lua new file mode 100644 index 0000000000000..f4c659d3d0f9c --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/discovery.lua @@ -0,0 +1,16 @@ +local actions = {} + +actions["suspend"] = {["disabled"] = true} +actions["resume"] = {["disabled"] = true} + +local suspend = false +if obj.spec.suspend ~= nil then + suspend = obj.spec.suspend +end +if suspend then + actions["resume"]["disabled"] = false +else + actions["suspend"]["disabled"] = false +end + +return actions diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/resume/action.lua b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/resume/action.lua new file mode 100644 index 0000000000000..cb41993777699 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/resume/action.lua @@ -0,0 +1,5 @@ +if obj.spec.suspend ~= nil and obj.spec.suspend then + obj.spec.suspend = false +end + +return obj diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/suspend/action.lua b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/suspend/action.lua new file mode 100644 index 0000000000000..1a338b2ad1361 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/suspend/action.lua @@ -0,0 +1,3 @@ +obj.spec.suspend = true + +return obj diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/testdata/initial_alert.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/testdata/initial_alert.yaml new file mode 100644 index 0000000000000..37ddc069c82f4 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/testdata/initial_alert.yaml @@ -0,0 +1,15 @@ +apiVersion: notification.toolkit.fluxcd.io/v1beta3 +kind: Alert +metadata: + name: slack + namespace: flux-system +spec: + summary: "Cluster addons impacted in us-east-2" + providerRef: + name: slack-bot + eventSeverity: error + eventSources: + - kind: GitRepository + name: '*' + - kind: Kustomization + name: '*' diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/testdata/resumed_alert.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/testdata/resumed_alert.yaml new file mode 100644 index 0000000000000..3a0a57ff5b258 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/testdata/resumed_alert.yaml @@ -0,0 +1,16 @@ +apiVersion: notification.toolkit.fluxcd.io/v1beta3 +kind: Alert +metadata: + name: slack + namespace: flux-system +spec: + summary: "Cluster addons impacted in us-east-2" + providerRef: + name: slack-bot + eventSeverity: error + eventSources: + - kind: GitRepository + name: '*' + - kind: Kustomization + name: '*' + suspend: false diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/testdata/suspended_alert.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/testdata/suspended_alert.yaml new file mode 100644 index 0000000000000..8f416896bc1ec --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Alert/actions/testdata/suspended_alert.yaml @@ -0,0 +1,16 @@ +apiVersion: notification.toolkit.fluxcd.io/v1beta3 +kind: Alert +metadata: + name: slack + namespace: flux-system +spec: + summary: "Cluster addons impacted in us-east-2" + providerRef: + name: slack-bot + eventSeverity: error + eventSources: + - kind: GitRepository + name: '*' + - kind: Kustomization + name: '*' + suspend: true diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/action_test.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/action_test.yaml new file mode 100644 index 0000000000000..4438d3ed13020 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/action_test.yaml @@ -0,0 +1,26 @@ +discoveryTests: +- inputPath: testdata/initial_provider.yaml + result: + - name: suspend + disabled: false + - name: resume + disabled: true +- inputPath: testdata/suspended_provider.yaml + result: + - name: suspend + disabled: true + - name: resume + disabled: false +- inputPath: testdata/resumed_provider.yaml + result: + - name: suspend + disabled: false + - name: resume + disabled: true +actionTests: +- action: suspend + inputPath: testdata/initial_provider.yaml + expectedOutputPath: testdata/suspended_provider.yaml +- action: resume + inputPath: testdata/suspended_provider.yaml + expectedOutputPath: testdata/resumed_provider.yaml diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/discovery.lua b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/discovery.lua new file mode 100644 index 0000000000000..f4c659d3d0f9c --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/discovery.lua @@ -0,0 +1,16 @@ +local actions = {} + +actions["suspend"] = {["disabled"] = true} +actions["resume"] = {["disabled"] = true} + +local suspend = false +if obj.spec.suspend ~= nil then + suspend = obj.spec.suspend +end +if suspend then + actions["resume"]["disabled"] = false +else + actions["suspend"]["disabled"] = false +end + +return actions diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/resume/action.lua b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/resume/action.lua new file mode 100644 index 0000000000000..cb41993777699 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/resume/action.lua @@ -0,0 +1,5 @@ +if obj.spec.suspend ~= nil and obj.spec.suspend then + obj.spec.suspend = false +end + +return obj diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/suspend/action.lua b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/suspend/action.lua new file mode 100644 index 0000000000000..1a338b2ad1361 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/suspend/action.lua @@ -0,0 +1,3 @@ +obj.spec.suspend = true + +return obj diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/testdata/initial_provider.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/testdata/initial_provider.yaml new file mode 100644 index 0000000000000..d53ecd3697b08 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/testdata/initial_provider.yaml @@ -0,0 +1,11 @@ +apiVersion: notification.toolkit.fluxcd.io/v1beta3 +kind: Provider +metadata: + name: slack-bot + namespace: flagger-system +spec: + type: slack + channel: general + address: https://slack.com/api/chat.postMessage + secretRef: + name: slack-bot-token diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/testdata/resumed_provider.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/testdata/resumed_provider.yaml new file mode 100644 index 0000000000000..684589b3bc45b --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/testdata/resumed_provider.yaml @@ -0,0 +1,12 @@ +apiVersion: notification.toolkit.fluxcd.io/v1beta3 +kind: Provider +metadata: + name: slack-bot + namespace: flagger-system +spec: + type: slack + channel: general + address: https://slack.com/api/chat.postMessage + secretRef: + name: slack-bot-token + suspend: false diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/testdata/suspended_provider.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/testdata/suspended_provider.yaml new file mode 100644 index 0000000000000..330e3a6116755 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Provider/actions/testdata/suspended_provider.yaml @@ -0,0 +1,12 @@ +apiVersion: notification.toolkit.fluxcd.io/v1beta3 +kind: Provider +metadata: + name: slack-bot + namespace: flagger-system +spec: + type: slack + channel: general + address: https://slack.com/api/chat.postMessage + secretRef: + name: slack-bot-token + suspend: true diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/action_test.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/action_test.yaml new file mode 100644 index 0000000000000..eff2eff163846 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/action_test.yaml @@ -0,0 +1,35 @@ +discoveryTests: +- inputPath: testdata/initial_receiver.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +- inputPath: testdata/suspended_receiver.yaml + result: + - name: reconcile + disabled: true + - name: suspend + disabled: true + - name: resume + disabled: false +- inputPath: testdata/resumed_receiver.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +actionTests: +- action: reconcile + inputPath: testdata/initial_receiver.yaml + expectedOutputPath: testdata/reconciled_receiver.yaml +- action: suspend + inputPath: testdata/initial_receiver.yaml + expectedOutputPath: testdata/suspended_receiver.yaml +- action: resume + inputPath: testdata/suspended_receiver.yaml + expectedOutputPath: testdata/resumed_receiver.yaml diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/discovery.lua b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/discovery.lua new file mode 100644 index 0000000000000..9000998815515 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/discovery.lua @@ -0,0 +1,18 @@ +local actions = {} + +actions["reconcile"] = {["disabled"] = true} +actions["suspend"] = {["disabled"] = true} +actions["resume"] = {["disabled"] = true} + +local suspend = false +if obj.spec.suspend ~= nil then + suspend = obj.spec.suspend +end +if suspend then + actions["resume"]["disabled"] = false +else + actions["reconcile"]["disabled"] = false + actions["suspend"]["disabled"] = false +end + +return actions diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/reconcile/action.lua b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/reconcile/action.lua new file mode 100644 index 0000000000000..a534b36fb3ebc --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/reconcile/action.lua @@ -0,0 +1,7 @@ +local os = require("os") +if obj.metadata.annotations == nil then + obj.metadata.annotations = {} +end +obj.metadata.annotations["reconcile.fluxcd.io/requestedAt"] = "By Argo CD at: " .. os.date("!%Y-%m-%dT%X") + +return obj diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/resume/action.lua b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/resume/action.lua new file mode 100644 index 0000000000000..cb41993777699 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/resume/action.lua @@ -0,0 +1,5 @@ +if obj.spec.suspend ~= nil and obj.spec.suspend then + obj.spec.suspend = false +end + +return obj diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/suspend/action.lua b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/suspend/action.lua new file mode 100644 index 0000000000000..1a338b2ad1361 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/suspend/action.lua @@ -0,0 +1,3 @@ +obj.spec.suspend = true + +return obj diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/testdata/initial_receiver.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/testdata/initial_receiver.yaml new file mode 100644 index 0000000000000..fa00d3e65de3e --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/testdata/initial_receiver.yaml @@ -0,0 +1,16 @@ +apiVersion: notification.toolkit.fluxcd.io/v1 +kind: Receiver +metadata: + name: github-receiver + namespace: flux-system +spec: + type: github + events: + - "ping" + - "push" + secretRef: + name: receiver-token + resources: + - apiVersion: source.toolkit.fluxcd.io/v1 + kind: GitRepository + name: flux-system diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/testdata/reconciled_receiver.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/testdata/reconciled_receiver.yaml new file mode 100644 index 0000000000000..90594de5b3331 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/testdata/reconciled_receiver.yaml @@ -0,0 +1,18 @@ +apiVersion: notification.toolkit.fluxcd.io/v1 +kind: Receiver +metadata: + name: github-receiver + namespace: flux-system + annotations: + reconcile.fluxcd.io/requestedAt: 'By Argo CD at: 0001-01-01T00:00:00' +spec: + type: github + events: + - "ping" + - "push" + secretRef: + name: receiver-token + resources: + - apiVersion: source.toolkit.fluxcd.io/v1 + kind: GitRepository + name: flux-system diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/testdata/resumed_receiver.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/testdata/resumed_receiver.yaml new file mode 100644 index 0000000000000..660d1cb0aed68 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/testdata/resumed_receiver.yaml @@ -0,0 +1,17 @@ +apiVersion: notification.toolkit.fluxcd.io/v1 +kind: Receiver +metadata: + name: github-receiver + namespace: flux-system +spec: + type: github + events: + - "ping" + - "push" + secretRef: + name: receiver-token + suspend: false + resources: + - apiVersion: source.toolkit.fluxcd.io/v1 + kind: GitRepository + name: flux-system diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/testdata/suspended_receiver.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/testdata/suspended_receiver.yaml new file mode 100644 index 0000000000000..b24fe8dda9aab --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/actions/testdata/suspended_receiver.yaml @@ -0,0 +1,17 @@ +apiVersion: notification.toolkit.fluxcd.io/v1 +kind: Receiver +metadata: + name: github-receiver + namespace: flux-system +spec: + type: github + events: + - "ping" + - "push" + secretRef: + name: receiver-token + suspend: true + resources: + - apiVersion: source.toolkit.fluxcd.io/v1 + kind: GitRepository + name: flux-system diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/health.lua b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/health.lua new file mode 100644 index 0000000000000..1586e9d50c8b5 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/health.lua @@ -0,0 +1,41 @@ +local hs = {} +if obj.spec.suspend ~= nil and obj.spec.suspend == true then + hs.message = obj.kind .. " is suspended" + hs.status = "Suspended" + return hs +end +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local numFailing = 0 + local numSucceeded = 0 + local message = "" + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + if condition.status == "True" then + numSucceeded = numSucceeded + 1 + elseif condition.status == "False" then + numFailing = numFailing + 1 + end + message = condition.reason + elseif condition.type == "Reconciling" and condition.status == "True" then + numFailing = numFailing + 1 + end + end + if(numFailing == 2) then + hs.message = message + hs.status = "Degraded" + return hs + elseif(numSucceeded == 1) then + hs.message = message + hs.status = "Healthy" + return hs + else + hs.message = message + hs.status = "Degraded" + return hs + end + end +end +hs.message = "Status unknown" +hs.status = "Progressing" +return hs diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/health_test.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/health_test.yaml new file mode 100644 index 0000000000000..7e4d4ea018273 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/health_test.yaml @@ -0,0 +1,13 @@ +tests: + # - healthStatus: + # status: Progressing + # message: Progressing + # inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: TokenNotFound + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: InstallSucceeded + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/testdata/degraded.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/testdata/degraded.yaml new file mode 100644 index 0000000000000..ba42fb102c85c --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/testdata/degraded.yaml @@ -0,0 +1,31 @@ +apiVersion: notification.toolkit.fluxcd.io/v1 +kind: Receiver +metadata: + name: github-receiver + namespace: flux-system +spec: + type: github + events: + - "ping" + - "push" + secretRef: + name: receiver-token + resources: + - apiVersion: source.toolkit.fluxcd.io/v1 + kind: GitRepository + name: flux-system +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Reconciliation in progress + observedGeneration: 1 + reason: ProgressingWithRetry + status: "True" + type: Reconciling + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'unable to read token from secret ''flux-system/receiver-token'' error: + secrets "receiver-token" not found' + observedGeneration: 1 + reason: TokenNotFound + status: "False" + type: Ready diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/testdata/healthy.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/testdata/healthy.yaml new file mode 100644 index 0000000000000..7b99499e98419 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/testdata/healthy.yaml @@ -0,0 +1,32 @@ +apiVersion: notification.toolkit.fluxcd.io/v1 +kind: Receiver +metadata: + name: github-receiver + namespace: flux-system +spec: + type: github + events: + - "ping" + - "push" + secretRef: + name: receiver-token + resources: + - apiVersion: source.toolkit.fluxcd.io/v1 + kind: GitRepository + name: flux-system +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Helm install succeeded for release flux-system/github-receiver.v1 with + chart podinfo@6.5.4 + observedGeneration: 2 + reason: InstallSucceeded + status: "True" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: Helm install succeeded for release flux-system/github-receiver.v1 with + chart podinfo@6.5.4 + observedGeneration: 1 + reason: InstallSucceeded + status: "True" + type: Released diff --git a/resource_customizations/notification.toolkit.fluxcd.io/Receiver/testdata/progressing.yaml b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/testdata/progressing.yaml new file mode 100644 index 0000000000000..78dccc33b7536 --- /dev/null +++ b/resource_customizations/notification.toolkit.fluxcd.io/Receiver/testdata/progressing.yaml @@ -0,0 +1,18 @@ +apiVersion: notification.toolkit.fluxcd.io/v1 +kind: Receiver +metadata: + name: github-receiver + namespace: flux-system +spec: + type: github + events: + - "ping" + - "push" + secretRef: + name: receiver-token + resources: + - apiVersion: source.toolkit.fluxcd.io/v1 + kind: GitRepository + name: flux-system +status: + conditions: [] diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health.lua b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health.lua new file mode 100644 index 0000000000000..1bcd2892b4160 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health.lua @@ -0,0 +1,32 @@ +local hs = {} +local healthyCondition = {} + +if obj.status ~= nil then + if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "ChildResourcesHealthy" then + healthyCondition = condition + end + end + end + + if obj.metadata.generation == obj.status.observedGeneration then + if (healthyCondition ~= {} and healthyCondition.status == "False" and (obj.metadata.generation == healthyCondition.observedGeneration) and healthyCondition.reason == "ISBSvcFailed") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message + end + return hs + elseif healthyCondition ~= {} and healthyCondition.status == "True" and (obj.metadata.generation == healthyCondition.observedGeneration) and obj.status.phase == "Deployed" then + hs.status = "Healthy" + hs.message = healthyCondition.message + return hs + end + end +end + +hs.status = "Progressing" +hs.message = "Waiting for 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 new file mode 100644 index 0000000000000..b0b683266c6eb --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/health_test.yaml @@ -0,0 +1,21 @@ +tests: +- healthStatus: + status: Progressing + message: "Waiting for ISBService status" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: "Successful" + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "ISBService Failed" + inputPath: testdata/degraded.yaml +- healthStatus: + status: Progressing + message: "Waiting for ISBService status" + inputPath: testdata/progressing-nostatus.yaml +- healthStatus: + status: Progressing + message: "Waiting for ISBService status" + inputPath: testdata/progressing-reason.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/degraded.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/degraded.yaml new file mode 100644 index 0000000000000..56429f44a13c6 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/degraded.yaml @@ -0,0 +1,40 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: ISBServiceRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '2' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"ISBServiceRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"2"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-isbsvc","namespace":"demo-app"},"spec":{"interStepBufferService":{"jetstream":{"persistence":{"volumeSize":"1Gi"},"version":"degraded"}}}} + creationTimestamp: '2024-07-12T20:56:22Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 6 + labels: + argocd.argoproj.io/instance: demo-app + name: my-isbsvc + namespace: demo-app + resourceVersion: '5515640' + uid: 0a364143-ddfb-4bb8-9a61-b17b7954de4b +spec: + interStepBufferService: + jetstream: + persistence: + volumeSize: 1Gi + version: degraded +status: + conditions: + - lastTransitionTime: '2024-07-15T22:38:02Z' + message: Successful + observedGeneration: 6 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-15T22:38:02Z' + message: ISBService Failed + observedGeneration: 6 + reason: ISBSvcFailed + status: 'False' + type: ChildResourcesHealthy + message: Deployed + observedGeneration: 6 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/healthy.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/healthy.yaml new file mode 100644 index 0000000000000..1ae59573cfffa --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/healthy.yaml @@ -0,0 +1,39 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: ISBServiceRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '2' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"ISBServiceRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"2"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-isbsvc","namespace":"demo-app"},"spec":{"interStepBufferService":{"jetstream":{"persistence":{"volumeSize":"1Gi"},"version":"latest"}}}} + creationTimestamp: '2024-07-12T20:56:22Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-isbsvc + namespace: demo-app + resourceVersion: '5455982' + uid: 0a364143-ddfb-4bb8-9a61-b17b7954de4b +spec: + interStepBufferService: + jetstream: + persistence: + volumeSize: 1Gi + version: latest +status: + conditions: + - lastTransitionTime: '2024-07-12T20:56:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-nostatus.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-nostatus.yaml new file mode 100644 index 0000000000000..3a886da092714 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-nostatus.yaml @@ -0,0 +1,23 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: ISBServiceRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '2' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"ISBServiceRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"2"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-isbsvc","namespace":"demo-app"},"spec":{"interStepBufferService":{"jetstream":{"persistence":{"volumeSize":"1Gi"},"version":"latest"}}}} + creationTimestamp: '2024-07-12T20:56:22Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 2 + labels: + argocd.argoproj.io/instance: demo-app + name: my-isbsvc + namespace: demo-app + resourceVersion: '5455982' + uid: 0a364143-ddfb-4bb8-9a61-b17b7954de4b +spec: + interStepBufferService: + jetstream: + persistence: + volumeSize: 1Gi + version: latest \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-reason.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-reason.yaml new file mode 100644 index 0000000000000..07dd50dc20d21 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing-reason.yaml @@ -0,0 +1,39 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: ISBServiceRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '2' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"ISBServiceRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"2"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-isbsvc","namespace":"demo-app"},"spec":{"interStepBufferService":{"jetstream":{"persistence":{"volumeSize":"1Gi"},"version":"latest"}}}} + creationTimestamp: '2024-07-12T20:56:22Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-isbsvc + namespace: demo-app + resourceVersion: '5455982' + uid: 0a364143-ddfb-4bb8-9a61-b17b7954de4b +spec: + interStepBufferService: + jetstream: + persistence: + volumeSize: 1Gi + version: latest +status: + conditions: + - lastTransitionTime: '2024-07-12T20:56:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:23Z' + message: Progressing + observedGeneration: 1 + reason: Progressing + status: 'False' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing.yaml b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing.yaml new file mode 100644 index 0000000000000..af9d3d0062433 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/ISBServiceRollout/testdata/progressing.yaml @@ -0,0 +1,39 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: ISBServiceRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '2' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"ISBServiceRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"2"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-isbsvc","namespace":"demo-app"},"spec":{"interStepBufferService":{"jetstream":{"persistence":{"volumeSize":"1Gi"},"version":"latest"}}}} + creationTimestamp: '2024-07-12T20:56:22Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 2 + labels: + argocd.argoproj.io/instance: demo-app + name: my-isbsvc + namespace: demo-app + resourceVersion: '5455982' + uid: 0a364143-ddfb-4bb8-9a61-b17b7954de4b +spec: + interStepBufferService: + jetstream: + persistence: + volumeSize: 1Gi + version: latest +status: + conditions: + - lastTransitionTime: '2024-07-12T20:56:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Deployed \ 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 new file mode 100644 index 0000000000000..2e221a7323649 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health.lua @@ -0,0 +1,32 @@ +local hs = {} +local healthyCondition = {} + +if obj.status ~= nil then + if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "ChildResourcesHealthy" then + healthyCondition = condition + end + end + end + + if obj.metadata.generation == obj.status.observedGeneration then + if (healthyCondition ~= {} and healthyCondition.status == "False" and (obj.metadata.generation == healthyCondition.observedGeneration) and healthyCondition.reason == "MonoVertexFailed") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message + end + return hs + elseif healthyCondition ~= {} and healthyCondition.status == "True" and (obj.metadata.generation == healthyCondition.observedGeneration) and obj.status.phase == "Deployed" then + hs.status = "Healthy" + hs.message = healthyCondition.message + return hs + end + end +end + +hs.status = "Progressing" +hs.message = "Waiting for MonoVertex status" +return hs \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml new file mode 100644 index 0000000000000..aee12b9ceb9c3 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/health_test.yaml @@ -0,0 +1,17 @@ +tests: +- healthStatus: + status: Progressing + message: "Waiting for MonoVertex status" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: "Successful" + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "MonoVertex Failed" + inputPath: testdata/degraded.yaml +- healthStatus: + status: Progressing + message: "Waiting for MonoVertex status" + inputPath: testdata/progressing-reason.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/degraded.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/degraded.yaml new file mode 100644 index 0000000000000..a6eedc9419f41 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/degraded.yaml @@ -0,0 +1,47 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: MonoVertexRollout +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"MonoVertexRollout","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-monovertex","namespace":"example-namespace"},"spec":{"monoVertex":{"spec":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}}}} + creationTimestamp: '2024-08-21T20:44:18Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-monovertex + namespace: example-namespace + resourceVersion: '947414' + uid: a63f377e-1500-437e-9267-579f4a790518 +spec: + monoVertex: + spec: + sink: + udsink: + container: + image: 'bad-image' + source: + transformer: + container: + image: 'quay.io/numaio/numaflow-rs/source-transformer-now:stable' + udsource: + container: + image: 'quay.io/numaio/numaflow-java/source-simple-source:stable' +status: + conditions: + - lastTransitionTime: '2024-08-21T20:44:18Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-08-22T21:10:23Z' + message: MonoVertex Failed + observedGeneration: 1 + reason: MonoVertexFailed + status: 'False' + type: ChildResourcesHealthy + message: Deployed + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/healthy.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/healthy.yaml new file mode 100644 index 0000000000000..ee9d76c826dc4 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/healthy.yaml @@ -0,0 +1,47 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: MonoVertexRollout +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"MonoVertexRollout","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-monovertex","namespace":"example-namespace"},"spec":{"monoVertex":{"spec":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}}}} + creationTimestamp: '2024-08-21T20:44:18Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-monovertex + namespace: example-namespace + resourceVersion: '947414' + uid: a63f377e-1500-437e-9267-579f4a790518 +spec: + monoVertex: + spec: + sink: + udsink: + container: + image: 'quay.io/numaio/numaflow-java/simple-sink:stable' + source: + transformer: + container: + image: 'quay.io/numaio/numaflow-rs/source-transformer-now:stable' + udsource: + container: + image: 'quay.io/numaio/numaflow-java/source-simple-source:stable' +status: + conditions: + - lastTransitionTime: '2024-08-21T20:44:18Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-08-22T21:10:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + message: Deployed + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing-reason.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing-reason.yaml new file mode 100644 index 0000000000000..3b147417e04d3 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing-reason.yaml @@ -0,0 +1,47 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: MonoVertexRollout +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"MonoVertexRollout","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-monovertex","namespace":"example-namespace"},"spec":{"monoVertex":{"spec":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}}}} + creationTimestamp: '2024-08-21T20:44:18Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-monovertex + namespace: example-namespace + resourceVersion: '947414' + uid: a63f377e-1500-437e-9267-579f4a790518 +spec: + monoVertex: + spec: + sink: + udsink: + container: + image: 'quay.io/numaio/numaflow-java/simple-sink:stable' + source: + transformer: + container: + image: 'quay.io/numaio/numaflow-rs/source-transformer-now:stable' + udsource: + container: + image: 'quay.io/numaio/numaflow-java/source-simple-source:stable' +status: + conditions: + - lastTransitionTime: '2024-08-21T20:44:18Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-08-22T21:10:23Z' + message: Progressing + observedGeneration: 1 + reason: Progressing + status: 'False' + type: ChildResourcesHealthy + message: Deployed + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing.yaml b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing.yaml new file mode 100644 index 0000000000000..14ebed98a3a85 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/MonoVertexRollout/testdata/progressing.yaml @@ -0,0 +1,47 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: MonoVertexRollout +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"MonoVertexRollout","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-monovertex","namespace":"example-namespace"},"spec":{"monoVertex":{"spec":{"sink":{"udsink":{"container":{"image":"quay.io/numaio/numaflow-java/simple-sink:stable"}}},"source":{"transformer":{"container":{"image":"quay.io/numaio/numaflow-rs/source-transformer-now:stable"}},"udsource":{"container":{"image":"quay.io/numaio/numaflow-java/source-simple-source:stable"}}}}}}} + creationTimestamp: '2024-08-21T20:44:18Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 2 + labels: + argocd.argoproj.io/instance: demo-app + name: my-monovertex + namespace: example-namespace + resourceVersion: '947414' + uid: a63f377e-1500-437e-9267-579f4a790518 +spec: + monoVertex: + spec: + sink: + udsink: + container: + image: 'quay.io/numaio/numaflow-java/simple-sink:stable' + source: + transformer: + container: + image: 'quay.io/numaio/numaflow-rs/source-transformer-now:stable' + udsource: + container: + image: 'quay.io/numaio/numaflow-java/source-simple-source:stable' +status: + conditions: + - lastTransitionTime: '2024-08-21T20:44:18Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-08-22T21:10:23Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + message: Deployed + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua new file mode 100644 index 0000000000000..9ff005740f6e8 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health.lua @@ -0,0 +1,32 @@ +local hs = {} +local healthyCondition = {} + +if obj.status ~= nil then + if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "ChildResourcesHealthy" then + healthyCondition = condition + end + end + end + + if obj.metadata.generation == obj.status.observedGeneration then + if (healthyCondition ~= {} and healthyCondition.status == "False" and (obj.metadata.generation == healthyCondition.observedGeneration) and healthyCondition.reason == "Degraded") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message + end + return hs + elseif healthyCondition ~= {} and healthyCondition.status == "True" and (obj.metadata.generation == healthyCondition.observedGeneration) and obj.status.phase == "Deployed" then + hs.status = "Healthy" + hs.message = healthyCondition.message + return hs + end + end +end + +hs.status = "Progressing" +hs.message = "Waiting for 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 new file mode 100644 index 0000000000000..30bb880f2d38a --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/health_test.yaml @@ -0,0 +1,17 @@ +tests: +- healthStatus: + status: Progressing + message: "Waiting for NumaflowController status" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: "Successful" + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "no controller definition found for version degraded" + inputPath: testdata/degraded.yaml +- healthStatus: + status: Progressing + message: "Waiting for NumaflowController status" + inputPath: testdata/progressing-reason.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/degraded.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/degraded.yaml new file mode 100644 index 0000000000000..4fa21c3195893 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/degraded.yaml @@ -0,0 +1,35 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: NumaflowControllerRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"NumaflowControllerRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"1"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"numaflow-controller","namespace":"demo-app"},"spec":{"controller":{"version":"xxx"}}} + creationTimestamp: '2024-07-12T20:56:20Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 4 + labels: + argocd.argoproj.io/instance: demo-app + name: numaflow-controller + namespace: demo-app + resourceVersion: '5514384' + uid: 904ab9bb-953e-4979-a124-5c92e8e25147 +spec: + controller: + version: degraded +status: + conditions: + - lastTransitionTime: '2024-07-15T22:29:52Z' + message: '' + reason: Unknown + status: Unknown + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-15T22:29:52Z' + message: '' + reason: Unknown + status: Unknown + type: ChildResourcesHealthy + message: no controller definition found for version degraded + observedGeneration: 4 + phase: Failed diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/healthy.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/healthy.yaml new file mode 100644 index 0000000000000..1efc00714e37b --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/healthy.yaml @@ -0,0 +1,36 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: NumaflowControllerRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"NumaflowControllerRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"1"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"numaflow-controller","namespace":"demo-app"},"spec":{"controller":{"version":"1.2.1"}}} + creationTimestamp: '2024-07-12T20:56:20Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: numaflow-controller + namespace: demo-app + resourceVersion: '5456204' + uid: 904ab9bb-953e-4979-a124-5c92e8e25147 +spec: + controller: + version: 1.2.1 +status: + conditions: + - lastTransitionTime: '2024-07-12T20:56:26Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:26Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Deployed diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing-reason.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing-reason.yaml new file mode 100644 index 0000000000000..e3c55cefc2c66 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing-reason.yaml @@ -0,0 +1,36 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: NumaflowControllerRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"NumaflowControllerRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"1"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"numaflow-controller","namespace":"demo-app"},"spec":{"controller":{"version":"1.2.1"}}} + creationTimestamp: '2024-07-12T20:56:20Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: numaflow-controller + namespace: demo-app + resourceVersion: '5456204' + uid: 904ab9bb-953e-4979-a124-5c92e8e25147 +spec: + controller: + version: 1.2.1 +status: + conditions: + - lastTransitionTime: '2024-07-12T20:56:26Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:26Z' + message: Progressing + observedGeneration: 1 + reason: Progressing + status: 'False' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing.yaml b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing.yaml new file mode 100644 index 0000000000000..e6c000df9d48a --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/NumaflowControllerRollout/testdata/progressing.yaml @@ -0,0 +1,36 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: NumaflowControllerRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '1' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"NumaflowControllerRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"1"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"numaflow-controller","namespace":"demo-app"},"spec":{"controller":{"version":"1.2.1"}}} + creationTimestamp: '2024-07-12T20:56:20Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 2 + labels: + argocd.argoproj.io/instance: demo-app + name: numaflow-controller + namespace: demo-app + resourceVersion: '5456204' + uid: 904ab9bb-953e-4979-a124-5c92e8e25147 +spec: + controller: + version: 1.2.1 +status: + conditions: + - lastTransitionTime: '2024-07-12T20:56:26Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:26Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Deployed \ 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 new file mode 100644 index 0000000000000..649cbb643d7f9 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health.lua @@ -0,0 +1,40 @@ +local hs = {} +local healthyCondition = {} +local pipelinePaused = {} + +if obj.status ~= nil then + if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "ChildResourcesHealthy" then + healthyCondition = condition + end + if condition.type == "PipelinePausingOrPaused" then + pipelinePaused = condition + end + end + end + + if obj.metadata.generation == obj.status.observedGeneration then + if (healthyCondition ~= {} and healthyCondition.status == "False" and (obj.metadata.generation == healthyCondition.observedGeneration) and healthyCondition.reason == "PipelineFailed") or obj.status.phase == "Failed" then + hs.status = "Degraded" + if obj.status.phase == "Failed" then + hs.message = obj.status.message + else + hs.message = healthyCondition.message + end + return hs + elseif (pipelinePaused ~= {} and pipelinePaused.status == "True") and (obj.metadata.generation == pipelinePaused.observedGeneration) then + hs.status = "Suspended" + hs.message = pipelinePaused.message + return hs + elseif (healthyCondition ~= {} and healthyCondition.status == "True") and (obj.metadata.generation == healthyCondition.observedGeneration) and obj.status.phase == "Deployed" then + hs.status = "Healthy" + hs.message = healthyCondition.message + return hs + end + end +end + +hs.status = "Progressing" +hs.message = "Waiting for Pipeline status" +return hs \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml new file mode 100644 index 0000000000000..99274d213992b --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/health_test.yaml @@ -0,0 +1,21 @@ +tests: +- healthStatus: + status: Progressing + message: "Waiting for Pipeline status" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Healthy + message: "Successful" + inputPath: testdata/healthy.yaml +- healthStatus: + status: Suspended + message: "Pipeline paused" + inputPath: testdata/paused.yaml +- healthStatus: + status: Degraded + message: "Pipeline Failed" + inputPath: testdata/degraded.yaml +- healthStatus: + status: Progressing + message: "Waiting for Pipeline status" + inputPath: testdata/progressing-reason.yaml \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/degraded.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/degraded.yaml new file mode 100644 index 0000000000000..81da0cb4ad8d8 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/degraded.yaml @@ -0,0 +1,59 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: PipelineRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '3' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"PipelineRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"3"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-other-pipeline","namespace":"demo-app"},"spec":{"pipeline":{"edges":[{"from":"in","to":"cat"},{"from":"cat","to":"out"},{"from":"cat","to":"out2"}],"interStepBufferServiceName":"my-isbsvc","vertices":[{"name":"in","source":{"generator":{"duration":"15s","rpu":5}}},{"name":"cat","udf":{"builtin":{"name":"cat"}}},{"name":"out","sink":{"log":{}}},{"name":"out2","sink":{"log":{}}}]}}} + creationTimestamp: '2024-07-12T20:56:24Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-other-pipeline + namespace: demo-app + resourceVersion: '5456110' + uid: 472d6284-b2d9-45ee-a159-fd4c3ad08d8c +spec: + pipeline: + edges: + - from: in + to: cat + - from: cat + to: out + - from: cat + to: out2 + interStepBufferServiceName: my-isbsvc + vertices: + - name: in + source: + generator: + duration: 15s + rpu: 5 + # - name: cat + # udf: + # builtin: + # name: cat + - name: out + sink: + log: {} + - name: out2 + sink: + log: {} +status: + conditions: + - lastTransitionTime: '2024-07-12T20:56:24Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:24Z' + message: Pipeline Failed + observedGeneration: 1 + reason: PipelineFailed + status: 'False' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/healthy.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/healthy.yaml new file mode 100644 index 0000000000000..842ef30e57889 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/healthy.yaml @@ -0,0 +1,59 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: PipelineRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '3' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"PipelineRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"3"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-other-pipeline","namespace":"demo-app"},"spec":{"pipeline":{"edges":[{"from":"in","to":"cat"},{"from":"cat","to":"out"},{"from":"cat","to":"out2"}],"interStepBufferServiceName":"my-isbsvc","vertices":[{"name":"in","source":{"generator":{"duration":"15s","rpu":5}}},{"name":"cat","udf":{"builtin":{"name":"cat"}}},{"name":"out","sink":{"log":{}}},{"name":"out2","sink":{"log":{}}}]}}} + creationTimestamp: '2024-07-12T20:56:24Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-other-pipeline + namespace: demo-app + resourceVersion: '5456110' + uid: 472d6284-b2d9-45ee-a159-fd4c3ad08d8c +spec: + pipeline: + edges: + - from: in + to: cat + - from: cat + to: out + - from: cat + to: out2 + interStepBufferServiceName: my-isbsvc + vertices: + - name: in + source: + generator: + duration: 15s + rpu: 5 + - name: cat + udf: + builtin: + name: cat + - name: out + sink: + log: {} + - name: out2 + sink: + log: {} +status: + conditions: + - lastTransitionTime: '2024-07-12T20:56:24Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:24Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/paused.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/paused.yaml new file mode 100644 index 0000000000000..8bd209bbfb2ea --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/paused.yaml @@ -0,0 +1,65 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: PipelineRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '3' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"PipelineRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"3"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-other-pipeline","namespace":"demo-app"},"spec":{"pipeline":{"edges":[{"from":"in","to":"cat"},{"from":"cat","to":"out"},{"from":"cat","to":"out2"}],"interStepBufferServiceName":"my-isbsvc","vertices":[{"name":"in","source":{"generator":{"duration":"15s","rpu":5}}},{"name":"cat","udf":{"builtin":{"name":"cat"}}},{"name":"out","sink":{"log":{}}},{"name":"out2","sink":{"log":{}}}]}}} + creationTimestamp: '2024-07-12T20:56:24Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-other-pipeline + namespace: demo-app + resourceVersion: '5458594' + uid: 472d6284-b2d9-45ee-a159-fd4c3ad08d8c +spec: + pipeline: + edges: + - from: in + to: cat + - from: cat + to: out + - from: cat + to: out2 + interStepBufferServiceName: my-isbsvc + vertices: + - name: in + source: + generator: + duration: 15s + rpu: 5 + - name: cat + udf: + builtin: + name: cat + - name: out + sink: + log: {} + - name: out2 + sink: + log: {} +status: + conditions: + - lastTransitionTime: '2024-07-12T21:14:18Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T21:14:18Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + - lastTransitionTime: '2024-07-12T21:14:17Z' + message: Pipeline paused + observedGeneration: 1 + reason: Paused + status: 'True' + type: PipelinePausingOrPaused + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing-reason.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing-reason.yaml new file mode 100644 index 0000000000000..5ec81c30145b3 --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing-reason.yaml @@ -0,0 +1,59 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: PipelineRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '3' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"PipelineRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"3"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-other-pipeline","namespace":"demo-app"},"spec":{"pipeline":{"edges":[{"from":"in","to":"cat"},{"from":"cat","to":"out"},{"from":"cat","to":"out2"}],"interStepBufferServiceName":"my-isbsvc","vertices":[{"name":"in","source":{"generator":{"duration":"15s","rpu":5}}},{"name":"cat","udf":{"builtin":{"name":"cat"}}},{"name":"out","sink":{"log":{}}},{"name":"out2","sink":{"log":{}}}]}}} + creationTimestamp: '2024-07-12T20:56:24Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 1 + labels: + argocd.argoproj.io/instance: demo-app + name: my-other-pipeline + namespace: demo-app + resourceVersion: '5456110' + uid: 472d6284-b2d9-45ee-a159-fd4c3ad08d8c +spec: + pipeline: + edges: + - from: in + to: cat + - from: cat + to: out + - from: cat + to: out2 + interStepBufferServiceName: my-isbsvc + vertices: + - name: in + source: + generator: + duration: 15s + rpu: 5 + - name: cat + udf: + builtin: + name: cat + - name: out + sink: + log: {} + - name: out2 + sink: + log: {} +status: + conditions: + - lastTransitionTime: '2024-07-12T20:56:24Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T20:56:24Z' + message: Progressing + observedGeneration: 1 + reason: Progressing + status: 'False' + type: ChildResourcesHealthy + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing.yaml b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing.yaml new file mode 100644 index 0000000000000..a161254fb0b8e --- /dev/null +++ b/resource_customizations/numaplane.numaproj.io/PipelineRollout/testdata/progressing.yaml @@ -0,0 +1,61 @@ +apiVersion: numaplane.numaproj.io/v1alpha1 +kind: PipelineRollout +metadata: + annotations: + argocd.argoproj.io/sync-wave: '3' + kubectl.kubernetes.io/last-applied-configuration: > + {"apiVersion":"numaplane.numaproj.io/v1alpha1","kind":"PipelineRollout","metadata":{"annotations":{"argocd.argoproj.io/sync-wave":"3"},"labels":{"argocd.argoproj.io/instance":"demo-app"},"name":"my-other-pipeline","namespace":"demo-app"},"spec":{"pipeline":{"edges":[{"from":"in","to":"cat"},{"from":"cat","to":"out"},{"from":"cat","to":"out2"}],"interStepBufferServiceName":"my-isbsvc","vertices":[{"name":"in","source":{"generator":{"duration":"15s","rpu":5}}},{"name":"out","sink":{"log":{}}},{"name":"out2","sink":{"log":{}}}]}}} + creationTimestamp: '2024-07-12T20:56:24Z' + finalizers: + - numaplane.numaproj.io/numaplane-controller + generation: 2 + labels: + argocd.argoproj.io/instance: demo-app + name: my-other-pipeline + namespace: demo-app + resourceVersion: '5461141' + uid: 472d6284-b2d9-45ee-a159-fd4c3ad08d8c +spec: + pipeline: + edges: + - from: in + to: cat + - from: cat + to: out + - from: cat + to: out2 + interStepBufferServiceName: my-isbsvc + vertices: + - name: in + source: + generator: + duration: 15s + rpu: 5 + - name: out + sink: + log: {} + - name: out2 + sink: + log: {} +status: + conditions: + - lastTransitionTime: '2024-07-12T21:31:03Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourceDeployed + - lastTransitionTime: '2024-07-12T21:31:03Z' + message: Successful + observedGeneration: 1 + reason: Successful + status: 'True' + type: ChildResourcesHealthy + - lastTransitionTime: '2024-07-12T21:14:17Z' + message: '' + observedGeneration: 1 + reason: Paused + status: 'True' + type: PipelinePausingOrPaused + observedGeneration: 1 + phase: Deployed \ No newline at end of file diff --git a/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/health.lua b/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/health.lua new file mode 100644 index 0000000000000..03cb9181447b7 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/health.lua @@ -0,0 +1,15 @@ +hs = {} +if obj.status == nil or obj.status.compliant == nil then + hs.status = "Progressing" + hs.message = "Waiting for the status to be reported" + return hs +end +if obj.status.compliant == "Compliant" then + hs.status = "Healthy" + hs.message = "All certificates found comply with the policy" + return hs +else + hs.status = "Degraded" + hs.message = "At least once certificate does not comply with the policy" + return hs +end diff --git a/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/health_test.yaml b/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/health_test.yaml new file mode 100644 index 0000000000000..017ce9ba50e60 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/health_test.yaml @@ -0,0 +1,13 @@ +tests: + - healthStatus: + status: Progressing + message: Waiting for the status to be reported + inputPath: testdata/progressing_no_status.yaml + - healthStatus: + status: Degraded + message: At least once certificate does not comply with the policy + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: All certificates found comply with the policy + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/testdata/degraded.yaml b/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/testdata/degraded.yaml new file mode 100644 index 0000000000000..4d44b3ad88d6e --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/testdata/degraded.yaml @@ -0,0 +1,34 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: CertificatePolicy +metadata: + name: policy-certificate + namespace: local-cluster +spec: + minimumDuration: 3000h + namespaceSelector: + exclude: + - kube-* + include: + - default + - cert-manager-operator + remediationAction: inform + severity: low +status: + compliancyDetails: + cert-manager-operator: + message: | + Found 1 non compliant certificates in the namespace cert-manager-operator. + List of non compliant certificates: + ca-root-secret expires in 2159h53m40.509362797s + nonCompliantCertificates: 1 + nonCompliantCertificatesList: + ca-root-secret: + ca: true + duration: 7776000000000000 + expiration: 2159h53m40.509362797s + expiry: 7775620509362797 + secretName: ca-root-secret + default: + message: | + Found 0 non compliant certificates in the namespace default. + compliant: NonCompliant diff --git a/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/testdata/healthy.yaml b/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/testdata/healthy.yaml new file mode 100644 index 0000000000000..8e999cf937ffd --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/testdata/healthy.yaml @@ -0,0 +1,24 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: CertificatePolicy +metadata: + name: policy-certificate + namespace: local-cluster +spec: + minimumDuration: 300h + namespaceSelector: + exclude: + - kube-* + include: + - default + - cert-manager-operator + remediationAction: inform + severity: low +status: + compliancyDetails: + cert-manager-operator: + message: | + Found 0 non compliant certificates in the namespace cert-manager-operator. + default: + message: | + Found 0 non compliant certificates in the namespace default. + compliant: Compliant diff --git a/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/testdata/progressing_no_status.yaml b/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/testdata/progressing_no_status.yaml new file mode 100644 index 0000000000000..5cb54c6075bb3 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/CertificatePolicy/testdata/progressing_no_status.yaml @@ -0,0 +1,15 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: CertificatePolicy +metadata: + name: policy-certificate + namespace: local-cluster +spec: + minimumDuration: 300h + namespaceSelector: + exclude: + - kube-* + include: + - default + - cert-manager-operator + remediationAction: inform + severity: low diff --git a/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/health.lua b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/health.lua new file mode 100644 index 0000000000000..5a4f936faa7c5 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/health.lua @@ -0,0 +1,33 @@ +hs = {} +if obj.status == nil or obj.status.compliant == nil then + hs.status = "Progressing" + hs.message = "Waiting for the status to be reported" + return hs +end +if obj.status.lastEvaluatedGeneration ~= obj.metadata.generation then + hs.status = "Progressing" + hs.message = "Waiting for the status to be updated" + return hs +end +if obj.status.compliant == "Compliant" then + hs.status = "Healthy" +else + hs.status = "Degraded" +end +if obj.status.compliancyDetails ~= nil then + messages = {} + for i, compliancy in ipairs(obj.status.compliancyDetails) do + if compliancy.conditions ~= nil then + for i, condition in ipairs(compliancy.conditions) do + if condition.message ~= nil and condition.type ~= nil then + table.insert(messages, condition.type .. " - " .. condition.message) + end + end + end + end + hs.message = table.concat(messages, "; ") + return hs +end +hs.status = "Progressing" +hs.message = "Waiting for compliance" +return hs diff --git a/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/health_test.yaml b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/health_test.yaml new file mode 100644 index 0000000000000..7eb34bbea2889 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/health_test.yaml @@ -0,0 +1,27 @@ +tests: + - healthStatus: + status: Progressing + message: Waiting for the status to be reported + inputPath: testdata/progressing_no_status.yaml + - healthStatus: + status: Degraded + message: >- + violation - namespaces [argo-example] not found; violation - namespaces + [argo-example-2] not found + inputPath: testdata/degraded.yaml + - healthStatus: + status: Progressing + message: Waiting for the status to be updated + inputPath: testdata/progressing.yaml + - healthStatus: + status: Healthy + message: >- + notification - namespaces [argo-example] was created successfully; + notification - namespaces [argo-example-2] was created successfully + inputPath: testdata/healthy_created.yaml + - healthStatus: + status: Healthy + message: >- + notification - namespaces [argo-example] found as specified; + notification - namespaces [argo-example-2] found as specified + inputPath: testdata/healthy_found.yaml diff --git a/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/degraded.yaml b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/degraded.yaml new file mode 100644 index 0000000000000..407c0e54620d2 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/degraded.yaml @@ -0,0 +1,61 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: ConfigurationPolicy +metadata: + name: policy-namespace + generation: 2 + namespace: local-cluster +spec: + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example + recreateOption: None + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example-2 + recreateOption: None + pruneObjectBehavior: None + remediationAction: inform + severity: low +status: + compliancyDetails: + - Compliant: NonCompliant + Validity: {} + conditions: + - lastTransitionTime: '2024-07-29T16:34:29Z' + message: 'namespaces [argo-example] not found' + reason: K8s does not have a `must have` object + status: 'True' + type: violation + - Compliant: NonCompliant + Validity: {} + conditions: + - lastTransitionTime: '2024-07-29T16:39:00Z' + message: 'namespaces [argo-example-2] not found' + reason: K8s does not have a `must have` object + status: 'True' + type: violation + compliant: NonCompliant + lastEvaluated: '2024-07-29T16:39:18Z' + lastEvaluatedGeneration: 2 + relatedObjects: + - compliant: NonCompliant + object: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example + reason: Resource not found but should exist + - compliant: NonCompliant + object: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example-2 + reason: Resource not found but should exist diff --git a/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/healthy_created.yaml b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/healthy_created.yaml new file mode 100644 index 0000000000000..36d5034053374 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/healthy_created.yaml @@ -0,0 +1,67 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: ConfigurationPolicy +metadata: + name: policy-namespace + generation: 3 + namespace: local-cluster +spec: + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example + recreateOption: None + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example-2 + recreateOption: None + pruneObjectBehavior: None + remediationAction: enforce + severity: low +status: + compliancyDetails: + - Compliant: Compliant + Validity: {} + conditions: + - lastTransitionTime: '2024-07-29T16:58:50Z' + message: 'namespaces [argo-example] was created successfully' + reason: K8s creation success + status: 'True' + type: notification + - Compliant: Compliant + Validity: {} + conditions: + - lastTransitionTime: '2024-07-29T16:58:50Z' + message: 'namespaces [argo-example-2] was created successfully' + reason: K8s creation success + status: 'True' + type: notification + compliant: Compliant + lastEvaluated: '2024-07-29T16:58:50Z' + lastEvaluatedGeneration: 3 + relatedObjects: + - compliant: Compliant + object: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example + properties: + createdByPolicy: true + uid: 782f50ee-4fa9-41d6-900e-66d9eaf8b111 + reason: K8s creation success + - compliant: Compliant + object: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example-2 + properties: + createdByPolicy: true + uid: ce34051f-a0dc-4db2-9f8f-64cc9223d4d7 + reason: K8s creation success diff --git a/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/healthy_found.yaml b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/healthy_found.yaml new file mode 100644 index 0000000000000..8975989c09529 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/healthy_found.yaml @@ -0,0 +1,67 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: ConfigurationPolicy +metadata: + name: policy-namespace + generation: 3 + namespace: local-cluster +spec: + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example + recreateOption: None + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example-2 + recreateOption: None + pruneObjectBehavior: None + remediationAction: enforce + severity: low +status: + compliancyDetails: + - Compliant: Compliant + Validity: {} + conditions: + - lastTransitionTime: '2024-07-29T16:58:59Z' + message: 'namespaces [argo-example] found as specified' + reason: K8s `must have` object already exists + status: 'True' + type: notification + - Compliant: Compliant + Validity: {} + conditions: + - lastTransitionTime: '2024-07-29T16:58:59Z' + message: 'namespaces [argo-example-2] found as specified' + reason: K8s `must have` object already exists + status: 'True' + type: notification + compliant: Compliant + lastEvaluated: '2024-07-29T16:59:26Z' + lastEvaluatedGeneration: 3 + relatedObjects: + - compliant: Compliant + object: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example + properties: + createdByPolicy: true + uid: 782f50ee-4fa9-41d6-900e-66d9eaf8b111 + reason: Resource found as expected + - compliant: Compliant + object: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example-2 + properties: + createdByPolicy: true + uid: ce34051f-a0dc-4db2-9f8f-64cc9223d4d7 + reason: Resource found as expected diff --git a/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/progressing.yaml b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/progressing.yaml new file mode 100644 index 0000000000000..1b2cd4860ea08 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/progressing.yaml @@ -0,0 +1,61 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: ConfigurationPolicy +metadata: + name: policy-namespace + generation: 3 + namespace: local-cluster +spec: + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example + recreateOption: None + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example-2 + recreateOption: None + pruneObjectBehavior: None + remediationAction: enforce + severity: low +status: + compliancyDetails: + - Compliant: NonCompliant + Validity: {} + conditions: + - lastTransitionTime: '2024-07-29T16:34:29Z' + message: 'namespaces [argo-example] not found' + reason: K8s does not have a `must have` object + status: 'True' + type: violation + - Compliant: NonCompliant + Validity: {} + conditions: + - lastTransitionTime: '2024-07-29T16:39:00Z' + message: 'namespaces [argo-example-2] not found' + reason: K8s does not have a `must have` object + status: 'True' + type: violation + compliant: NonCompliant + lastEvaluated: '2024-07-29T16:39:18Z' + lastEvaluatedGeneration: 2 + relatedObjects: + - compliant: NonCompliant + object: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example + reason: Resource not found but should exist + - compliant: NonCompliant + object: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example-2 + reason: Resource not found but should exist diff --git a/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/progressing_no_status.yaml b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/progressing_no_status.yaml new file mode 100644 index 0000000000000..1e43ce59ef121 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/ConfigurationPolicy/testdata/progressing_no_status.yaml @@ -0,0 +1,25 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: ConfigurationPolicy +metadata: + name: policy-namespace + generation: 2 + namespace: local-cluster +spec: + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example + recreateOption: None + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: argo-example-2 + recreateOption: None + pruneObjectBehavior: None + remediationAction: inform + severity: low diff --git a/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/health.lua b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/health.lua new file mode 100644 index 0000000000000..de8ed51192143 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/health.lua @@ -0,0 +1,26 @@ +hs = {} +if obj.status == nil or obj.status.conditions == nil then + hs.status = "Progressing" + hs.message = "Waiting for the status to be reported" + return hs +end +if obj.status.observedGeneration ~= nil and obj.status.observedGeneration ~= obj.metadata.generation then + hs.status = "Progressing" + hs.message = "Waiting for the status to be updated" + return hs +end +for i, condition in ipairs(obj.status.conditions) do + if condition.type == "Compliant" then + hs.message = condition.message + if condition.status == "True" then + hs.status = "Healthy" + return hs + else + hs.status = "Degraded" + return hs + end + end +end +hs.status = "Progressing" +hs.message = "Waiting for the compliance condition" +return hs diff --git a/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/health_test.yaml b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/health_test.yaml new file mode 100644 index 0000000000000..4c28366631eae --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/health_test.yaml @@ -0,0 +1,48 @@ +tests: + - healthStatus: + status: Progressing + message: Waiting for the status to be reported + inputPath: testdata/progressing_no_status.yaml + - healthStatus: + status: Degraded + message: >- + NonCompliant; the policy spec is valid, the policy does not specify an + OperatorGroup but one already exists in the namespace - assuming that + OperatorGroup is correct, the Subscription required by the policy was + not found, there are no relevant InstallPlans in the namespace, the + ClusterServiceVersion required by the policy was not found, no CRDs were + found for the operator, there are no relevant deployments because the + ClusterServiceVersion is missing, CatalogSource was found + inputPath: testdata/degraded.yaml + - healthStatus: + status: Progressing + message: Waiting for the status to be updated + inputPath: testdata/progressing_old_generation.yaml + - healthStatus: + status: Progressing + message: Waiting for the compliance condition + inputPath: testdata/progressing_no_compliance.yaml + - healthStatus: + status: Healthy + message: >- + Compliant; the policy spec is valid, the policy does not specify an + OperatorGroup but one already exists in the namespace - assuming that + OperatorGroup is correct, the Subscription matches what is required by + the policy, no InstallPlans requiring approval were found, + ClusterServiceVersion (argocd-operator.v0.11.0) - install strategy + completed with no errors, there are CRDs present for the operator, all + operator Deployments have their minimum availability, CatalogSource was + found + inputPath: testdata/healthy_no_generation.yaml + - healthStatus: + status: Healthy + message: >- + Compliant; the policy spec is valid, the policy does not specify an + OperatorGroup but one already exists in the namespace - assuming that + OperatorGroup is correct, the Subscription matches what is required by + the policy, no InstallPlans requiring approval were found, + ClusterServiceVersion (argocd-operator.v0.11.0) - install strategy + completed with no errors, there are CRDs present for the operator, all + operator Deployments have their minimum availability, CatalogSource was + found + inputPath: testdata/healthy_with_generation.yaml diff --git a/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/degraded.yaml b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/degraded.yaml new file mode 100644 index 0000000000000..1256bc25586bc --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/degraded.yaml @@ -0,0 +1,69 @@ +apiVersion: policy.open-cluster-management.io/v1beta1 +kind: OperatorPolicy +metadata: + name: install-argocd + generation: 1 + namespace: local-cluster +spec: + complianceConfig: + catalogSourceUnhealthy: Compliant + deploymentsUnavailable: NonCompliant + upgradesAvailable: Compliant + complianceType: musthave + remediationAction: inform + removalBehavior: + clusterServiceVersions: Delete + customResourceDefinitions: Keep + operatorGroups: DeleteIfUnused + subscriptions: Delete + severity: high + subscription: + channel: alpha + name: argocd-operator + source: community-operators + sourceNamespace: openshift-marketplace + upgradeApproval: None + versions: [] +status: + compliant: NonCompliant + conditions: + - lastTransitionTime: '2024-07-29T15:20:48Z' + message: CatalogSource was found + reason: CatalogSourcesFound + status: 'False' + type: CatalogSourcesUnhealthy + - lastTransitionTime: '2024-07-29T15:20:48Z' + message: >- + NonCompliant; the policy spec is valid, the policy does not specify an + OperatorGroup but one already exists in the namespace - assuming that + OperatorGroup is correct, the Subscription required by the policy was + not found, there are no relevant InstallPlans in the namespace, the + ClusterServiceVersion required by the policy was not found, no CRDs were + found for the operator, there are no relevant deployments because the + ClusterServiceVersion is missing, CatalogSource was found + reason: NonCompliant + status: 'False' + type: Compliant + - lastTransitionTime: '2024-07-29T15:20:48Z' + message: the Subscription required by the policy was not found + reason: SubscriptionMissing + status: 'False' + type: SubscriptionCompliant + relatedObjects: + - compliant: Compliant + object: + apiVersion: operators.coreos.com/v1alpha1 + kind: CatalogSource + metadata: + name: community-operators + namespace: openshift-marketplace + reason: Resource found as expected + - compliant: NonCompliant + object: + apiVersion: operators.coreos.com/v1alpha1 + kind: Subscription + metadata: + name: argocd-operator + namespace: openshift-operators + reason: Resource not found but should exist + resolvedSubscriptionLabel: argocd-operator.openshift-operators diff --git a/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/healthy_no_generation.yaml b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/healthy_no_generation.yaml new file mode 100644 index 0000000000000..39feedba5149b --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/healthy_no_generation.yaml @@ -0,0 +1,73 @@ +apiVersion: policy.open-cluster-management.io/v1beta1 +kind: OperatorPolicy +metadata: + name: install-argocd + generation: 2 + namespace: local-cluster +spec: + complianceConfig: + catalogSourceUnhealthy: Compliant + deploymentsUnavailable: NonCompliant + upgradesAvailable: Compliant + complianceType: musthave + remediationAction: enforce + removalBehavior: + clusterServiceVersions: Delete + customResourceDefinitions: Keep + operatorGroups: DeleteIfUnused + subscriptions: Delete + severity: high + subscription: + channel: alpha + name: argocd-operator + source: community-operators + sourceNamespace: openshift-marketplace + upgradeApproval: Automatic + versions: [] +status: + compliant: Compliant + conditions: + - lastTransitionTime: '2024-07-29T15:20:48Z' + message: CatalogSource was found + reason: CatalogSourcesFound + status: 'False' + type: CatalogSourcesUnhealthy + - lastTransitionTime: '2024-07-29T15:48:20Z' + message: >- + Compliant; the policy spec is valid, the policy does not specify an + OperatorGroup but one already exists in the namespace - assuming that + OperatorGroup is correct, the Subscription matches what is required by + the policy, no InstallPlans requiring approval were found, + ClusterServiceVersion (argocd-operator.v0.11.0) - install strategy + completed with no errors, there are CRDs present for the operator, all + operator Deployments have their minimum availability, CatalogSource was + found + reason: Compliant + status: 'True' + type: Compliant + - lastTransitionTime: '2024-07-29T15:47:45Z' + message: the Subscription matches what is required by the policy + reason: SubscriptionMatches + status: 'True' + type: SubscriptionCompliant + relatedObjects: + - compliant: Compliant + object: + apiVersion: operators.coreos.com/v1alpha1 + kind: CatalogSource + metadata: + name: community-operators + namespace: openshift-marketplace + reason: Resource found as expected + - compliant: Compliant + object: + apiVersion: operators.coreos.com/v1alpha1 + kind: Subscription + metadata: + name: argocd-operator + namespace: openshift-operators + properties: + createdByPolicy: true + uid: f3e6d8a7-eb73-4b29-b804-bf4609d2f7fb + reason: Resource found as expected + resolvedSubscriptionLabel: argocd-operator.openshift-operators diff --git a/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/healthy_with_generation.yaml b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/healthy_with_generation.yaml new file mode 100644 index 0000000000000..07d45c229b979 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/healthy_with_generation.yaml @@ -0,0 +1,74 @@ +apiVersion: policy.open-cluster-management.io/v1beta1 +kind: OperatorPolicy +metadata: + name: install-argocd + generation: 2 + namespace: local-cluster +spec: + complianceConfig: + catalogSourceUnhealthy: Compliant + deploymentsUnavailable: NonCompliant + upgradesAvailable: Compliant + complianceType: musthave + remediationAction: enforce + removalBehavior: + clusterServiceVersions: Delete + customResourceDefinitions: Keep + operatorGroups: DeleteIfUnused + subscriptions: Delete + severity: high + subscription: + channel: alpha + name: argocd-operator + source: community-operators + sourceNamespace: openshift-marketplace + upgradeApproval: Automatic + versions: [] +status: + compliant: Compliant + conditions: + - lastTransitionTime: '2024-07-29T15:20:48Z' + message: CatalogSource was found + reason: CatalogSourcesFound + status: 'False' + type: CatalogSourcesUnhealthy + - lastTransitionTime: '2024-07-29T15:48:20Z' + message: >- + Compliant; the policy spec is valid, the policy does not specify an + OperatorGroup but one already exists in the namespace - assuming that + OperatorGroup is correct, the Subscription matches what is required by + the policy, no InstallPlans requiring approval were found, + ClusterServiceVersion (argocd-operator.v0.11.0) - install strategy + completed with no errors, there are CRDs present for the operator, all + operator Deployments have their minimum availability, CatalogSource was + found + reason: Compliant + status: 'True' + type: Compliant + - lastTransitionTime: '2024-07-29T15:47:45Z' + message: the Subscription matches what is required by the policy + reason: SubscriptionMatches + status: 'True' + type: SubscriptionCompliant + observedGeneration: 2 + relatedObjects: + - compliant: Compliant + object: + apiVersion: operators.coreos.com/v1alpha1 + kind: CatalogSource + metadata: + name: community-operators + namespace: openshift-marketplace + reason: Resource found as expected + - compliant: Compliant + object: + apiVersion: operators.coreos.com/v1alpha1 + kind: Subscription + metadata: + name: argocd-operator + namespace: openshift-operators + properties: + createdByPolicy: true + uid: f3e6d8a7-eb73-4b29-b804-bf4609d2f7fb + reason: Resource found as expected + resolvedSubscriptionLabel: argocd-operator.openshift-operators diff --git a/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/progressing_no_compliance.yaml b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/progressing_no_compliance.yaml new file mode 100644 index 0000000000000..fdd7596aeb3c9 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/progressing_no_compliance.yaml @@ -0,0 +1,61 @@ +apiVersion: policy.open-cluster-management.io/v1beta1 +kind: OperatorPolicy +metadata: + name: install-argocd + generation: 2 + namespace: local-cluster +spec: + complianceConfig: + catalogSourceUnhealthy: Compliant + deploymentsUnavailable: NonCompliant + upgradesAvailable: Compliant + complianceType: musthave + remediationAction: enforce + removalBehavior: + clusterServiceVersions: Delete + customResourceDefinitions: Keep + operatorGroups: DeleteIfUnused + subscriptions: Delete + severity: high + subscription: + channel: alpha + name: argocd-operator + source: community-operators + sourceNamespace: openshift-marketplace + upgradeApproval: Automatic + versions: [] +status: + compliant: Compliant + conditions: + - lastTransitionTime: '2024-07-29T15:20:48Z' + message: CatalogSource was found + reason: CatalogSourcesFound + status: 'False' + type: CatalogSourcesUnhealthy + - lastTransitionTime: '2024-07-29T15:47:45Z' + message: the Subscription matches what is required by the policy + reason: SubscriptionMatches + status: 'True' + type: SubscriptionCompliant + observedGeneration: 2 + relatedObjects: + - compliant: Compliant + object: + apiVersion: operators.coreos.com/v1alpha1 + kind: CatalogSource + metadata: + name: community-operators + namespace: openshift-marketplace + reason: Resource found as expected + - compliant: Compliant + object: + apiVersion: operators.coreos.com/v1alpha1 + kind: Subscription + metadata: + name: argocd-operator + namespace: openshift-operators + properties: + createdByPolicy: true + uid: f3e6d8a7-eb73-4b29-b804-bf4609d2f7fb + reason: Resource found as expected + resolvedSubscriptionLabel: argocd-operator.openshift-operators diff --git a/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/progressing_no_status.yaml b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/progressing_no_status.yaml new file mode 100644 index 0000000000000..e40a779400243 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/progressing_no_status.yaml @@ -0,0 +1,26 @@ +apiVersion: policy.open-cluster-management.io/v1beta1 +kind: OperatorPolicy +metadata: + name: install-argocd + generation: 1 + namespace: local-cluster +spec: + complianceConfig: + catalogSourceUnhealthy: Compliant + deploymentsUnavailable: NonCompliant + upgradesAvailable: Compliant + complianceType: musthave + remediationAction: inform + removalBehavior: + clusterServiceVersions: Delete + customResourceDefinitions: Keep + operatorGroups: DeleteIfUnused + subscriptions: Delete + severity: high + subscription: + channel: alpha + name: argocd-operator + source: community-operators + sourceNamespace: openshift-marketplace + upgradeApproval: None + versions: [] diff --git a/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/progressing_old_generation.yaml b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/progressing_old_generation.yaml new file mode 100644 index 0000000000000..4cdbaad9f5a2e --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/OperatorPolicy/testdata/progressing_old_generation.yaml @@ -0,0 +1,63 @@ +apiVersion: policy.open-cluster-management.io/v1beta1 +kind: OperatorPolicy +metadata: + name: install-argocd + generation: 2 + namespace: local-cluster +spec: + complianceConfig: + catalogSourceUnhealthy: Compliant + deploymentsUnavailable: NonCompliant + upgradesAvailable: Compliant + complianceType: musthave + remediationAction: enforce + removalBehavior: + clusterServiceVersions: Delete + customResourceDefinitions: Keep + operatorGroups: DeleteIfUnused + subscriptions: Delete + severity: high + subscription: + channel: alpha + name: argocd-operator + source: community-operators + sourceNamespace: openshift-marketplace + upgradeApproval: Automatic + versions: [] +status: + compliant: NonCompliant + conditions: + - lastTransitionTime: '2024-07-29T15:20:48Z' + message: CatalogSource was found + reason: CatalogSourcesFound + status: 'False' + type: CatalogSourcesUnhealthy + - lastTransitionTime: '2024-07-29T15:20:48Z' + message: 'NonCompliant; the policy spec is valid, the policy does not specify an OperatorGroup but one already exists in the namespace - assuming that OperatorGroup is correct, the Subscription required by the policy was not found, there are no relevant InstallPlans in the namespace, the ClusterServiceVersion required by the policy was not found, no CRDs were found for the operator, there are no relevant deployments because the ClusterServiceVersion is missing, CatalogSource was found' + reason: NonCompliant + status: 'False' + type: Compliant + - lastTransitionTime: '2024-07-29T15:20:48Z' + message: the Subscription required by the policy was not found + reason: SubscriptionMissing + status: 'False' + type: SubscriptionCompliant + observedGeneration: 1 + relatedObjects: + - compliant: Compliant + object: + apiVersion: operators.coreos.com/v1alpha1 + kind: CatalogSource + metadata: + name: community-operators + namespace: openshift-marketplace + reason: Resource found as expected + - compliant: NonCompliant + object: + apiVersion: operators.coreos.com/v1alpha1 + kind: Subscription + metadata: + name: argocd-operator + namespace: openshift-operators + reason: Resource not found but should exist + resolvedSubscriptionLabel: argocd-operator.openshift-operators diff --git a/resource_customizations/policy.open-cluster-management.io/Policy/health.lua b/resource_customizations/policy.open-cluster-management.io/Policy/health.lua new file mode 100644 index 0000000000000..9b43c04c4b5e7 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/Policy/health.lua @@ -0,0 +1,38 @@ +hs = {} +if obj.status == nil or obj.status.compliant == nil then + hs.status = "Progressing" + hs.message = "Waiting for the status to be reported" + return hs +end +if obj.status.compliant == "Compliant" then + hs.status = "Healthy" +else + hs.status = "Degraded" +end +noncompliants = {} +if obj.status.status ~= nil then + -- "root" policy + for i, entry in ipairs(obj.status.status) do + if entry.compliant ~= "Compliant" then + noncompliants[i] = entry.clustername + end + end + if table.getn(noncompliants) == 0 then + hs.message = "All clusters are compliant" + else + hs.message = "NonCompliant clusters: " .. table.concat(noncompliants, ", ") + end +elseif obj.status.details ~= nil then + -- "replicated" policy + for i, entry in ipairs(obj.status.details) do + if entry.compliant ~= "Compliant" then + noncompliants[i] = entry.templateMeta.name + end + end + if table.getn(noncompliants) == 0 then + hs.message = "All templates are compliant" + else + hs.message = "NonCompliant templates: " .. table.concat(noncompliants, ", ") + end +end +return hs diff --git a/resource_customizations/policy.open-cluster-management.io/Policy/health_test.yaml b/resource_customizations/policy.open-cluster-management.io/Policy/health_test.yaml new file mode 100644 index 0000000000000..ede9cc5c8a2c0 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/Policy/health_test.yaml @@ -0,0 +1,17 @@ +tests: + - healthStatus: + status: Degraded + message: 'NonCompliant clusters: local-cluster, managed' + inputPath: testdata/degraded_root.yaml + - healthStatus: + status: Degraded + message: 'NonCompliant templates: example-namespace' + inputPath: testdata/degraded_replicated.yaml + - healthStatus: + status: Healthy + message: All clusters are compliant + inputPath: testdata/healthy_root.yaml + - healthStatus: + status: Healthy + message: All templates are compliant + inputPath: testdata/healthy_replicated.yaml diff --git a/resource_customizations/policy.open-cluster-management.io/Policy/testdata/degraded_replicated.yaml b/resource_customizations/policy.open-cluster-management.io/Policy/testdata/degraded_replicated.yaml new file mode 100644 index 0000000000000..5a0c3305fc4d6 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/Policy/testdata/degraded_replicated.yaml @@ -0,0 +1,80 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: Policy +metadata: + name: open-cluster-management-global-set.argo-example + namespace: local-cluster + labels: + policy.open-cluster-management.io/cluster-name: local-cluster + policy.open-cluster-management.io/cluster-namespace: local-cluster + policy.open-cluster-management.io/root-policy: open-cluster-management-global-set.argo-example +spec: + disabled: false + policy-templates: + - objectDefinition: + apiVersion: policy.open-cluster-management.io/v1 + kind: ConfigurationPolicy + metadata: + name: example-namespace + spec: + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: example + remediationAction: inform + severity: low + - objectDefinition: + apiVersion: policy.open-cluster-management.io/v1 + kind: ConfigurationPolicy + metadata: + name: example-pod + spec: + namespaceSelector: + exclude: + - kube-* + include: + - default + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Pod + metadata: + name: foobar + spec: + containers: + - image: 'registry.redhat.io/rhel9/httpd-24:latest' + name: httpd + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + runAsNonRoot: true + remediationAction: enforce + severity: low +status: + compliant: NonCompliant + details: + - compliant: NonCompliant + history: + - eventName: open-cluster-management-global-set.argo-example.17e701cc5101e3a4 + lastTimestamp: '2024-07-30T13:49:19Z' + message: 'NonCompliant; violation - namespaces [example] not found' + templateMeta: + creationTimestamp: null + name: example-namespace + - compliant: Compliant + history: + - eventName: open-cluster-management-global-set.argo-example.17e7034c879045a3 + lastTimestamp: '2024-07-30T14:16:49Z' + message: 'Compliant; notification - pods [foobar] was created successfully in namespace default' + - eventName: open-cluster-management-global-set.argo-example.17e7020b47782ddc + lastTimestamp: '2024-07-30T13:53:49Z' + message: 'NonCompliant; violation - pods [foobar] not found in namespace default' + templateMeta: + creationTimestamp: null + name: example-pod diff --git a/resource_customizations/policy.open-cluster-management.io/Policy/testdata/degraded_root.yaml b/resource_customizations/policy.open-cluster-management.io/Policy/testdata/degraded_root.yaml new file mode 100644 index 0000000000000..62c54297c4240 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/Policy/testdata/degraded_root.yaml @@ -0,0 +1,68 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: Policy +metadata: + generation: 2 + name: argo-example + namespace: open-cluster-management-global-set +spec: + disabled: false + policy-templates: + - objectDefinition: + apiVersion: policy.open-cluster-management.io/v1 + kind: ConfigurationPolicy + metadata: + name: example-namespace + spec: + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: example + remediationAction: inform + severity: low + - objectDefinition: + apiVersion: policy.open-cluster-management.io/v1 + kind: ConfigurationPolicy + metadata: + name: example-pod + spec: + namespaceSelector: + exclude: + - kube-* + include: + - default + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Pod + metadata: + name: foobar + spec: + containers: + - image: 'registry.redhat.io/rhel9/httpd-24:latest' + name: httpd + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + runAsNonRoot: true + remediationAction: inform + severity: low + remediationAction: inform +status: + compliant: NonCompliant + placement: + - placement: argo-example-placement + placementBinding: argo-example-placement + status: + - clustername: local-cluster + clusternamespace: local-cluster + compliant: NonCompliant + - clustername: managed + clusternamespace: managed + compliant: NonCompliant diff --git a/resource_customizations/policy.open-cluster-management.io/Policy/testdata/healthy_replicated.yaml b/resource_customizations/policy.open-cluster-management.io/Policy/testdata/healthy_replicated.yaml new file mode 100644 index 0000000000000..132311cf2bdf3 --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/Policy/testdata/healthy_replicated.yaml @@ -0,0 +1,91 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: Policy +metadata: + name: open-cluster-management-global-set.argo-example + generation: 4 + namespace: local-cluster + labels: + policy.open-cluster-management.io/cluster-name: local-cluster + policy.open-cluster-management.io/cluster-namespace: local-cluster + policy.open-cluster-management.io/root-policy: open-cluster-management-global-set.argo-example +spec: + disabled: false + policy-templates: + - objectDefinition: + apiVersion: policy.open-cluster-management.io/v1 + kind: ConfigurationPolicy + metadata: + name: example-namespace + spec: + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: example + remediationAction: inform + severity: low + - objectDefinition: + apiVersion: policy.open-cluster-management.io/v1 + kind: ConfigurationPolicy + metadata: + name: example-pod + spec: + namespaceSelector: + exclude: + - kube-* + include: + - default + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Pod + metadata: + name: foobar + spec: + containers: + - image: 'registry.redhat.io/rhel9/httpd-24:latest' + name: httpd + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + runAsNonRoot: true + remediationAction: inform + severity: low + remediationAction: inform +status: + compliant: Compliant + details: + - compliant: Compliant + history: + - eventName: open-cluster-management-global-set.argo-example.17e703831ab809b3 + lastTimestamp: '2024-07-30T14:20:44Z' + message: 'Compliant; notification - namespaces [example] found as specified' + - eventName: open-cluster-management-global-set.argo-example.17e703810146765a + lastTimestamp: '2024-07-30T14:20:35Z' + message: 'Compliant; notification - namespaces [example] was created successfully' + - eventName: open-cluster-management-global-set.argo-example.17e701cc5101e3a4 + lastTimestamp: '2024-07-30T13:49:19Z' + message: 'NonCompliant; violation - namespaces [example] not found' + templateMeta: + creationTimestamp: null + name: example-namespace + - compliant: Compliant + history: + - eventName: open-cluster-management-global-set.argo-example.17e7034ea145078e + lastTimestamp: '2024-07-30T14:16:58Z' + message: 'Compliant; notification - pods [foobar] found as specified in namespace default' + - eventName: open-cluster-management-global-set.argo-example.17e7034c879045a3 + lastTimestamp: '2024-07-30T14:16:49Z' + message: 'Compliant; notification - pods [foobar] was created successfully in namespace default' + - eventName: open-cluster-management-global-set.argo-example.17e7020b47782ddc + lastTimestamp: '2024-07-30T13:53:49Z' + message: 'NonCompliant; violation - pods [foobar] not found in namespace default' + templateMeta: + creationTimestamp: null + name: example-pod diff --git a/resource_customizations/policy.open-cluster-management.io/Policy/testdata/healthy_root.yaml b/resource_customizations/policy.open-cluster-management.io/Policy/testdata/healthy_root.yaml new file mode 100644 index 0000000000000..e46b8a7db147c --- /dev/null +++ b/resource_customizations/policy.open-cluster-management.io/Policy/testdata/healthy_root.yaml @@ -0,0 +1,68 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: Policy +metadata: + generation: 4 + name: argo-example + namespace: open-cluster-management-global-set +spec: + disabled: false + policy-templates: + - objectDefinition: + apiVersion: policy.open-cluster-management.io/v1 + kind: ConfigurationPolicy + metadata: + name: example-namespace + spec: + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Namespace + metadata: + name: example + remediationAction: inform + severity: low + - objectDefinition: + apiVersion: policy.open-cluster-management.io/v1 + kind: ConfigurationPolicy + metadata: + name: example-pod + spec: + namespaceSelector: + exclude: + - kube-* + include: + - default + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Pod + metadata: + name: foobar + spec: + containers: + - image: 'registry.redhat.io/rhel9/httpd-24:latest' + name: httpd + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + runAsNonRoot: true + remediationAction: inform + severity: low + remediationAction: inform +status: + compliant: Compliant + placement: + - placement: argo-example-placement + placementBinding: argo-example-placement + status: + - clustername: local-cluster + clusternamespace: local-cluster + compliant: Compliant + - clustername: managed + clusternamespace: managed + compliant: Compliant diff --git a/resource_customizations/policy/PodDisruptionBudget/health.lua b/resource_customizations/policy/PodDisruptionBudget/health.lua new file mode 100644 index 0000000000000..afaa61752cb67 --- /dev/null +++ b/resource_customizations/policy/PodDisruptionBudget/health.lua @@ -0,0 +1,23 @@ +-- Reference CRD can be found here: +-- https://kubernetes.io/docs/reference/kubernetes-api/policy-resources/pod-disruption-budget-v1/ +hs = {} +hs.status = "Progressing" +hs.message = "Waiting for status" + +if obj.status ~= nil then + if obj.status.conditions ~= nil then + for i, condition in ipairs(obj.status.conditions) do + if condition.status == "False" then + hs.status = "Degraded" + hs.message = "PodDisruptionBudget has " .. condition.reason + return hs + end + if condition.status == "True" then + hs.status = "Healthy" + hs.message = "PodDisruptionBudget has " .. condition.reason + end + end + end +end + +return hs diff --git a/resource_customizations/policy/PodDisruptionBudget/health_test.yaml b/resource_customizations/policy/PodDisruptionBudget/health_test.yaml new file mode 100644 index 0000000000000..3ad31b60186ee --- /dev/null +++ b/resource_customizations/policy/PodDisruptionBudget/health_test.yaml @@ -0,0 +1,13 @@ +tests: +- healthStatus: + status: Healthy + message: 'PodDisruptionBudget has SufficientPods' + inputPath: testdata/healthy.yaml +- healthStatus: + status: Progressing + message: 'Waiting for status' + inputPath: testdata/progressing.yaml +- healthStatus: + status: Degraded + message: 'PodDisruptionBudget has InsufficientPods' + inputPath: testdata/degraded.yaml diff --git a/resource_customizations/policy/PodDisruptionBudget/testdata/degraded.yaml b/resource_customizations/policy/PodDisruptionBudget/testdata/degraded.yaml new file mode 100644 index 0000000000000..2c2a854e8bc52 --- /dev/null +++ b/resource_customizations/policy/PodDisruptionBudget/testdata/degraded.yaml @@ -0,0 +1,23 @@ +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: foo + namespace: bar +spec: + minAvailable: 3 + selector: + matchLabels: + app.kubernetes.io/name: foo +status: + conditions: + - lastTransitionTime: "2024-09-06T18:29:05Z" + message: "" + observedGeneration: 2 + reason: InsufficientPods + status: "False" + type: DisruptionAllowed + currentHealthy: 2 + desiredHealthy: 3 + disruptionsAllowed: 0 + expectedPods: 2 + observedGeneration: 2 diff --git a/resource_customizations/policy/PodDisruptionBudget/testdata/healthy.yaml b/resource_customizations/policy/PodDisruptionBudget/testdata/healthy.yaml new file mode 100644 index 0000000000000..9a971588a6820 --- /dev/null +++ b/resource_customizations/policy/PodDisruptionBudget/testdata/healthy.yaml @@ -0,0 +1,23 @@ +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: foo + namespace: bar +spec: + minAvailable: 1 + selector: + matchLabels: + app.kubernetes.io/name: foo +status: + conditions: + - lastTransitionTime: "2024-09-06T18:29:05Z" + message: "" + observedGeneration: 1 + reason: SufficientPods + status: "True" + type: DisruptionAllowed + currentHealthy: 2 + desiredHealthy: 1 + disruptionsAllowed: 1 + expectedPods: 2 + observedGeneration: 1 diff --git a/resource_customizations/policy/PodDisruptionBudget/testdata/progressing.yaml b/resource_customizations/policy/PodDisruptionBudget/testdata/progressing.yaml new file mode 100644 index 0000000000000..3edcc7fd4cfa2 --- /dev/null +++ b/resource_customizations/policy/PodDisruptionBudget/testdata/progressing.yaml @@ -0,0 +1,10 @@ +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: foo + namespace: default +spec: + minAvailable: 1 + selector: + matchLabels: + app.kubernetes.io/name: foo diff --git a/resource_customizations/rabbitmq.com/RabbitmqCluster/health.lua b/resource_customizations/rabbitmq.com/RabbitmqCluster/health.lua new file mode 100644 index 0000000000000..22916ad6f84cd --- /dev/null +++ b/resource_customizations/rabbitmq.com/RabbitmqCluster/health.lua @@ -0,0 +1,53 @@ +hs = {} +clusterAvailable = {} +allReplicasReady = {} + +if obj.status ~= nil then + if obj.status.conditions ~= nil then + + for i, condition in ipairs(obj.status.conditions) do + if condition.type == "ReconcileSuccess" and condition.status == "False" then + hs.status = "Degraded" + hs.message = condition.message + return hs + end + if condition.type == "ClusterAvailable" then + clusterAvailable.status = condition.status + clusterAvailable.message = condition.message + end + if condition.type == "AllReplicasReady" then + allReplicasReady.status = condition.status + allReplicasReady.message = condition.message + end + end + + if clusterAvailable.status == "Unknown" or allReplicasReady.status == "Unknown" then + hs.status = "Degraded" + hs.message = "No statefulset or endpoints found" + return hs + end + + if clusterAvailable.status == "False" then + hs.status = "Progressing" + hs.message = "Waiting for RabbitMQ cluster formation" + return hs + end + + if allReplicasReady.status == "False" then + hs.status = "Progressing" + hs.message = "Waiting for RabbitMQ instances ready" + return hs + end + + if clusterAvailable.status == "True" and allReplicasReady.status == "True" then + hs.status = "Healthy" + hs.message = "RabbitMQ cluster ready" + return hs + end + + end +end + +hs.status = "Progressing" +hs.message = "Waiting for RabbitMQ Operator" +return hs \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/RabbitmqCluster/health_test.yaml b/resource_customizations/rabbitmq.com/RabbitmqCluster/health_test.yaml new file mode 100644 index 0000000000000..7e7c44e4b57ce --- /dev/null +++ b/resource_customizations/rabbitmq.com/RabbitmqCluster/health_test.yaml @@ -0,0 +1,29 @@ +tests: +- healthStatus: + status: Degraded + message: Unknown 'foo' parameter + inputPath: testdata/degraded_badconfig.yaml +- healthStatus: + status: Degraded + message: No statefulset or endpoints found + inputPath: testdata/degraded_cluster_unknown.yaml +- healthStatus: + status: Degraded + message: No statefulset or endpoints found + inputPath: testdata/degraded_replicas_unknown.yaml +- healthStatus: + status: Progressing + message: Waiting for RabbitMQ Operator + inputPath: testdata/progressing_no_status.yaml +- healthStatus: + status: Progressing + message: Waiting for RabbitMQ cluster formation + inputPath: testdata/progressing_cluster_unavailable.yaml +- healthStatus: + status: Progressing + message: Waiting for RabbitMQ instances ready + inputPath: testdata/progressing_pods_not_ready.yaml +- healthStatus: + status: Healthy + message: RabbitMQ cluster ready + inputPath: testdata/healthy.yaml \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/degraded_badconfig.yaml b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/degraded_badconfig.yaml new file mode 100644 index 0000000000000..29b03cb406ccb --- /dev/null +++ b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/degraded_badconfig.yaml @@ -0,0 +1,31 @@ +apiVersion: rabbitmq.com/v1beta1 +kind: RabbitmqCluster +metadata: + labels: + app: example-rabbitmq + name: example-rabbitmq + namespace: example +spec: + image: docker.io/bitnami/rabbitmq:3.10.7-debian-11-r8 + persistence: + storage: 32Gi + storageClassName: default + rabbitmq: + replicas: 3 + resources: + limits: + cpu: 250m + memory: 1792Mi + requests: + cpu: 250m + memory: 1792Mi + service: + type: ClusterIP + foo: bar +status: + conditions: + - lastTransitionTime: "2023-08-30T07:44:39Z" + message: Unknown 'foo' parameter + reason: Initializing + status: "False" + type: ReconcileSuccess \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/degraded_cluster_unknown.yaml b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/degraded_cluster_unknown.yaml new file mode 100644 index 0000000000000..86b7be4bd468b --- /dev/null +++ b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/degraded_cluster_unknown.yaml @@ -0,0 +1,44 @@ +apiVersion: rabbitmq.com/v1beta1 +kind: RabbitmqCluster +metadata: + labels: + app: example-rabbitmq + name: example-rabbitmq + namespace: example +spec: + image: docker.io/bitnami/rabbitmq:3.10.7-debian-11-r8 + persistence: + storage: 32Gi + storageClassName: default + rabbitmq: + replicas: 3 + resources: + limits: + cpu: 250m + memory: 1792Mi + requests: + cpu: 250m + memory: 1792Mi + service: + type: ClusterIP +status: + conditions: + - lastTransitionTime: "2023-08-30T07:44:34Z" + reason: NotAllPodsReady + message: 0/3 Pods ready + status: "False" + type: AllReplicasReady + - lastTransitionTime: "2023-08-30T07:37:06Z" + reason: CouldNotRetrieveEndpoints + message: Could not verify available service endpoints + status: "Unknown" + type: ClusterAvailable + - lastTransitionTime: "2023-08-30T07:33:06Z" + reason: NoWarnings + status: "True" + type: NoWarnings + - lastTransitionTime: "2023-08-30T07:44:39Z" + message: Finish reconciling + reason: Success + status: "True" + type: ReconcileSuccess \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/degraded_replicas_unknown.yaml b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/degraded_replicas_unknown.yaml new file mode 100644 index 0000000000000..f92f5afd66d17 --- /dev/null +++ b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/degraded_replicas_unknown.yaml @@ -0,0 +1,44 @@ +apiVersion: rabbitmq.com/v1beta1 +kind: RabbitmqCluster +metadata: + labels: + app: example-rabbitmq + name: example-rabbitmq + namespace: example +spec: + image: docker.io/bitnami/rabbitmq:3.10.7-debian-11-r8 + persistence: + storage: 32Gi + storageClassName: default + rabbitmq: + replicas: 3 + resources: + limits: + cpu: 250m + memory: 1792Mi + requests: + cpu: 250m + memory: 1792Mi + service: + type: ClusterIP +status: + conditions: + - lastTransitionTime: "2023-08-30T07:44:34Z" + reason: MissingStatefulSet + message: Could not find StatefulSet + status: "Unknown" + type: AllReplicasReady + - lastTransitionTime: "2023-08-30T07:37:06Z" + reason: NoEndpointsAvailable + message: The service has no endpoints available + status: "False" + type: ClusterAvailable + - lastTransitionTime: "2023-08-30T07:33:06Z" + reason: NoWarnings + status: "True" + type: NoWarnings + - lastTransitionTime: "2023-08-30T07:44:39Z" + message: Finish reconciling + reason: Success + status: "True" + type: ReconcileSuccess \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/healthy.yaml b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/healthy.yaml new file mode 100644 index 0000000000000..b436fba2bce26 --- /dev/null +++ b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/healthy.yaml @@ -0,0 +1,42 @@ +apiVersion: rabbitmq.com/v1beta1 +kind: RabbitmqCluster +metadata: + labels: + app: example-rabbitmq + name: example-rabbitmq + namespace: example +spec: + image: docker.io/bitnami/rabbitmq:3.10.7-debian-11-r8 + persistence: + storage: 32Gi + storageClassName: default + rabbitmq: + replicas: 3 + resources: + limits: + cpu: 250m + memory: 1792Mi + requests: + cpu: 250m + memory: 1792Mi + service: + type: ClusterIP +status: + conditions: + - lastTransitionTime: "2023-08-30T07:44:34Z" + reason: AllPodsAreReady + status: "True" + type: AllReplicasReady + - lastTransitionTime: "2023-08-30T07:37:06Z" + reason: AtLeastOneEndpointAvailable + status: "True" + type: ClusterAvailable + - lastTransitionTime: "2023-08-30T07:33:06Z" + reason: NoWarnings + status: "True" + type: NoWarnings + - lastTransitionTime: "2023-08-30T07:44:39Z" + message: Finish reconciling + reason: Success + status: "True" + type: ReconcileSuccess \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/progressing_cluster_unavailable.yaml b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/progressing_cluster_unavailable.yaml new file mode 100644 index 0000000000000..b01d9f52e2874 --- /dev/null +++ b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/progressing_cluster_unavailable.yaml @@ -0,0 +1,44 @@ +apiVersion: rabbitmq.com/v1beta1 +kind: RabbitmqCluster +metadata: + labels: + app: example-rabbitmq + name: example-rabbitmq + namespace: example +spec: + image: docker.io/bitnami/rabbitmq:3.10.7-debian-11-r8 + persistence: + storage: 32Gi + storageClassName: default + rabbitmq: + replicas: 3 + resources: + limits: + cpu: 250m + memory: 1792Mi + requests: + cpu: 250m + memory: 1792Mi + service: + type: ClusterIP +status: + conditions: + - lastTransitionTime: "2023-08-30T07:44:34Z" + reason: NotAllPodsReady + message: 0/3 Pods ready + status: "False" + type: AllReplicasReady + - lastTransitionTime: "2023-08-30T07:37:06Z" + reason: NoEndpointsAvailable + message: The service has no endpoints available + status: "False" + type: ClusterAvailable + - lastTransitionTime: "2023-08-30T07:33:06Z" + reason: NoWarnings + status: "True" + type: NoWarnings + - lastTransitionTime: "2023-08-30T07:44:39Z" + message: Finish reconciling + reason: Success + status: "True" + type: ReconcileSuccess \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/progressing_no_status.yaml b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/progressing_no_status.yaml new file mode 100644 index 0000000000000..b1ef1afe03562 --- /dev/null +++ b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/progressing_no_status.yaml @@ -0,0 +1,23 @@ +apiVersion: rabbitmq.com/v1beta1 +kind: RabbitmqCluster +metadata: + labels: + app: example-rabbitmq + name: example-rabbitmq + namespace: example +spec: + image: docker.io/bitnami/rabbitmq:3.10.7-debian-11-r8 + persistence: + storage: 32Gi + storageClassName: default + rabbitmq: + replicas: 3 + resources: + limits: + cpu: 250m + memory: 1792Mi + requests: + cpu: 250m + memory: 1792Mi + service: + type: ClusterIP \ No newline at end of file diff --git a/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/progressing_pods_not_ready.yaml b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/progressing_pods_not_ready.yaml new file mode 100644 index 0000000000000..0cbbb2d050250 --- /dev/null +++ b/resource_customizations/rabbitmq.com/RabbitmqCluster/testdata/progressing_pods_not_ready.yaml @@ -0,0 +1,43 @@ +apiVersion: rabbitmq.com/v1beta1 +kind: RabbitmqCluster +metadata: + labels: + app: example-rabbitmq + name: example-rabbitmq + namespace: example +spec: + image: docker.io/bitnami/rabbitmq:3.10.7-debian-11-r8 + persistence: + storage: 32Gi + storageClassName: default + rabbitmq: + replicas: 3 + resources: + limits: + cpu: 250m + memory: 1792Mi + requests: + cpu: 250m + memory: 1792Mi + service: + type: ClusterIP +status: + conditions: + - lastTransitionTime: "2023-08-30T07:44:34Z" + reason: NotAllPodsReady + message: 1/3 Pods ready + status: "False" + type: AllReplicasReady + - lastTransitionTime: "2023-08-30T07:37:06Z" + reason: AtLeastOneEndpointAvailable + status: "True" + type: ClusterAvailable + - lastTransitionTime: "2023-08-30T07:33:06Z" + reason: NoWarnings + status: "True" + type: NoWarnings + - lastTransitionTime: "2023-08-30T07:44:39Z" + message: Finish reconciling + reason: Success + status: "True" + type: ReconcileSuccess \ No newline at end of file diff --git a/resource_customizations/rds.aws.crossplane.io/DBCluster/health.lua b/resource_customizations/rds.aws.crossplane.io/DBCluster/health.lua new file mode 100644 index 0000000000000..dafa85d47a859 --- /dev/null +++ b/resource_customizations/rds.aws.crossplane.io/DBCluster/health.lua @@ -0,0 +1,41 @@ +local hs = {} +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local ready = false + local synced = false + local suspended = false + for i, condition in ipairs(obj.status.conditions) do + + if condition.type == "Ready" then + ready = condition.status == "True" + ready_message = condition.reason + elseif condition.type == "Synced" then + synced = condition.status == "True" + if condition.reason == "ReconcileError" then + synced_message = condition.message + elseif condition.reason == "ReconcilePaused" then + suspended = true + suspended_message = condition.reason + end + end + end + if ready and synced then + hs.status = "Healthy" + hs.message = ready_message + elseif synced == false and suspended == true then + hs.status = "Suspended" + hs.message = suspended_message + elseif ready == false and synced == true and suspended == false then + hs.status = "Progressing" + hs.message = "Waiting for DBCluster to be available" + else + hs.status = "Degraded" + hs.message = synced_message + end + return hs + end +end + +hs.status = "Progressing" +hs.message = "Waiting for DBCluster to be created" +return hs diff --git a/resource_customizations/rds.aws.crossplane.io/DBCluster/health_test.yaml b/resource_customizations/rds.aws.crossplane.io/DBCluster/health_test.yaml new file mode 100644 index 0000000000000..280532d2bc195 --- /dev/null +++ b/resource_customizations/rds.aws.crossplane.io/DBCluster/health_test.yaml @@ -0,0 +1,18 @@ +tests: +- healthStatus: + status: Progressing + message: Waiting for DBCluster to be available + inputPath: testdata/creating.yaml +- healthStatus: + status: Healthy + message: Available + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "create failed: cannot create DBCluster in AWS: InvalidParameterValue: + Invalid DB engine\n\tstatus code: 400, request id: " + inputPath: testdata/degraded.yaml +- healthStatus: + status: Suspended + message: ReconcilePaused + inputPath: testdata/suspended.yaml diff --git a/resource_customizations/rds.aws.crossplane.io/DBCluster/testdata/creating.yaml b/resource_customizations/rds.aws.crossplane.io/DBCluster/testdata/creating.yaml new file mode 100644 index 0000000000000..e5addf24b688b --- /dev/null +++ b/resource_customizations/rds.aws.crossplane.io/DBCluster/testdata/creating.yaml @@ -0,0 +1,48 @@ +apiVersion: rds.aws.crossplane.io/v1alpha1 +kind: DBCluster +metadata: + name: test-rds1 +spec: + deletionPolicy: Delete + forProvider: + allowMajorVersionUpgrade: true + applyImmediately: true + autogeneratePassword: true + databaseName: app + dbSubnetGroupName: test-rds + engine: aurora-postgresql + engineVersion: '16.2' + masterUsername: root + skipFinalSnapshot: true + managementPolicies: + - '*' + providerConfigRef: + name: provider-aws + publishConnectionDetailsTo: + configRef: + name: store-config + name: test-rds1-rds +status: + atProvider: + activityStreamStatus: stopped + clusterCreateTime: '2024-07-15T14:23:42Z' + crossAccountClone: false + dbClusterARN: 'arn:aws:rds:abc123:cluster:test-rds1' + dbClusterIdentifier: test-rds1 + dbClusterParameterGroup: default.aurora-postgresql16 + dbClusterResourceID: cluster-abc123 + dbSubnetGroup: test-rds + endpoint: test-rds1.cluster-abc.rds.amazonaws.com + status: creating + vpcSecurityGroups: + - status: active + vpcSecurityGroupID: sg-abc123 + conditions: + - lastTransitionTime: '2024-07-15T14:23:42Z' + reason: Creating + status: 'False' + type: Ready + - lastTransitionTime: '2024-07-15T14:23:42Z' + reason: ReconcileSuccess + status: 'True' + type: Synced diff --git a/resource_customizations/rds.aws.crossplane.io/DBCluster/testdata/degraded.yaml b/resource_customizations/rds.aws.crossplane.io/DBCluster/testdata/degraded.yaml new file mode 100644 index 0000000000000..1203a9421accd --- /dev/null +++ b/resource_customizations/rds.aws.crossplane.io/DBCluster/testdata/degraded.yaml @@ -0,0 +1,37 @@ +apiVersion: rds.aws.crossplane.io/v1alpha1 +kind: DBCluster +metadata: + name: test-rds1 +spec: + deletionPolicy: Delete + forProvider: + allowMajorVersionUpgrade: true + applyImmediately: true + autogeneratePassword: true + databaseName: app + dbSubnetGroupName: test-rds + engine: foobar + engineVersion: '16.2' + masterUsername: root + skipFinalSnapshot: true + managementPolicies: + - '*' + providerConfigRef: + name: provider-aws + publishConnectionDetailsTo: + configRef: + name: store-config + name: test-rds1-rds +status: + atProvider: {} + conditions: + - lastTransitionTime: "2024-07-17T18:03:12Z" + reason: Creating + status: "False" + type: Ready + - lastTransitionTime: "2024-07-17T18:03:12Z" + message: "create failed: cannot create DBCluster in AWS: InvalidParameterValue: + Invalid DB engine\n\tstatus code: 400, request id: " + reason: ReconcileError + status: "False" + type: Synced diff --git a/resource_customizations/rds.aws.crossplane.io/DBCluster/testdata/healthy.yaml b/resource_customizations/rds.aws.crossplane.io/DBCluster/testdata/healthy.yaml new file mode 100644 index 0000000000000..3e824228a25ad --- /dev/null +++ b/resource_customizations/rds.aws.crossplane.io/DBCluster/testdata/healthy.yaml @@ -0,0 +1,61 @@ +apiVersion: rds.aws.crossplane.io/v1alpha1 +kind: DBCluster +metadata: + name: test-rds1 +spec: + deletionPolicy: Delete + forProvider: + allowMajorVersionUpgrade: true + applyImmediately: true + autogeneratePassword: true + databaseName: app + dbSubnetGroupName: test-rds + engine: aurora-postgresql + engineVersion: '16.2' + masterUsername: root + skipFinalSnapshot: true + managementPolicies: + - '*' + providerConfigRef: + name: provider-aws + publishConnectionDetailsTo: + configRef: + name: store-config + name: test-rds1-rds +status: + atProvider: + activityStreamStatus: stopped + clusterCreateTime: "2024-07-15T14:23:42Z" + crossAccountClone: false + dbClusterARN: arn:aws:rds:abc123:cluster:test-rds1 + dbClusterIdentifier: test-rds1 + dbClusterMembers: + - dbClusterParameterGroupStatus: in-sync + dbInstanceIdentifier: test-rds1-0 + isClusterWriter: true + promotionTier: 1 + dbClusterParameterGroup: default.aurora-postgresql16 + dbClusterResourceID: cluster-abc123 + dbSubnetGroup: sandbox5-valhalla-rds + earliestRestorableTime: "2024-07-15T14:24:40Z" + endpoint: test-rds1.cluster-abc123.rds.amazonaws.com + engineVersion: "16.2" + hostedZoneID: abc123 + httpEndpointEnabled: false + iamDatabaseAuthenticationEnabled: false + latestRestorableTime: "2024-07-15T14:46:08Z" + multiAZ: false + readerEndpoint: test-rds1.abc123.rds.amazonaws.com + status: available + vpcSecurityGroups: + - status: active + vpcSecurityGroupID: sg-abc123 + conditions: + - lastTransitionTime: "2024-07-15T14:48:40Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2024-07-15T14:23:42Z" + reason: ReconcileSuccess + status: "True" + type: Synced diff --git a/resource_customizations/rds.aws.crossplane.io/DBCluster/testdata/suspended.yaml b/resource_customizations/rds.aws.crossplane.io/DBCluster/testdata/suspended.yaml new file mode 100644 index 0000000000000..960f4d86733ee --- /dev/null +++ b/resource_customizations/rds.aws.crossplane.io/DBCluster/testdata/suspended.yaml @@ -0,0 +1,37 @@ +apiVersion: rds.aws.crossplane.io/v1alpha1 +kind: DBCluster +metadata: + name: test-rds1 + annotations: + crossplane.io/paused: "true" +spec: + deletionPolicy: Delete + forProvider: + allowMajorVersionUpgrade: true + applyImmediately: true + autogeneratePassword: true + databaseName: app + dbSubnetGroupName: test-rds + engine: aurora-postgresql + engineVersion: '16.2' + masterUsername: root + skipFinalSnapshot: true + managementPolicies: + - '*' + providerConfigRef: + name: provider-aws + publishConnectionDetailsTo: + configRef: + name: store-config + name: test-rds1-rds +status: + atProvider: {} + conditions: + - lastTransitionTime: "2024-07-17T18:03:12Z" + reason: Creating + status: "False" + type: Ready + - lastTransitionTime: "2024-07-17T18:04:55Z" + reason: ReconcilePaused + status: "False" + type: Synced diff --git a/resource_customizations/rds.aws.crossplane.io/DBInstance/health.lua b/resource_customizations/rds.aws.crossplane.io/DBInstance/health.lua new file mode 100644 index 0000000000000..91e22df91a6be --- /dev/null +++ b/resource_customizations/rds.aws.crossplane.io/DBInstance/health.lua @@ -0,0 +1,41 @@ +local hs = {} +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local ready = false + local synced = false + local suspended = false + for i, condition in ipairs(obj.status.conditions) do + + if condition.type == "Ready" then + ready = condition.status == "True" + ready_message = condition.reason + elseif condition.type == "Synced" then + synced = condition.status == "True" + if condition.reason == "ReconcileError" then + synced_message = condition.message + elseif condition.reason == "ReconcilePaused" then + suspended = true + suspended_message = condition.reason + end + end + end + if ready and synced then + hs.status = "Healthy" + hs.message = ready_message + elseif synced == false and suspended == true then + hs.status = "Suspended" + hs.message = suspended_message + elseif ready == false and synced == true and suspended == false then + hs.status = "Progressing" + hs.message = "Waiting for DBInstance to be available" + else + hs.status = "Degraded" + hs.message = synced_message + end + return hs + end +end + +hs.status = "Progressing" +hs.message = "Waiting for DBInstance to be created" +return hs diff --git a/resource_customizations/rds.aws.crossplane.io/DBInstance/health_test.yaml b/resource_customizations/rds.aws.crossplane.io/DBInstance/health_test.yaml new file mode 100644 index 0000000000000..d8db77007ca88 --- /dev/null +++ b/resource_customizations/rds.aws.crossplane.io/DBInstance/health_test.yaml @@ -0,0 +1,14 @@ +tests: +- healthStatus: + status: Progressing + message: Waiting for DBInstance to be available + inputPath: testdata/creating.yaml +- healthStatus: + status: Healthy + message: Available + inputPath: testdata/healthy.yaml +- healthStatus: + status: Degraded + message: "update failed: cannot update DBInstance in AWS: InvalidParameterValue: + Invalid DB Instance class: db.t4g.foobar\n\tstatus code: 400, request id: " + inputPath: testdata/degraded.yaml diff --git a/resource_customizations/rds.aws.crossplane.io/DBInstance/testdata/creating.yaml b/resource_customizations/rds.aws.crossplane.io/DBInstance/testdata/creating.yaml new file mode 100644 index 0000000000000..883d55e0041b4 --- /dev/null +++ b/resource_customizations/rds.aws.crossplane.io/DBInstance/testdata/creating.yaml @@ -0,0 +1,45 @@ +apiVersion: rds.aws.crossplane.io/v1alpha1 +kind: DBInstance +metadata: + name: test-rds1-0 +spec: + deletionPolicy: Delete + forProvider: + autoMinorVersionUpgrade: true + caCertificateIdentifier: rds-ca-rsa2048-g1 + dbClusterIdentifier: test-rds1 + dbInstanceClass: db.t4g.medium + dbName: app + dbSubnetGroupName: test-rds + enablePerformanceInsights: false + engine: aurora-postgresql + licenseModel: postgresql-license + masterUsername: root + multiAZ: false + preferredMaintenanceWindow: 'tue:00:36-tue:01:06' + promotionTier: 1 + publiclyAccessible: false + region: eu-north-1 + storageThroughput: 0 + managementPolicies: + - '*' + providerConfigRef: + name: provider-aws +status: + atProvider: + certificateDetails: + cAIdentifier: rds-ca-rsa2048-g1 + customerOwnedIPEnabled: false + dbInstanceARN: 'arn:aws:rds:abc:db:test-rds1-0' + dbInstanceIdentifier: test-rds1-0 + dbInstancePort: 0 + dbInstanceStatus: creating + conditions: + - lastTransitionTime: '2024-07-15T14:25:07Z' + reason: Creating + status: 'False' + type: Ready + - lastTransitionTime: '2024-07-15T14:25:07Z' + reason: ReconcileSuccess + status: 'True' + type: Synced diff --git a/resource_customizations/rds.aws.crossplane.io/DBInstance/testdata/degraded.yaml b/resource_customizations/rds.aws.crossplane.io/DBInstance/testdata/degraded.yaml new file mode 100644 index 0000000000000..60fd417bada80 --- /dev/null +++ b/resource_customizations/rds.aws.crossplane.io/DBInstance/testdata/degraded.yaml @@ -0,0 +1,64 @@ +apiVersion: rds.aws.crossplane.io/v1alpha1 +kind: DBInstance +metadata: + name: test-rds1-0 +spec: + deletionPolicy: Delete + forProvider: + autoMinorVersionUpgrade: true + caCertificateIdentifier: rds-ca-rsa2048-g1 + dbClusterIdentifier: test-rds1 + dbInstanceClass: db.t4g.foobar + dbName: app + dbSubnetGroupName: test-rds + enablePerformanceInsights: false + engine: aurora-postgresql + licenseModel: postgresql-license + masterUsername: root + multiAZ: false + preferredMaintenanceWindow: 'tue:00:36-tue:01:06' + promotionTier: 1 + publiclyAccessible: false + region: eu-north-1 + storageThroughput: 0 + managementPolicies: + - '*' + providerConfigRef: + name: provider-aws +status: + atProvider: + certificateDetails: + cAIdentifier: rds-ca-rsa2048-g1 + validTill: "2025-07-15T16:06:53Z" + customerOwnedIPEnabled: false + dbInstanceARN: arn:aws:rds:123:db:test-rds1-app-0 + dbInstanceIdentifier: test-rds1-app-0 + dbInstancePort: 0 + dbInstanceStatus: available + dbiResourceID: db-123 + endpoint: + address: test-rds1-app-0.123.abc.rds.amazonaws.com + hostedZoneID: ABC213 + port: 5432 + engineVersion: "16.2" + iamDatabaseAuthenticationEnabled: false + instanceCreateTime: "2024-07-15T16:08:27Z" + optionGroupMemberships: + - optionGroupName: default:aurora-postgresql-16 + status: in-sync + pendingModifiedValues: {} + performanceInsightsEnabled: false + vpcSecurityGroups: + - status: active + vpcSecurityGroupID: sg-abc123 + conditions: + - lastTransitionTime: "2024-07-15T17:04:24Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2024-07-17T17:57:38Z" + message: "update failed: cannot update DBInstance in AWS: InvalidParameterValue: + Invalid DB Instance class: db.t4g.foobar\n\tstatus code: 400, request id: " + reason: ReconcileError + status: "False" + type: Synced diff --git a/resource_customizations/rds.aws.crossplane.io/DBInstance/testdata/healthy.yaml b/resource_customizations/rds.aws.crossplane.io/DBInstance/testdata/healthy.yaml new file mode 100644 index 0000000000000..c993c91b7bd6d --- /dev/null +++ b/resource_customizations/rds.aws.crossplane.io/DBInstance/testdata/healthy.yaml @@ -0,0 +1,65 @@ +apiVersion: rds.aws.crossplane.io/v1alpha1 +kind: DBInstance +metadata: + name: test-rds1-0 +spec: + deletionPolicy: Delete + forProvider: + autoMinorVersionUpgrade: true + caCertificateIdentifier: rds-ca-rsa2048-g1 + dbClusterIdentifier: test-rds1 + dbInstanceClass: db.t4g.medium + dbName: app + dbSubnetGroupName: test-rds + enablePerformanceInsights: false + engine: aurora-postgresql + licenseModel: postgresql-license + masterUsername: root + multiAZ: false + preferredMaintenanceWindow: 'tue:00:36-tue:01:06' + promotionTier: 1 + publiclyAccessible: false + region: eu-north-1 + storageThroughput: 0 + managementPolicies: + - '*' + providerConfigRef: + name: provider-aws +status: + atProvider: + certificateDetails: + cAIdentifier: rds-ca-rsa2048-g1 + validTill: "2025-07-15T14:27:27Z" + customerOwnedIPEnabled: false + dbInstanceARN: arn:aws:rds:abc123:db:test-rds1-0 + dbInstanceIdentifier: test-rds1-0 + dbInstancePort: 0 + dbInstanceStatus: available + dbParameterGroups: + - dbParameterGroupName: default.aurora-postgresql16 + parameterApplyStatus: in-sync + dbiResourceID: db-abc123 + endpoint: + address: test-rds1-0.abc123.rds.amazonaws.com + hostedZoneID: abc123 + port: 5432 + engineVersion: "16.2" + iamDatabaseAuthenticationEnabled: false + instanceCreateTime: "2024-07-15T14:29:00Z" + optionGroupMemberships: + - optionGroupName: default:aurora-postgresql-16 + status: in-sync + pendingModifiedValues: {} + performanceInsightsEnabled: false + vpcSecurityGroups: + - status: active + vpcSecurityGroupID: sg-abc123 + conditions: + - lastTransitionTime: "2024-07-15T14:48:40Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2024-07-15T14:25:07Z" + reason: ReconcileSuccess + status: "True" + type: Synced diff --git a/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/heatlh.lua b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/health.lua similarity index 100% rename from resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/heatlh.lua rename to resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/health.lua diff --git a/resource_customizations/s3.aws.crossplane.io/Bucket/health.lua b/resource_customizations/s3.aws.crossplane.io/Bucket/health.lua new file mode 100644 index 0000000000000..ae9d8ff97ff9f --- /dev/null +++ b/resource_customizations/s3.aws.crossplane.io/Bucket/health.lua @@ -0,0 +1,41 @@ +local hs = {} +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local ready = false + local synced = false + local suspended = false + for i, condition in ipairs(obj.status.conditions) do + + if condition.type == "Ready" then + ready = condition.status == "True" + ready_message = condition.reason + elseif condition.type == "Synced" then + synced = condition.status == "True" + if condition.reason == "ReconcileError" then + synced_message = condition.message + elseif condition.reason == "ReconcilePaused" then + suspended = true + suspended_message = condition.reason + end + end + end + if ready and synced then + hs.status = "Healthy" + hs.message = ready_message + elseif synced == false and suspended == true then + hs.status = "Suspended" + hs.message = suspended_message + elseif ready == false and synced == true and suspended == false then + hs.status = "Progressing" + hs.message = "Waiting for Bucket to be available" + else + hs.status = "Degraded" + hs.message = synced_message + end + return hs + end +end + +hs.status = "Progressing" +hs.message = "Waiting for Bucket to be created" +return hs diff --git a/resource_customizations/s3.aws.crossplane.io/Bucket/health_test.yaml b/resource_customizations/s3.aws.crossplane.io/Bucket/health_test.yaml new file mode 100644 index 0000000000000..7fd4388805e9b --- /dev/null +++ b/resource_customizations/s3.aws.crossplane.io/Bucket/health_test.yaml @@ -0,0 +1,14 @@ +tests: +- healthStatus: + status: Degraded + message: >- + delete failed: operation error S3: DeleteBucket, https response error + StatusCode: 409, RequestID: ABC123, HostID: + ABC/123/ABC=, + api error BucketNotEmpty: The bucket you tried to delete is not empty. + You must delete all versions in the bucket. + inputPath: testdata/ReconcileError.yaml +- healthStatus: + status: Healthy + message: Available + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/s3.aws.crossplane.io/Bucket/testdata/ReconcileError.yaml b/resource_customizations/s3.aws.crossplane.io/Bucket/testdata/ReconcileError.yaml new file mode 100644 index 0000000000000..601a08e623d0c --- /dev/null +++ b/resource_customizations/s3.aws.crossplane.io/Bucket/testdata/ReconcileError.yaml @@ -0,0 +1,42 @@ +apiVersion: s3.aws.crossplane.io/v1beta1 +kind: Bucket +metadata: + name: example +spec: + deletionPolicy: Delete + forProvider: + locationConstraint: eu-north-1 + objectOwnership: BucketOwnerEnforced + paymentConfiguration: + payer: BucketOwner + publicAccessBlockConfiguration: + blockPublicAcls: true + blockPublicPolicy: true + ignorePublicAcls: true + restrictPublicBuckets: true + serverSideEncryptionConfiguration: + rules: + - applyServerSideEncryptionByDefault: + sseAlgorithm: AES256 + versioningConfiguration: + status: Suspended + providerConfigRef: + name: provider-aws +status: + atProvider: + arn: 'arn:aws:s3:::example' + conditions: + - lastTransitionTime: '2024-07-12T09:51:07Z' + reason: Deleting + status: 'False' + type: Ready + - lastTransitionTime: '2024-07-12T09:51:07Z' + message: >- + delete failed: operation error S3: DeleteBucket, https response error + StatusCode: 409, RequestID: ABC123, HostID: + ABC/123/ABC=, + api error BucketNotEmpty: The bucket you tried to delete is not empty. + You must delete all versions in the bucket. + reason: ReconcileError + status: 'False' + type: Synced diff --git a/resource_customizations/s3.aws.crossplane.io/Bucket/testdata/healthy.yaml b/resource_customizations/s3.aws.crossplane.io/Bucket/testdata/healthy.yaml new file mode 100644 index 0000000000000..fc29b984719f0 --- /dev/null +++ b/resource_customizations/s3.aws.crossplane.io/Bucket/testdata/healthy.yaml @@ -0,0 +1,36 @@ +apiVersion: s3.aws.crossplane.io/v1beta1 +kind: Bucket +metadata: + name: example +spec: + deletionPolicy: Delete + forProvider: + locationConstraint: eu-north-1 + objectOwnership: BucketOwnerEnforced + paymentConfiguration: + payer: BucketOwner + publicAccessBlockConfiguration: + blockPublicAcls: true + blockPublicPolicy: true + ignorePublicAcls: true + restrictPublicBuckets: true + serverSideEncryptionConfiguration: + rules: + - applyServerSideEncryptionByDefault: + sseAlgorithm: AES256 + versioningConfiguration: + status: Suspended + providerConfigRef: + name: provider-aws +status: + atProvider: + arn: arn:aws:s3:::example + conditions: + - lastTransitionTime: "2024-07-12T12:50:46Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2024-07-12T12:50:44Z" + reason: ReconcileSuccess + status: "True" + type: Synced diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/action_test.yaml b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/action_test.yaml new file mode 100644 index 0000000000000..170d73e9a8e02 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/action_test.yaml @@ -0,0 +1,35 @@ +discoveryTests: +- inputPath: testdata/initial_bucket.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +- inputPath: testdata/suspended_bucket.yaml + result: + - name: reconcile + disabled: true + - name: suspend + disabled: true + - name: resume + disabled: false +- inputPath: testdata/resumed_bucket.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +actionTests: +- action: reconcile + inputPath: testdata/initial_bucket.yaml + expectedOutputPath: testdata/reconciled_bucket.yaml +- action: suspend + inputPath: testdata/initial_bucket.yaml + expectedOutputPath: testdata/suspended_bucket.yaml +- action: resume + inputPath: testdata/suspended_bucket.yaml + expectedOutputPath: testdata/resumed_bucket.yaml diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/discovery.lua b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/discovery.lua new file mode 100644 index 0000000000000..9000998815515 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/discovery.lua @@ -0,0 +1,18 @@ +local actions = {} + +actions["reconcile"] = {["disabled"] = true} +actions["suspend"] = {["disabled"] = true} +actions["resume"] = {["disabled"] = true} + +local suspend = false +if obj.spec.suspend ~= nil then + suspend = obj.spec.suspend +end +if suspend then + actions["resume"]["disabled"] = false +else + actions["reconcile"]["disabled"] = false + actions["suspend"]["disabled"] = false +end + +return actions diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/reconcile/action.lua b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/reconcile/action.lua new file mode 100644 index 0000000000000..a534b36fb3ebc --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/reconcile/action.lua @@ -0,0 +1,7 @@ +local os = require("os") +if obj.metadata.annotations == nil then + obj.metadata.annotations = {} +end +obj.metadata.annotations["reconcile.fluxcd.io/requestedAt"] = "By Argo CD at: " .. os.date("!%Y-%m-%dT%X") + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/resume/action.lua b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/resume/action.lua new file mode 100644 index 0000000000000..cb41993777699 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/resume/action.lua @@ -0,0 +1,5 @@ +if obj.spec.suspend ~= nil and obj.spec.suspend then + obj.spec.suspend = false +end + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/suspend/action.lua b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/suspend/action.lua new file mode 100644 index 0000000000000..1a338b2ad1361 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/suspend/action.lua @@ -0,0 +1,3 @@ +obj.spec.suspend = true + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/testdata/initial_bucket.yaml b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/testdata/initial_bucket.yaml new file mode 100644 index 0000000000000..2de992d401e6c --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/testdata/initial_bucket.yaml @@ -0,0 +1,12 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: Bucket +metadata: + name: minio-bucket + namespace: default +spec: + interval: 5m0s + endpoint: minio.example.com + insecure: true + secretRef: + name: minio-bucket-secret + bucketName: example diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/testdata/reconciled_bucket.yaml b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/testdata/reconciled_bucket.yaml new file mode 100644 index 0000000000000..80074067a75bf --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/testdata/reconciled_bucket.yaml @@ -0,0 +1,14 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: Bucket +metadata: + name: minio-bucket + namespace: default + annotations: + reconcile.fluxcd.io/requestedAt: 'By Argo CD at: 0001-01-01T00:00:00' +spec: + interval: 5m0s + endpoint: minio.example.com + insecure: true + secretRef: + name: minio-bucket-secret + bucketName: example diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/testdata/resumed_bucket.yaml b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/testdata/resumed_bucket.yaml new file mode 100644 index 0000000000000..40cfe6c9fc43d --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/testdata/resumed_bucket.yaml @@ -0,0 +1,13 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: Bucket +metadata: + name: minio-bucket + namespace: default +spec: + interval: 5m0s + endpoint: minio.example.com + insecure: true + secretRef: + name: minio-bucket-secret + bucketName: example + suspend: false diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/testdata/suspended_bucket.yaml b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/testdata/suspended_bucket.yaml new file mode 100644 index 0000000000000..0f10c70214c62 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/actions/testdata/suspended_bucket.yaml @@ -0,0 +1,13 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: Bucket +metadata: + name: minio-bucket + namespace: default +spec: + interval: 5m0s + endpoint: minio.example.com + insecure: true + secretRef: + name: minio-bucket-secret + bucketName: example + suspend: true diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/health.lua b/resource_customizations/source.toolkit.fluxcd.io/Bucket/health.lua new file mode 100644 index 0000000000000..9ad39cb708294 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/health.lua @@ -0,0 +1,45 @@ +local hs = {} +if obj.spec.suspend ~= nil and obj.spec.suspend == true then + hs.message = obj.kind .. " is suspended" + hs.status = "Suspended" + return hs +end +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local numProgressing = 0 + local numSucceeded = 0 + local message = "" + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + if condition.status == "True" then + numSucceeded = numSucceeded + 1 + elseif condition.status == "Unknown" then + numProgressing = numProgressing + 1 + end + message = condition.reason + elseif condition.type == "Reconciling" and condition.status == "True" then + numProgressing = numProgressing + 1 + elseif condition.type == "ArtifactOutdated" and condition.status == "True" then + message = message .. " " .. condition.reason + elseif condition.type == "ArtifactInStorage" and condition.status == "True" then + numSucceeded = numSucceeded + 1 + end + end + if(numProgressing == 2) then + hs.message = message + hs.status = "Progressing" + return hs + elseif(numSucceeded == 2) then + hs.message = message + hs.status = "Healthy" + return hs + else + hs.message = message + hs.status = "Degraded" + return hs + end + end +end +hs.message = "Status unknown" +hs.status = "Progressing" +return hs diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/health_test.yaml b/resource_customizations/source.toolkit.fluxcd.io/Bucket/health_test.yaml new file mode 100644 index 0000000000000..1cbb664013978 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/health_test.yaml @@ -0,0 +1,13 @@ +tests: + # - healthStatus: + # status: Progressing + # message: Progressing + # inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: BucketOperationFailed + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: Succeeded + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/testdata/degraded.yaml b/resource_customizations/source.toolkit.fluxcd.io/Bucket/testdata/degraded.yaml new file mode 100644 index 0000000000000..d2d469e36563c --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/testdata/degraded.yaml @@ -0,0 +1,34 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: Bucket +metadata: + name: minio-bucket + namespace: default +spec: + interval: 5m0s + endpoint: minio.example.com + insecure: true + secretRef: + name: minio-bucket-secret + bucketName: example +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: building artifact + observedGeneration: 1 + reason: ProgressingWithRetry + status: "True" + type: Reconciling + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'failed to confirm existence of ''example'' bucket: XML syntax error + on line 5: element closed by ' + observedGeneration: 1 + reason: BucketOperationFailed + status: "False" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'failed to confirm existence of ''example'' bucket: XML syntax error + on line 5: element closed by ' + observedGeneration: 1 + reason: BucketOperationFailed + status: "True" + type: FetchFailed diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/testdata/healthy.yaml b/resource_customizations/source.toolkit.fluxcd.io/Bucket/testdata/healthy.yaml new file mode 100644 index 0000000000000..b0e39bd81c5f3 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/testdata/healthy.yaml @@ -0,0 +1,26 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: Bucket +metadata: + name: minio-bucket + namespace: default +spec: + interval: 5m0s + endpoint: minio.example.com + insecure: true + secretRef: + name: minio-bucket-secret + bucketName: example +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'stored artifact: revision ''sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855''' + observedGeneration: 3 + reason: Succeeded + status: "True" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'stored artifact: revision ''sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855''' + observedGeneration: 3 + reason: Succeeded + status: "True" + type: ArtifactInStorage diff --git a/resource_customizations/source.toolkit.fluxcd.io/Bucket/testdata/progressing.yaml b/resource_customizations/source.toolkit.fluxcd.io/Bucket/testdata/progressing.yaml new file mode 100644 index 0000000000000..be2e1b364bbab --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/Bucket/testdata/progressing.yaml @@ -0,0 +1,14 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: Bucket +metadata: + name: minio-bucket + namespace: default +spec: + interval: 5m0s + endpoint: minio.example.com + insecure: true + secretRef: + name: minio-bucket-secret + bucketName: example +status: + conditions: [] diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/action_test.yaml b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/action_test.yaml new file mode 100644 index 0000000000000..203f40629d209 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/action_test.yaml @@ -0,0 +1,35 @@ +discoveryTests: +- inputPath: testdata/initial_gitrepository.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +- inputPath: testdata/suspended_gitrepository.yaml + result: + - name: reconcile + disabled: true + - name: suspend + disabled: true + - name: resume + disabled: false +- inputPath: testdata/resumed_gitrepository.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +actionTests: +- action: reconcile + inputPath: testdata/initial_gitrepository.yaml + expectedOutputPath: testdata/reconciled_gitrepository.yaml +- action: suspend + inputPath: testdata/initial_gitrepository.yaml + expectedOutputPath: testdata/suspended_gitrepository.yaml +- action: resume + inputPath: testdata/suspended_gitrepository.yaml + expectedOutputPath: testdata/resumed_gitrepository.yaml diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/discovery.lua b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/discovery.lua new file mode 100644 index 0000000000000..9000998815515 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/discovery.lua @@ -0,0 +1,18 @@ +local actions = {} + +actions["reconcile"] = {["disabled"] = true} +actions["suspend"] = {["disabled"] = true} +actions["resume"] = {["disabled"] = true} + +local suspend = false +if obj.spec.suspend ~= nil then + suspend = obj.spec.suspend +end +if suspend then + actions["resume"]["disabled"] = false +else + actions["reconcile"]["disabled"] = false + actions["suspend"]["disabled"] = false +end + +return actions diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/reconcile/action.lua b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/reconcile/action.lua new file mode 100644 index 0000000000000..a534b36fb3ebc --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/reconcile/action.lua @@ -0,0 +1,7 @@ +local os = require("os") +if obj.metadata.annotations == nil then + obj.metadata.annotations = {} +end +obj.metadata.annotations["reconcile.fluxcd.io/requestedAt"] = "By Argo CD at: " .. os.date("!%Y-%m-%dT%X") + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/resume/action.lua b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/resume/action.lua new file mode 100644 index 0000000000000..cb41993777699 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/resume/action.lua @@ -0,0 +1,5 @@ +if obj.spec.suspend ~= nil and obj.spec.suspend then + obj.spec.suspend = false +end + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/suspend/action.lua b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/suspend/action.lua new file mode 100644 index 0000000000000..1a338b2ad1361 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/suspend/action.lua @@ -0,0 +1,3 @@ +obj.spec.suspend = true + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/testdata/initial_gitrepository.yaml b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/testdata/initial_gitrepository.yaml new file mode 100644 index 0000000000000..3cd5664e591f0 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/testdata/initial_gitrepository.yaml @@ -0,0 +1,10 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m + url: https://github.com/stefanprodan/podinfo + ref: + branch: master diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/testdata/reconciled_gitrepository.yaml b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/testdata/reconciled_gitrepository.yaml new file mode 100644 index 0000000000000..4cfe3861aca1f --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/testdata/reconciled_gitrepository.yaml @@ -0,0 +1,12 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: podinfo + namespace: default + annotations: + reconcile.fluxcd.io/requestedAt: 'By Argo CD at: 0001-01-01T00:00:00' +spec: + interval: 5m + url: https://github.com/stefanprodan/podinfo + ref: + branch: master diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/testdata/resumed_gitrepository.yaml b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/testdata/resumed_gitrepository.yaml new file mode 100644 index 0000000000000..0a204953f5fe7 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/testdata/resumed_gitrepository.yaml @@ -0,0 +1,11 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m + url: https://github.com/stefanprodan/podinfo + ref: + branch: master + suspend: false diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/testdata/suspended_gitrepository.yaml b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/testdata/suspended_gitrepository.yaml new file mode 100644 index 0000000000000..22c7be6772be2 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/actions/testdata/suspended_gitrepository.yaml @@ -0,0 +1,11 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m + url: https://github.com/stefanprodan/podinfo + ref: + branch: master + suspend: true diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/health.lua b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/health.lua new file mode 100644 index 0000000000000..9ad39cb708294 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/health.lua @@ -0,0 +1,45 @@ +local hs = {} +if obj.spec.suspend ~= nil and obj.spec.suspend == true then + hs.message = obj.kind .. " is suspended" + hs.status = "Suspended" + return hs +end +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local numProgressing = 0 + local numSucceeded = 0 + local message = "" + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + if condition.status == "True" then + numSucceeded = numSucceeded + 1 + elseif condition.status == "Unknown" then + numProgressing = numProgressing + 1 + end + message = condition.reason + elseif condition.type == "Reconciling" and condition.status == "True" then + numProgressing = numProgressing + 1 + elseif condition.type == "ArtifactOutdated" and condition.status == "True" then + message = message .. " " .. condition.reason + elseif condition.type == "ArtifactInStorage" and condition.status == "True" then + numSucceeded = numSucceeded + 1 + end + end + if(numProgressing == 2) then + hs.message = message + hs.status = "Progressing" + return hs + elseif(numSucceeded == 2) then + hs.message = message + hs.status = "Healthy" + return hs + else + hs.message = message + hs.status = "Degraded" + return hs + end + end +end +hs.message = "Status unknown" +hs.status = "Progressing" +return hs diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/health_test.yaml b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/health_test.yaml new file mode 100644 index 0000000000000..c743c0b477d1a --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/health_test.yaml @@ -0,0 +1,13 @@ +tests: + # - healthStatus: + # status: Progressing + # message: Progressing + # inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: GitOperationFailed + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: Succeeded + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/testdata/degraded.yaml b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/testdata/degraded.yaml new file mode 100644 index 0000000000000..653e71945dbf5 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/testdata/degraded.yaml @@ -0,0 +1,38 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m + url: https://github.com/stefanprodan/podinfo-faulty + ref: + branch: master +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'processing object: new generation 1 -> 2' + observedGeneration: 2 + reason: ProgressingWithRetry + status: "True" + type: Reconciling + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'failed to checkout and determine revision: unable to list remote for + ''https://github.com/stefanprodan/podinfo-faulty'': authentication required' + observedGeneration: 2 + reason: GitOperationFailed + status: "False" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'failed to checkout and determine revision: unable to list remote for + ''https://github.com/stefanprodan/podinfo-faulty'': authentication required' + observedGeneration: 2 + reason: GitOperationFailed + status: "True" + type: FetchFailed + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: stored artifact for revision 'master@sha1:08238eada746de8114efa36d36e2aa93bd76cfab' + observedGeneration: 1 + reason: Succeeded + status: "True" + type: ArtifactInStorage diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/testdata/healthy.yaml b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/testdata/healthy.yaml new file mode 100644 index 0000000000000..0bf0210615591 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/testdata/healthy.yaml @@ -0,0 +1,24 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m + url: https://github.com/stefanprodan/podinfo + ref: + branch: master +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: stored artifact for revision 'master@sha1:08238eada746de8114efa36d36e2aa93bd76cfab' + observedGeneration: 1 + reason: Succeeded + status: "True" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: stored artifact for revision 'master@sha1:08238eada746de8114efa36d36e2aa93bd76cfab' + observedGeneration: 1 + reason: Succeeded + status: "True" + type: ArtifactInStorage diff --git a/resource_customizations/source.toolkit.fluxcd.io/GitRepository/testdata/progressing.yaml b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/testdata/progressing.yaml new file mode 100644 index 0000000000000..c1c99bf084246 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/GitRepository/testdata/progressing.yaml @@ -0,0 +1,12 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m + url: https://github.com/stefanprodan/podinfo + ref: + branch: master +status: + conditions: [] diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/action_test.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/action_test.yaml new file mode 100644 index 0000000000000..e5d34eb71f1bf --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/action_test.yaml @@ -0,0 +1,35 @@ +discoveryTests: +- inputPath: testdata/initial_helmchart.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +- inputPath: testdata/suspended_helmchart.yaml + result: + - name: reconcile + disabled: true + - name: suspend + disabled: true + - name: resume + disabled: false +- inputPath: testdata/resumed_helmchart.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +actionTests: +- action: reconcile + inputPath: testdata/initial_helmchart.yaml + expectedOutputPath: testdata/reconciled_helmchart.yaml +- action: suspend + inputPath: testdata/initial_helmchart.yaml + expectedOutputPath: testdata/suspended_helmchart.yaml +- action: resume + inputPath: testdata/suspended_helmchart.yaml + expectedOutputPath: testdata/resumed_helmchart.yaml diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/discovery.lua b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/discovery.lua new file mode 100644 index 0000000000000..9000998815515 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/discovery.lua @@ -0,0 +1,18 @@ +local actions = {} + +actions["reconcile"] = {["disabled"] = true} +actions["suspend"] = {["disabled"] = true} +actions["resume"] = {["disabled"] = true} + +local suspend = false +if obj.spec.suspend ~= nil then + suspend = obj.spec.suspend +end +if suspend then + actions["resume"]["disabled"] = false +else + actions["reconcile"]["disabled"] = false + actions["suspend"]["disabled"] = false +end + +return actions diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/reconcile/action.lua b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/reconcile/action.lua new file mode 100644 index 0000000000000..a534b36fb3ebc --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/reconcile/action.lua @@ -0,0 +1,7 @@ +local os = require("os") +if obj.metadata.annotations == nil then + obj.metadata.annotations = {} +end +obj.metadata.annotations["reconcile.fluxcd.io/requestedAt"] = "By Argo CD at: " .. os.date("!%Y-%m-%dT%X") + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/resume/action.lua b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/resume/action.lua new file mode 100644 index 0000000000000..cb41993777699 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/resume/action.lua @@ -0,0 +1,5 @@ +if obj.spec.suspend ~= nil and obj.spec.suspend then + obj.spec.suspend = false +end + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/suspend/action.lua b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/suspend/action.lua new file mode 100644 index 0000000000000..1a338b2ad1361 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/suspend/action.lua @@ -0,0 +1,3 @@ +obj.spec.suspend = true + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/testdata/initial_helmchart.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/testdata/initial_helmchart.yaml new file mode 100644 index 0000000000000..da341e25a4d73 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/testdata/initial_helmchart.yaml @@ -0,0 +1,13 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmChart +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + chart: podinfo + reconcileStrategy: ChartVersion + sourceRef: + kind: HelmRepository + name: podinfo + version: '5.*' diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/testdata/reconciled_helmchart.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/testdata/reconciled_helmchart.yaml new file mode 100644 index 0000000000000..e3d3e5fedeb34 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/testdata/reconciled_helmchart.yaml @@ -0,0 +1,15 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmChart +metadata: + name: podinfo + namespace: default + annotations: + reconcile.fluxcd.io/requestedAt: 'By Argo CD at: 0001-01-01T00:00:00' +spec: + interval: 5m0s + chart: podinfo + reconcileStrategy: ChartVersion + sourceRef: + kind: HelmRepository + name: podinfo + version: '5.*' diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/testdata/resumed_helmchart.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/testdata/resumed_helmchart.yaml new file mode 100644 index 0000000000000..9711ecdeee097 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/testdata/resumed_helmchart.yaml @@ -0,0 +1,14 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmChart +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + chart: podinfo + reconcileStrategy: ChartVersion + sourceRef: + kind: HelmRepository + name: podinfo + suspend: false + version: '5.*' diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/testdata/suspended_helmchart.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/testdata/suspended_helmchart.yaml new file mode 100644 index 0000000000000..76e63f010c577 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/actions/testdata/suspended_helmchart.yaml @@ -0,0 +1,14 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmChart +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + chart: podinfo + reconcileStrategy: ChartVersion + sourceRef: + kind: HelmRepository + name: podinfo + suspend: true + version: '5.*' diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/health.lua b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/health.lua new file mode 100644 index 0000000000000..9ad39cb708294 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/health.lua @@ -0,0 +1,45 @@ +local hs = {} +if obj.spec.suspend ~= nil and obj.spec.suspend == true then + hs.message = obj.kind .. " is suspended" + hs.status = "Suspended" + return hs +end +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local numProgressing = 0 + local numSucceeded = 0 + local message = "" + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + if condition.status == "True" then + numSucceeded = numSucceeded + 1 + elseif condition.status == "Unknown" then + numProgressing = numProgressing + 1 + end + message = condition.reason + elseif condition.type == "Reconciling" and condition.status == "True" then + numProgressing = numProgressing + 1 + elseif condition.type == "ArtifactOutdated" and condition.status == "True" then + message = message .. " " .. condition.reason + elseif condition.type == "ArtifactInStorage" and condition.status == "True" then + numSucceeded = numSucceeded + 1 + end + end + if(numProgressing == 2) then + hs.message = message + hs.status = "Progressing" + return hs + elseif(numSucceeded == 2) then + hs.message = message + hs.status = "Healthy" + return hs + else + hs.message = message + hs.status = "Degraded" + return hs + end + end +end +hs.message = "Status unknown" +hs.status = "Progressing" +return hs diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/health_test.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/health_test.yaml new file mode 100644 index 0000000000000..275b858d3c3c2 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/health_test.yaml @@ -0,0 +1,13 @@ +tests: + # - healthStatus: + # status: Progressing + # message: Progressing + # inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: SourceUnavailable + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: ChartPullSucceeded + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/testdata/degraded.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/testdata/degraded.yaml new file mode 100644 index 0000000000000..1875514c4a623 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/testdata/degraded.yaml @@ -0,0 +1,41 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmChart +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + chart: podinfo + reconcileStrategy: ChartVersion + sourceRef: + kind: HelmRepository + name: podinfo + version: '5.*' +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'processing object: new generation 1 -> 2' + observedGeneration: 2 + reason: ProgressingWithRetry + status: "True" + type: Reconciling + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'failed to get source: HelmRepository.source.toolkit.fluxcd.io "podinfo-faulty" + not found' + observedGeneration: 2 + reason: SourceUnavailable + status: "False" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'failed to get source: HelmRepository.source.toolkit.fluxcd.io "podinfo-faulty" + not found' + observedGeneration: 2 + reason: SourceUnavailable + status: "True" + type: FetchFailed + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: pulled 'podinfo' chart with version '5.2.1' + observedGeneration: 1 + reason: ChartPullSucceeded + status: "True" + type: ArtifactInStorage diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/testdata/healthy.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/testdata/healthy.yaml new file mode 100644 index 0000000000000..7b39f91436460 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/testdata/healthy.yaml @@ -0,0 +1,27 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmChart +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + chart: podinfo + reconcileStrategy: ChartVersion + sourceRef: + kind: HelmRepository + name: podinfo + version: '5.*' +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: pulled 'podinfo' chart with version '5.2.1' + observedGeneration: 1 + reason: ChartPullSucceeded + status: "True" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: pulled 'podinfo' chart with version '5.2.1' + observedGeneration: 1 + reason: ChartPullSucceeded + status: "True" + type: ArtifactInStorage diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmChart/testdata/progressing.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/testdata/progressing.yaml new file mode 100644 index 0000000000000..038511b26308a --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmChart/testdata/progressing.yaml @@ -0,0 +1,16 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmChart +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + chart: podinfo + reconcileStrategy: ChartVersion + sourceRef: + kind: HelmRepository + name: podinfo + version: '5.*' +status: + conditions: [] + diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/action_test.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/action_test.yaml new file mode 100644 index 0000000000000..c4d8d22e4ffce --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/action_test.yaml @@ -0,0 +1,35 @@ +discoveryTests: +- inputPath: testdata/initial_helmrepository.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +- inputPath: testdata/suspended_helmrepository.yaml + result: + - name: reconcile + disabled: true + - name: suspend + disabled: true + - name: resume + disabled: false +- inputPath: testdata/resumed_helmrepository.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +actionTests: +- action: reconcile + inputPath: testdata/initial_helmrepository.yaml + expectedOutputPath: testdata/reconciled_helmrepository.yaml +- action: suspend + inputPath: testdata/initial_helmrepository.yaml + expectedOutputPath: testdata/suspended_helmrepository.yaml +- action: resume + inputPath: testdata/suspended_helmrepository.yaml + expectedOutputPath: testdata/resumed_helmrepository.yaml diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/discovery.lua b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/discovery.lua new file mode 100644 index 0000000000000..9000998815515 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/discovery.lua @@ -0,0 +1,18 @@ +local actions = {} + +actions["reconcile"] = {["disabled"] = true} +actions["suspend"] = {["disabled"] = true} +actions["resume"] = {["disabled"] = true} + +local suspend = false +if obj.spec.suspend ~= nil then + suspend = obj.spec.suspend +end +if suspend then + actions["resume"]["disabled"] = false +else + actions["reconcile"]["disabled"] = false + actions["suspend"]["disabled"] = false +end + +return actions diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/reconcile/action.lua b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/reconcile/action.lua new file mode 100644 index 0000000000000..a534b36fb3ebc --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/reconcile/action.lua @@ -0,0 +1,7 @@ +local os = require("os") +if obj.metadata.annotations == nil then + obj.metadata.annotations = {} +end +obj.metadata.annotations["reconcile.fluxcd.io/requestedAt"] = "By Argo CD at: " .. os.date("!%Y-%m-%dT%X") + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/resume/action.lua b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/resume/action.lua new file mode 100644 index 0000000000000..cb41993777699 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/resume/action.lua @@ -0,0 +1,5 @@ +if obj.spec.suspend ~= nil and obj.spec.suspend then + obj.spec.suspend = false +end + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/suspend/action.lua b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/suspend/action.lua new file mode 100644 index 0000000000000..1a338b2ad1361 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/suspend/action.lua @@ -0,0 +1,3 @@ +obj.spec.suspend = true + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/testdata/initial_helmrepository.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/testdata/initial_helmrepository.yaml new file mode 100644 index 0000000000000..e055d5aa054b3 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/testdata/initial_helmrepository.yaml @@ -0,0 +1,8 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + url: https://stefanprodan.github.io/podinfo diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/testdata/reconciled_helmrepository.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/testdata/reconciled_helmrepository.yaml new file mode 100644 index 0000000000000..d879fada430fc --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/testdata/reconciled_helmrepository.yaml @@ -0,0 +1,10 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: podinfo + namespace: default + annotations: + reconcile.fluxcd.io/requestedAt: 'By Argo CD at: 0001-01-01T00:00:00' +spec: + interval: 5m0s + url: https://stefanprodan.github.io/podinfo diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/testdata/resumed_helmrepository.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/testdata/resumed_helmrepository.yaml new file mode 100644 index 0000000000000..a68df7d1f41bd --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/testdata/resumed_helmrepository.yaml @@ -0,0 +1,9 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + suspend: false + url: https://stefanprodan.github.io/podinfo diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/testdata/suspended_helmrepository.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/testdata/suspended_helmrepository.yaml new file mode 100644 index 0000000000000..fe69f4142ab6f --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/actions/testdata/suspended_helmrepository.yaml @@ -0,0 +1,9 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + suspend: true + url: https://stefanprodan.github.io/podinfo diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/health.lua b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/health.lua new file mode 100644 index 0000000000000..9ad39cb708294 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/health.lua @@ -0,0 +1,45 @@ +local hs = {} +if obj.spec.suspend ~= nil and obj.spec.suspend == true then + hs.message = obj.kind .. " is suspended" + hs.status = "Suspended" + return hs +end +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local numProgressing = 0 + local numSucceeded = 0 + local message = "" + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + if condition.status == "True" then + numSucceeded = numSucceeded + 1 + elseif condition.status == "Unknown" then + numProgressing = numProgressing + 1 + end + message = condition.reason + elseif condition.type == "Reconciling" and condition.status == "True" then + numProgressing = numProgressing + 1 + elseif condition.type == "ArtifactOutdated" and condition.status == "True" then + message = message .. " " .. condition.reason + elseif condition.type == "ArtifactInStorage" and condition.status == "True" then + numSucceeded = numSucceeded + 1 + end + end + if(numProgressing == 2) then + hs.message = message + hs.status = "Progressing" + return hs + elseif(numSucceeded == 2) then + hs.message = message + hs.status = "Healthy" + return hs + else + hs.message = message + hs.status = "Degraded" + return hs + end + end +end +hs.message = "Status unknown" +hs.status = "Progressing" +return hs diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/health_test.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/health_test.yaml new file mode 100644 index 0000000000000..2093ed4de070f --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/health_test.yaml @@ -0,0 +1,13 @@ +tests: + # - healthStatus: + # status: Progressing + # message: Progressing + # inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: Failed + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: Succeeded + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/testdata/degraded.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/testdata/degraded.yaml new file mode 100644 index 0000000000000..ebeddb5e05bc7 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/testdata/degraded.yaml @@ -0,0 +1,38 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + url: https://stefanprodan.github.io/podinfo-faulty +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'processing object: new generation 1 -> 2' + observedGeneration: 2 + reason: ProgressingWithRetry + status: "True" + type: Reconciling + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'failed to fetch Helm repository index: failed to cache index to temporary + file: failed to fetch https://stefanprodan.github.io/podinfo-faulty/index.yaml + : 404 Not Found' + observedGeneration: 2 + reason: Failed + status: "False" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'failed to fetch Helm repository index: failed to cache index to temporary + file: failed to fetch https://stefanprodan.github.io/podinfo-faulty/index.yaml + : 404 Not Found' + observedGeneration: 2 + reason: Failed + status: "True" + type: FetchFailed + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'stored artifact: revision ''sha256:3dfe15d87f81dedc8ddaf116c7302892e54a0d8f269e35f65aaff9ac4d1b179c''' + observedGeneration: 1 + reason: Succeeded + status: "True" + type: ArtifactInStorage diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/testdata/healthy.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/testdata/healthy.yaml new file mode 100644 index 0000000000000..b483b480478cc --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/testdata/healthy.yaml @@ -0,0 +1,22 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + url: https://stefanprodan.github.io/podinfo +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'stored artifact: revision ''sha256:3dfe15d87f81dedc8ddaf116c7302892e54a0d8f269e35f65aaff9ac4d1b179c''' + observedGeneration: 1 + reason: Succeeded + status: "True" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'stored artifact: revision ''sha256:3dfe15d87f81dedc8ddaf116c7302892e54a0d8f269e35f65aaff9ac4d1b179c''' + observedGeneration: 1 + reason: Succeeded + status: "True" + type: ArtifactInStorage diff --git a/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/testdata/progressing.yaml b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/testdata/progressing.yaml new file mode 100644 index 0000000000000..a13de50e72dcb --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/HelmRepository/testdata/progressing.yaml @@ -0,0 +1,11 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + url: https://stefanprodan.github.io/podinfo +status: + conditions: [] + diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/action_test.yaml b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/action_test.yaml new file mode 100644 index 0000000000000..925f5dfa1877c --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/action_test.yaml @@ -0,0 +1,35 @@ +discoveryTests: +- inputPath: testdata/initial_ocirepository.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +- inputPath: testdata/suspended_ocirepository.yaml + result: + - name: reconcile + disabled: true + - name: suspend + disabled: true + - name: resume + disabled: false +- inputPath: testdata/resumed_ocirepository.yaml + result: + - name: reconcile + disabled: false + - name: suspend + disabled: false + - name: resume + disabled: true +actionTests: +- action: reconcile + inputPath: testdata/initial_ocirepository.yaml + expectedOutputPath: testdata/reconciled_ocirepository.yaml +- action: suspend + inputPath: testdata/initial_ocirepository.yaml + expectedOutputPath: testdata/suspended_ocirepository.yaml +- action: resume + inputPath: testdata/suspended_ocirepository.yaml + expectedOutputPath: testdata/resumed_ocirepository.yaml diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/discovery.lua b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/discovery.lua new file mode 100644 index 0000000000000..9000998815515 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/discovery.lua @@ -0,0 +1,18 @@ +local actions = {} + +actions["reconcile"] = {["disabled"] = true} +actions["suspend"] = {["disabled"] = true} +actions["resume"] = {["disabled"] = true} + +local suspend = false +if obj.spec.suspend ~= nil then + suspend = obj.spec.suspend +end +if suspend then + actions["resume"]["disabled"] = false +else + actions["reconcile"]["disabled"] = false + actions["suspend"]["disabled"] = false +end + +return actions diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/reconcile/action.lua b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/reconcile/action.lua new file mode 100644 index 0000000000000..a534b36fb3ebc --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/reconcile/action.lua @@ -0,0 +1,7 @@ +local os = require("os") +if obj.metadata.annotations == nil then + obj.metadata.annotations = {} +end +obj.metadata.annotations["reconcile.fluxcd.io/requestedAt"] = "By Argo CD at: " .. os.date("!%Y-%m-%dT%X") + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/resume/action.lua b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/resume/action.lua new file mode 100644 index 0000000000000..cb41993777699 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/resume/action.lua @@ -0,0 +1,5 @@ +if obj.spec.suspend ~= nil and obj.spec.suspend then + obj.spec.suspend = false +end + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/suspend/action.lua b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/suspend/action.lua new file mode 100644 index 0000000000000..1a338b2ad1361 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/suspend/action.lua @@ -0,0 +1,3 @@ +obj.spec.suspend = true + +return obj diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/testdata/initial_ocirepository.yaml b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/testdata/initial_ocirepository.yaml new file mode 100644 index 0000000000000..cd33f5200ee82 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/testdata/initial_ocirepository.yaml @@ -0,0 +1,10 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: OCIRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + url: oci://ghcr.io/stefanprodan/manifests/podinfo + ref: + tag: latest diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/testdata/reconciled_ocirepository.yaml b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/testdata/reconciled_ocirepository.yaml new file mode 100644 index 0000000000000..b2df7fab875f3 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/testdata/reconciled_ocirepository.yaml @@ -0,0 +1,12 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: OCIRepository +metadata: + name: podinfo + namespace: default + annotations: + reconcile.fluxcd.io/requestedAt: 'By Argo CD at: 0001-01-01T00:00:00' +spec: + interval: 5m0s + url: oci://ghcr.io/stefanprodan/manifests/podinfo + ref: + tag: latest diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/testdata/resumed_ocirepository.yaml b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/testdata/resumed_ocirepository.yaml new file mode 100644 index 0000000000000..5a0ffad096e3c --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/testdata/resumed_ocirepository.yaml @@ -0,0 +1,11 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: OCIRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + url: oci://ghcr.io/stefanprodan/manifests/podinfo + ref: + tag: latest + suspend: false diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/testdata/suspended_ocirepository.yaml b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/testdata/suspended_ocirepository.yaml new file mode 100644 index 0000000000000..3fa77a4980317 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/actions/testdata/suspended_ocirepository.yaml @@ -0,0 +1,11 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: OCIRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + url: oci://ghcr.io/stefanprodan/manifests/podinfo + ref: + tag: latest + suspend: true diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/health.lua b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/health.lua new file mode 100644 index 0000000000000..9ad39cb708294 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/health.lua @@ -0,0 +1,45 @@ +local hs = {} +if obj.spec.suspend ~= nil and obj.spec.suspend == true then + hs.message = obj.kind .. " is suspended" + hs.status = "Suspended" + return hs +end +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local numProgressing = 0 + local numSucceeded = 0 + local message = "" + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + if condition.status == "True" then + numSucceeded = numSucceeded + 1 + elseif condition.status == "Unknown" then + numProgressing = numProgressing + 1 + end + message = condition.reason + elseif condition.type == "Reconciling" and condition.status == "True" then + numProgressing = numProgressing + 1 + elseif condition.type == "ArtifactOutdated" and condition.status == "True" then + message = message .. " " .. condition.reason + elseif condition.type == "ArtifactInStorage" and condition.status == "True" then + numSucceeded = numSucceeded + 1 + end + end + if(numProgressing == 2) then + hs.message = message + hs.status = "Progressing" + return hs + elseif(numSucceeded == 2) then + hs.message = message + hs.status = "Healthy" + return hs + else + hs.message = message + hs.status = "Degraded" + return hs + end + end +end +hs.message = "Status unknown" +hs.status = "Progressing" +return hs diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/health_test.yaml b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/health_test.yaml new file mode 100644 index 0000000000000..04adef01baa8b --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/health_test.yaml @@ -0,0 +1,13 @@ +tests: + # - healthStatus: + # status: Progressing + # message: Progressing + # inputPath: testdata/progressing.yaml + - healthStatus: + status: Degraded + message: OCIArtifactPullFailed + inputPath: testdata/degraded.yaml + - healthStatus: + status: Healthy + message: Succeeded + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/testdata/degraded.yaml b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/testdata/degraded.yaml new file mode 100644 index 0000000000000..9c91459ee2a01 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/testdata/degraded.yaml @@ -0,0 +1,38 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: OCIRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + url: oci://ghcr.io/stefanprodan/manifests/podinfo + ref: + tag: latest +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'processing object: new generation 1 -> 2' + observedGeneration: 2 + reason: Progressing + status: "True" + type: Reconciling + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'failed to determine artifact digest: GET https://ghcr.io/token?scope=repository%!!(MISSING)A(MISSING)stefanprodan%!!(MISSING)F(MISSING)manifests%!!(MISSING)F(MISSING)podinfo-faulty%!!(MISSING)A(MISSING)pull&service=ghcr.io: + DENIED: requested access to the resource is denied' + observedGeneration: 2 + reason: OCIArtifactPullFailed + status: "False" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: 'failed to determine artifact digest: GET https://ghcr.io/token?scope=repository%!A(MISSING)stefanprodan%!F(MISSING)manifests%!F(MISSING)podinfo-faulty%!A(MISSING)pull&service=ghcr.io: + DENIED: requested access to the resource is denied' + observedGeneration: 2 + reason: OCIArtifactPullFailed + status: "True" + type: FetchFailed + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: stored artifact for digest 'latest@sha256:f74fa29c9ebfc7f55b0d829166812ce03c9e3951ab16954863cef1d12837c7a5' + observedGeneration: 1 + reason: Succeeded + status: "True" + type: ArtifactInStorage diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/testdata/healthy.yaml b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/testdata/healthy.yaml new file mode 100644 index 0000000000000..e20aa0f1963fc --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/testdata/healthy.yaml @@ -0,0 +1,24 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: OCIRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + url: oci://ghcr.io/stefanprodan/manifests/podinfo + ref: + tag: latest +status: + conditions: + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: stored artifact for digest 'latest@sha256:f74fa29c9ebfc7f55b0d829166812ce03c9e3951ab16954863cef1d12837c7a5' + observedGeneration: 1 + reason: Succeeded + status: "True" + type: Ready + - lastTransitionTime: "2024-07-16T12:00:00Z" + message: stored artifact for digest 'latest@sha256:f74fa29c9ebfc7f55b0d829166812ce03c9e3951ab16954863cef1d12837c7a5' + observedGeneration: 1 + reason: Succeeded + status: "True" + type: ArtifactInStorage diff --git a/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/testdata/progressing.yaml b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/testdata/progressing.yaml new file mode 100644 index 0000000000000..b6635496469d6 --- /dev/null +++ b/resource_customizations/source.toolkit.fluxcd.io/OCIRepository/testdata/progressing.yaml @@ -0,0 +1,12 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: OCIRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m0s + url: oci://ghcr.io/stefanprodan/manifests/podinfo + ref: + tag: latest +status: + conditions: [] diff --git a/server/account/account.go b/server/account/account.go index 8c499c7da2707..541401a731022 100644 --- a/server/account/account.go +++ b/server/account/account.go @@ -48,7 +48,7 @@ func (s *Server) UpdatePassword(ctx context.Context, q *account.UpdatePasswordRe // assuming user is trying to update someone else if username is different or issuer is not Argo CD if updatedUsername != username || issuer != session.SessionManagerClaimsIssuer { if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceAccounts, rbacpolicy.ActionUpdate, q.Name); err != nil { - return nil, err + return nil, fmt.Errorf("permission denied: %w", err) } } @@ -70,7 +70,7 @@ func (s *Server) UpdatePassword(ctx context.Context, q *account.UpdatePasswordRe iat, err := session.Iat(ctx) if err != nil { - return nil, err + 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.") @@ -80,12 +80,12 @@ func (s *Server) UpdatePassword(ctx context.Context, q *account.UpdatePasswordRe // Need to validate password complexity with regular expression passwordPattern, err := s.settingsMgr.GetPasswordPattern() if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get password pattern: %w", err) } validPasswordRegexp, err := regexp.Compile(passwordPattern) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to compile password regex: %w", err) } if !validPasswordRegexp.Match([]byte(q.NewPassword)) { @@ -95,7 +95,7 @@ func (s *Server) UpdatePassword(ctx context.Context, q *account.UpdatePasswordRe hashedPassword, err := password.HashPassword(q.NewPassword) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to hash password: %w", err) } err = s.settingsMgr.UpdateAccount(updatedUsername, func(acc *settings.Account) error { @@ -105,7 +105,7 @@ func (s *Server) UpdatePassword(ctx context.Context, q *account.UpdatePasswordRe return nil }) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to update account password: %w", err) } if updatedUsername == username { @@ -132,7 +132,7 @@ func (s *Server) CanI(ctx context.Context, r *account.CanIRequest) (*account.Can if r.Resource == "logs" { serverRBACLogEnforceEnable, err := s.settingsMgr.GetServerRBACLogEnforceEnable() if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get server RBAC log enforcement setting: %w", err) } if !serverRBACLogEnforceEnable { @@ -174,7 +174,7 @@ func (s *Server) ensureHasAccountPermission(ctx context.Context, action string, return nil } if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceAccounts, action, account); err != nil { - return err + return fmt.Errorf("permission denied for account %s with action %s: %w", account, action, err) } return nil } @@ -184,7 +184,7 @@ func (s *Server) ListAccounts(ctx context.Context, r *account.ListAccountRequest resp := account.AccountsList{} accounts, err := s.settingsMgr.GetAccounts() if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get accounts: %w", err) } for name, a := range accounts { if err := s.ensureHasAccountPermission(ctx, rbacpolicy.ActionGet, name); err == nil { @@ -200,11 +200,11 @@ func (s *Server) ListAccounts(ctx context.Context, r *account.ListAccountRequest // GetAccount returns an account func (s *Server) GetAccount(ctx context.Context, r *account.GetAccountRequest) (*account.Account, error) { if err := s.ensureHasAccountPermission(ctx, rbacpolicy.ActionGet, r.Name); err != nil { - return nil, err + return nil, fmt.Errorf("permission denied to get account %s: %w", r.Name, err) } a, err := s.settingsMgr.GetAccount(r.Name) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get account %s: %w", r.Name, err) } return toApiAccount(r.Name, *a), nil } @@ -212,14 +212,14 @@ func (s *Server) GetAccount(ctx context.Context, r *account.GetAccountRequest) ( // CreateToken creates a token func (s *Server) CreateToken(ctx context.Context, r *account.CreateTokenRequest) (*account.CreateTokenResponse, error) { if err := s.ensureHasAccountPermission(ctx, rbacpolicy.ActionUpdate, r.Name); err != nil { - return nil, err + return nil, fmt.Errorf("permission denied to create token for account %s: %w", r.Name, err) } id := r.Id if id == "" { uniqueId, err := uuid.NewRandom() if err != nil { - return nil, err + return nil, fmt.Errorf("failed to generate unique ID: %w", err) } id = uniqueId.String() } @@ -252,7 +252,7 @@ func (s *Server) CreateToken(ctx context.Context, r *account.CreateTokenRequest) return nil }) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to update account with new token: %w", err) } return &account.CreateTokenResponse{Token: tokenString}, nil } @@ -260,7 +260,7 @@ func (s *Server) CreateToken(ctx context.Context, r *account.CreateTokenRequest) // DeleteToken deletes a token func (s *Server) DeleteToken(ctx context.Context, r *account.DeleteTokenRequest) (*account.EmptyResponse, error) { if err := s.ensureHasAccountPermission(ctx, rbacpolicy.ActionUpdate, r.Name); err != nil { - return nil, err + return nil, fmt.Errorf("permission denied to delete account %s: %w", r.Name, err) } err := s.settingsMgr.UpdateAccount(r.Name, func(account *settings.Account) error { @@ -271,7 +271,7 @@ func (s *Server) DeleteToken(ctx context.Context, r *account.DeleteTokenRequest) return status.Errorf(codes.NotFound, "token with id '%s' does not exist", r.Id) }) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to delete account %s: %w", r.Name, err) } return &account.EmptyResponse{}, nil } diff --git a/server/account/account_test.go b/server/account/account_test.go index ca5571f117048..03290ad3692c4 100644 --- a/server/account/account_test.go +++ b/server/account/account_test.go @@ -292,7 +292,8 @@ func TestCreateToken_UserSpecifiedID(t *testing.T) { _, err = accountServer.CreateToken(ctx, &account.CreateTokenRequest{Name: "account1", Id: "test"}) require.Error(t, err) - assert.Contains(t, "account already has token with id 'test'", err.Error()) + assert.Contains(t, err.Error(), "failed to update account with new token:") + assert.Contains(t, err.Error(), "account already has token with id 'test'") } func TestDeleteToken_SuccessfullyRemoved(t *testing.T) { diff --git a/server/application/application.go b/server/application/application.go index 7fd22c37458d6..08a8ab19d008b 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -112,6 +112,7 @@ func NewServer( settingsMgr *settings.SettingsManager, projInformer cache.SharedIndexInformer, enabledNamespaces []string, + enableK8sEvent []string, ) (application.ApplicationServiceServer, AppResourceTreeFn) { if appBroadcaster == nil { appBroadcaster = &broadcasterHandler{} @@ -133,7 +134,7 @@ func NewServer( kubectl: kubectl, enf: enf, projectLock: projectLock, - auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server"), + auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server", enableK8sEvent), settingsMgr: settingsMgr, projInformer: projInformer, enabledNamespaces: enabledNamespaces, @@ -181,7 +182,7 @@ func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespa if apierr.IsNotFound(err) { if project != "" { // We know that the user was allowed to get the Application, but the Application does not exist. Return 404. - return nil, nil, status.Errorf(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error()) + return nil, nil, status.Error(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error()) } // 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. @@ -203,7 +204,7 @@ func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespa // The user specified a project. We would have returned a 404 if the user had access to the app, but the app // did not exist. So we have to return a 404 when the app does exist, but the user does not have access. // Otherwise, they could infer that the app exists based on the error code. - return nil, nil, status.Errorf(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error()) + return nil, nil, status.Error(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error()) } // The user didn't specify a project. We always return permission denied for both lack of access and lack of // existence. @@ -220,7 +221,7 @@ func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespa }).Warnf("user tried to %s application in project %s, but the application is in project %s", action, project, effectiveProject) // The user has access to the app, but the app is in a different project. Return 404, meaning "app doesn't // exist in that project". - return nil, nil, status.Errorf(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error()) + return nil, nil, status.Error(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error()) } // Get the app's associated project, and make sure all project restrictions are enforced. proj, err := s.getAppProject(ctx, a, logCtx) @@ -511,24 +512,25 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan } manifestInfo, err := client.GenerateManifest(ctx, &apiclient.ManifestRequest{ - Repo: repo, - Revision: source.TargetRevision, - AppLabelKey: appInstanceLabelKey, - AppName: a.InstanceName(s.ns), - Namespace: a.Spec.Destination.Namespace, - ApplicationSource: &source, - Repos: helmRepos, - KustomizeOptions: kustomizeOptions, - KubeVersion: serverVersion, - ApiVersions: argo.APIResourcesToStrings(apiResources, true), - HelmRepoCreds: helmCreds, - HelmOptions: helmOptions, - TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)), - EnabledSourceTypes: enableGenerateManifests, - ProjectName: proj.Name, - ProjectSourceRepos: proj.Spec.SourceRepos, - HasMultipleSources: a.Spec.HasMultipleSources(), - RefSources: refSources, + Repo: repo, + Revision: source.TargetRevision, + AppLabelKey: appInstanceLabelKey, + AppName: a.InstanceName(s.ns), + Namespace: a.Spec.Destination.Namespace, + ApplicationSource: &source, + Repos: helmRepos, + KustomizeOptions: kustomizeOptions, + KubeVersion: serverVersion, + ApiVersions: argo.APIResourcesToStrings(apiResources, true), + HelmRepoCreds: helmCreds, + HelmOptions: helmOptions, + TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)), + EnabledSourceTypes: enableGenerateManifests, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, + HasMultipleSources: a.Spec.HasMultipleSources(), + RefSources: refSources, + AnnotationManifestGeneratePaths: a.GetAnnotation(v1alpha1.AnnotationKeyManifestGeneratePaths), }) if err != nil { return fmt.Errorf("error generating manifests: %w", err) @@ -629,22 +631,23 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get } req := &apiclient.ManifestRequest{ - Repo: repo, - Revision: source.TargetRevision, - AppLabelKey: appInstanceLabelKey, - AppName: a.Name, - Namespace: a.Spec.Destination.Namespace, - ApplicationSource: &source, - Repos: helmRepos, - KustomizeOptions: kustomizeOptions, - KubeVersion: serverVersion, - ApiVersions: argo.APIResourcesToStrings(apiResources, true), - HelmRepoCreds: helmCreds, - HelmOptions: helmOptions, - TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)), - EnabledSourceTypes: enableGenerateManifests, - ProjectName: proj.Name, - ProjectSourceRepos: proj.Spec.SourceRepos, + Repo: repo, + Revision: source.TargetRevision, + AppLabelKey: appInstanceLabelKey, + AppName: a.Name, + Namespace: a.Spec.Destination.Namespace, + ApplicationSource: &source, + Repos: helmRepos, + KustomizeOptions: kustomizeOptions, + KubeVersion: serverVersion, + ApiVersions: argo.APIResourcesToStrings(apiResources, true), + HelmRepoCreds: helmCreds, + HelmOptions: helmOptions, + TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)), + EnabledSourceTypes: enableGenerateManifests, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, + AnnotationManifestGeneratePaths: a.GetAnnotation(v1alpha1.AnnotationKeyManifestGeneratePaths), } repoStreamClient, err := client.GenerateManifestWithFiles(stream.Context()) @@ -1495,71 +1498,9 @@ func (s *Server) RevisionMetadata(ctx context.Context, q *application.RevisionMe return nil, err } - var versionId int64 = 0 - if q.VersionId != nil { - versionId = int64(*q.VersionId) - } - - var source *v1alpha1.ApplicationSource - - // To support changes between single source and multi source revisions - // we have to calculate if the operation has to be done as multisource or not. - // There are 2 different scenarios, checking current revision and historic revision - // - Current revision (VersionId is nil or 0): - // - The application is multi source and required version too -> multi source - // - The application is single source and the required version too -> single source - // - The application is multi source and the required version is single source -> single source - // - The application is single source and the required version is multi source -> multi source - // - Historic revision: - // - The application is multi source and the previous one too -> multi source - // - The application is single source and the previous one too -> single source - // - The application is multi source and the previous one is single source -> multi source - // - The application is single source and the previous one is multi source -> single source - isRevisionMultiSource := a.Spec.HasMultipleSources() - emptyHistory := len(a.Status.History) == 0 - if !emptyHistory { - for _, h := range a.Status.History { - if h.ID == versionId { - isRevisionMultiSource = len(h.Revisions) > 0 - break - } - } - } - - // If the historical data is empty (because the app hasn't been synced yet) - // we can use the source, if not (the app has been synced at least once) - // we have to use the history because sources can be added/removed - if emptyHistory { - if isRevisionMultiSource { - source = &a.Spec.Sources[*q.SourceIndex] - } else { - s := a.Spec.GetSource() - source = &s - } - } else { - // the source count can change during the time, we cannot just trust in .status.sync - // because if a source has been added/removed, the revisions there won't match - // as this is only used for the UI and not internally, we can use the historical data - // using the specific revisionId - for _, h := range a.Status.History { - if h.ID == versionId { - // The iteration values are assigned to the respective iteration variables as in an assignment statement. - // The iteration variables may be declared by the “range” clause using a form of short variable declaration (:=). - // In this case their types are set to the types of the respective iteration values and their scope is the block of the "for" statement; - // they are re-used in each iteration. If the iteration variables are declared outside the "for" statement, - // after execution their values will be those of the last iteration. - // https://golang.org/ref/spec#For_statements - h := h - if isRevisionMultiSource { - source = &h.Sources[*q.SourceIndex] - } else { - source = &h.Source - } - } - } - } - if source == nil { - return nil, fmt.Errorf("revision not found: %w", err) + source, err := getAppSourceBySourceIndexAndVersionId(a, q.SourceIndex, q.VersionId) + if err != nil { + return nil, fmt.Errorf("error getting app source by source index and version ID: %w", err) } repo, err := s.db.GetRepository(ctx, source.RepoURL, proj.Name) @@ -1585,22 +1526,9 @@ func (s *Server) RevisionChartDetails(ctx context.Context, q *application.Revisi return nil, err } - var source *v1alpha1.ApplicationSource - if a.Spec.HasMultipleSources() { - // the source count can change during the time, we cannot just trust in .status.sync - // because if a source has been added/removed, the revisions there won't match - // as this is only used for the UI and not internally, we can use the historical data - // using the specific revisionId - for _, h := range a.Status.History { - if h.ID == int64(*q.VersionId) { - source = &h.Sources[*q.SourceIndex] - } - } - if source == nil { - return nil, fmt.Errorf("revision not found: %w", err) - } - } else { - source = a.Spec.Source + source, err := getAppSourceBySourceIndexAndVersionId(a, q.SourceIndex, q.VersionId) + if err != nil { + return nil, fmt.Errorf("error getting app source by source index and version ID: %w", err) } if source.Chart == "" { @@ -1622,6 +1550,76 @@ func (s *Server) RevisionChartDetails(ctx context.Context, q *application.Revisi }) } +// getAppSourceBySourceIndexAndVersionId returns the source for a specific source index and version ID. Source index and +// version ID are optional. If the source index is not specified, it defaults to 0. If the version ID is not specified, +// 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 *appv1.Application, sourceIndexMaybe *int32, versionIdMaybe *int32) (appv1.ApplicationSource, error) { + // Start with all the app's configured sources. + sources := a.Spec.GetSources() + + // If the user specified a version, get the sources for that version. If the version is not found, return an error. + if versionIdMaybe != nil { + versionId := int64(*versionIdMaybe) + var err error + sources, err = getSourcesByVersionId(a, versionId) + if err != nil { + return appv1.ApplicationSource{}, fmt.Errorf("error getting source by version ID: %w", err) + } + } + + // Start by assuming we want the first source. + sourceIndex := 0 + + // If the user specified a source index, use that instead. + if sourceIndexMaybe != nil { + sourceIndex = int(*sourceIndexMaybe) + if sourceIndex >= len(sources) { + if len(sources) == 1 { + return appv1.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 are only %d sources", sourceIndex, len(sources)) + } + } + + source := sources[sourceIndex] + + return source, nil +} + +// 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) (appv1.RevisionHistory, bool) { + for _, h := range histories { + if h.ID == versionId { + return h, true + } + } + 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 *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) + } + + h, ok := getRevisionHistoryByVersionId(a.Status.History, versionId) + if !ok { + return nil, fmt.Errorf("revision history not found for version ID %d", versionId) + } + + if len(h.Sources) > 0 { + return h.Sources, nil + } + + return []v1alpha1.ApplicationSource{h.Source}, nil +} + func isMatchingResource(q *application.ResourcesQuery, key kube.ResourceKey) bool { return (q.GetName() == "" || q.GetName() == key.Name) && (q.GetNamespace() == "" || q.GetNamespace() == key.Namespace) && @@ -2006,7 +2004,7 @@ func (s *Server) resolveSourceRevisions(ctx context.Context, a *appv1.Applicatio } revision, displayRevision, err := s.resolveRevision(ctx, a, syncReq, index) if err != nil { - return "", "", nil, nil, status.Errorf(codes.FailedPrecondition, err.Error()) + return "", "", nil, nil, status.Error(codes.FailedPrecondition, err.Error()) } sourceRevisions[index] = revision displayRevisions[index] = displayRevision @@ -2021,7 +2019,7 @@ func (s *Server) resolveSourceRevisions(ctx context.Context, a *appv1.Applicatio } revision, displayRevision, err := s.resolveRevision(ctx, a, syncReq, -1) if err != nil { - return "", "", nil, nil, status.Errorf(codes.FailedPrecondition, err.Error()) + return "", "", nil, nil, status.Error(codes.FailedPrecondition, err.Error()) } return revision, displayRevision, nil, nil, nil } @@ -2305,7 +2303,8 @@ func (s *Server) logAppEvent(a *appv1.Application, ctx context.Context, reason s user = "Unknown user" } message := fmt.Sprintf("%s %s", user, action) - s.auditLogger.LogAppEvent(a, eventInfo, message, user) + 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(res *appv1.ResourceNode, ctx context.Context, reason string, action string) { @@ -2372,14 +2371,14 @@ func (s *Server) getAvailableActions(resourceOverrides map[string]appv1.Resource ResourceOverrides: resourceOverrides, } - discoveryScript, err := luaVM.GetResourceActionDiscovery(obj) + discoveryScripts, err := luaVM.GetResourceActionDiscovery(obj) if err != nil { return nil, fmt.Errorf("error getting Lua discovery script: %w", err) } - if discoveryScript == "" { + if len(discoveryScripts) == 0 { return []appv1.ResourceAction{}, nil } - availableActions, err := luaVM.ExecuteResourceActionDiscovery(obj, discoveryScript) + availableActions, err := luaVM.ExecuteResourceActionDiscovery(obj, discoveryScripts) if err != nil { return nil, fmt.Errorf("error executing Lua discovery script: %w", err) } @@ -2448,7 +2447,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(ctx, app, proj, newObj) + err := s.verifyResourcePermitted(app, proj, newObj) if err != nil { return nil, err } @@ -2541,7 +2540,7 @@ func (s *Server) patchResource(ctx context.Context, config *rest.Config, liveObj return &application.ApplicationResponse{}, nil } -func (s *Server) verifyResourcePermitted(ctx context.Context, app *appv1.Application, proj *appv1.AppProject, obj *unstructured.Unstructured) 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 { @@ -2678,7 +2677,7 @@ func (s *Server) isNamespaceEnabled(namespace string) bool { return security.IsNamespaceEnabled(namespace, s.ns, s.enabledNamespaces) } -// getProjectFromApplicationQuery gets the project names from a query. If the legacy "project" field was specified, use +// getProjectsFromApplicationQuery gets the project names from a query. If the legacy "project" field was specified, use // that. Otherwise, use the newer "projects" field. func getProjectsFromApplicationQuery(q application.ApplicationQuery) []string { if q.Project != nil { diff --git a/server/application/application_test.go b/server/application/application_test.go index ca81e7a6151a2..c182829fa19bd 100644 --- a/server/application/application_test.go +++ b/server/application/application_test.go @@ -69,6 +69,8 @@ const ( fakeRepoURL = "https://git.com/repo.git" ) +var testEnableEventList []string = argo.DefaultEnableEventList() + func fakeRepo() *appsv1.Repository { return &appsv1.Repository{ Repo: fakeRepoURL, @@ -306,6 +308,7 @@ func newTestAppServerWithEnforcerConfigure(f func(*rbac.Enforcer), t *testing.T, settingsMgr, projInformer, []string{}, + testEnableEventList, ) return server.(*Server) } @@ -486,6 +489,7 @@ func newTestAppServerWithEnforcerConfigureWithBenchmark(f func(*rbac.Enforcer), settingsMgr, projInformer, []string{}, + testEnableEventList, ) return server.(*Server) } @@ -2652,7 +2656,10 @@ func TestIsApplicationPermitted(t *testing.T) { } func TestAppNamespaceRestrictions(t *testing.T) { + t.Parallel() + t.Run("List applications in controller namespace", func(t *testing.T) { + t.Parallel() testApp := newTestApp() appServer := newTestAppServer(t, testApp) apps, err := appServer.List(context.TODO(), &application.ApplicationQuery{}) @@ -2661,6 +2668,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { }) t.Run("List applications with non-allowed apps existing", func(t *testing.T) { + t.Parallel() testApp1 := newTestApp() testApp1.Namespace = "argocd-1" appServer := newTestAppServer(t, testApp1) @@ -2670,6 +2678,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { }) t.Run("List applications with non-allowed apps existing and explicit ns request", func(t *testing.T) { + t.Parallel() testApp1 := newTestApp() testApp2 := newTestApp() testApp2.Namespace = "argocd-1" @@ -2680,6 +2689,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { }) t.Run("List applications with allowed apps in other namespaces", func(t *testing.T) { + t.Parallel() testApp1 := newTestApp() testApp1.Namespace = "argocd-1" appServer := newTestAppServer(t, testApp1) @@ -2690,6 +2700,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { }) t.Run("Get application in control plane namespace", func(t *testing.T) { + t.Parallel() testApp := newTestApp() appServer := newTestAppServer(t, testApp) app, err := appServer.Get(context.TODO(), &application.ApplicationQuery{ @@ -2699,6 +2710,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { assert.Equal(t, "test-app", app.GetName()) }) t.Run("Get application in other namespace when forbidden", func(t *testing.T) { + t.Parallel() testApp := newTestApp() testApp.Namespace = "argocd-1" appServer := newTestAppServer(t, testApp) @@ -2711,6 +2723,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { require.Nil(t, app) }) t.Run("Get application in other namespace when allowed", func(t *testing.T) { + t.Parallel() testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" @@ -2734,6 +2747,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { require.Equal(t, "test-app", app.Name) }) t.Run("Get application in other namespace when project is not allowed", func(t *testing.T) { + t.Parallel() testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" @@ -2756,6 +2770,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { require.ErrorContains(t, err, "app is not allowed in project") }) t.Run("Create application in other namespace when allowed", func(t *testing.T) { + t.Parallel() testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" @@ -2779,6 +2794,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { }) t.Run("Create application in other namespace when not allowed by project", func(t *testing.T) { + t.Parallel() testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" @@ -2801,6 +2817,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { }) t.Run("Create application in other namespace when not allowed by configuration", func(t *testing.T) { + t.Parallel() testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" @@ -2822,6 +2839,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { require.ErrorContains(t, err, "namespace 'argocd-1' is not permitted") }) t.Run("Get application sync window in other namespace when project is allowed", func(t *testing.T) { + t.Parallel() testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" @@ -2840,6 +2858,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { assert.Empty(t, active.ActiveWindows) }) t.Run("Get application sync window in other namespace when project is not allowed", func(t *testing.T) { + t.Parallel() testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" @@ -2859,6 +2878,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { require.ErrorContains(t, err, "app is not allowed in project") }) t.Run("Get list of links in other namespace when project is not allowed", func(t *testing.T) { + t.Parallel() testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" @@ -2881,6 +2901,7 @@ func TestAppNamespaceRestrictions(t *testing.T) { require.ErrorContains(t, err, "app is not allowed in project") }) t.Run("Get list of links in other namespace when project is allowed", func(t *testing.T) { + t.Parallel() testApp := newTestApp() testApp.Namespace = "argocd-1" testApp.Spec.Project = "other-ns" @@ -3025,3 +3046,269 @@ func TestServer_ResolveSourceRevisions_SingleSource(t *testing.T) { assert.Equal(t, ([]string)(nil), sourceRevisions) assert.Equal(t, ([]string)(nil), displayRevisions) } + +func Test_RevisionMetadata(t *testing.T) { + t.Parallel() + + singleSourceApp := newTestApp() + singleSourceApp.Name = "single-source-app" + singleSourceApp.Spec = appv1.ApplicationSpec{ + Source: &appv1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + Path: "helm-guestbook", + TargetRevision: "HEAD", + }, + } + + multiSourceApp := newTestApp() + multiSourceApp.Name = "multi-source-app" + multiSourceApp.Spec = appv1.ApplicationSpec{ + Sources: []appv1.ApplicationSource{ + { + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + Path: "helm-guestbook", + TargetRevision: "HEAD", + }, + { + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + Path: "kustomize-guestbook", + TargetRevision: "HEAD", + }, + }, + } + + singleSourceHistory := []appv1.RevisionHistory{ + { + ID: 1, + Source: singleSourceApp.Spec.GetSource(), + Revision: "a", + }, + } + multiSourceHistory := []appv1.RevisionHistory{ + { + ID: 1, + Sources: multiSourceApp.Spec.GetSources(), + Revisions: []string{"a", "b"}, + }, + } + + testCases := []struct { + name string + multiSource bool + history *struct { + matchesSourceType bool + } + sourceIndex *int32 + versionId *int32 + expectErrorContains *string + }{ + { + name: "single-source app without history, no source index, no version ID", + multiSource: false, + }, + { + name: "single-source app without history, no source index, missing version ID", + multiSource: false, + versionId: ptr.To(int32(999)), + expectErrorContains: ptr.To("the app has no history"), + }, + { + name: "single source app without history, present source index, no version ID", + multiSource: false, + sourceIndex: ptr.To(int32(0)), + }, + { + name: "single source app without history, invalid source index, no version ID", + multiSource: false, + sourceIndex: ptr.To(int32(999)), + expectErrorContains: ptr.To("source index 999 not found"), + }, + { + name: "single source app with matching history, no source index, no version ID", + multiSource: false, + history: &struct{ matchesSourceType bool }{true}, + }, + { + name: "single source app with matching history, no source index, missing version ID", + multiSource: false, + history: &struct{ matchesSourceType bool }{true}, + versionId: ptr.To(int32(999)), + expectErrorContains: ptr.To("history not found for version ID 999"), + }, + { + name: "single source app with matching history, no source index, present version ID", + multiSource: false, + history: &struct{ matchesSourceType bool }{true}, + versionId: ptr.To(int32(1)), + }, + { + name: "single source app with multi-source history, no source index, no version ID", + multiSource: false, + history: &struct{ matchesSourceType bool }{false}, + }, + { + name: "single source app with multi-source history, no source index, missing version ID", + multiSource: false, + history: &struct{ matchesSourceType bool }{false}, + versionId: ptr.To(int32(999)), + expectErrorContains: ptr.To("history not found for version ID 999"), + }, + { + name: "single source app with multi-source history, no source index, present version ID", + multiSource: false, + history: &struct{ matchesSourceType bool }{false}, + versionId: ptr.To(int32(1)), + }, + { + name: "single-source app with multi-source history, source index 1, no version ID", + multiSource: false, + sourceIndex: ptr.To(int32(1)), + history: &struct{ matchesSourceType bool }{false}, + // Since the user requested source index 1, but no version ID, we'll get an error when looking at the live + // source, because the live source is single-source. + expectErrorContains: ptr.To("there is only 1 source"), + }, + { + name: "single-source app with multi-source history, invalid source index, no version ID", + multiSource: false, + sourceIndex: ptr.To(int32(999)), + history: &struct{ matchesSourceType bool }{false}, + expectErrorContains: ptr.To("source index 999 not found"), + }, + { + name: "single-source app with multi-source history, valid source index, present version ID", + multiSource: false, + sourceIndex: ptr.To(int32(1)), + history: &struct{ matchesSourceType bool }{false}, + versionId: ptr.To(int32(1)), + }, + { + name: "multi-source app without history, no source index, no version ID", + multiSource: true, + }, + { + name: "multi-source app without history, no source index, missing version ID", + multiSource: true, + versionId: ptr.To(int32(999)), + expectErrorContains: ptr.To("the app has no history"), + }, + { + name: "multi-source app without history, present source index, no version ID", + multiSource: true, + sourceIndex: ptr.To(int32(1)), + }, + { + name: "multi-source app without history, invalid source index, no version ID", + multiSource: true, + sourceIndex: ptr.To(int32(999)), + expectErrorContains: ptr.To("source index 999 not found"), + }, + { + name: "multi-source app with matching history, no source index, no version ID", + multiSource: true, + history: &struct{ matchesSourceType bool }{true}, + }, + { + name: "multi-source app with matching history, no source index, missing version ID", + multiSource: true, + history: &struct{ matchesSourceType bool }{true}, + versionId: ptr.To(int32(999)), + expectErrorContains: ptr.To("history not found for version ID 999"), + }, + { + name: "multi-source app with matching history, no source index, present version ID", + multiSource: true, + history: &struct{ matchesSourceType bool }{true}, + versionId: ptr.To(int32(1)), + }, + { + name: "multi-source app with single-source history, no source index, no version ID", + multiSource: true, + history: &struct{ matchesSourceType bool }{false}, + }, + { + name: "multi-source app with single-source history, no source index, missing version ID", + multiSource: true, + history: &struct{ matchesSourceType bool }{false}, + versionId: ptr.To(int32(999)), + expectErrorContains: ptr.To("history not found for version ID 999"), + }, + { + name: "multi-source app with single-source history, no source index, present version ID", + multiSource: true, + history: &struct{ matchesSourceType bool }{false}, + versionId: ptr.To(int32(1)), + }, + { + name: "multi-source app with single-source history, source index 1, no version ID", + multiSource: true, + sourceIndex: ptr.To(int32(1)), + history: &struct{ matchesSourceType bool }{false}, + }, + { + name: "multi-source app with single-source history, invalid source index, no version ID", + multiSource: true, + sourceIndex: ptr.To(int32(999)), + history: &struct{ matchesSourceType bool }{false}, + expectErrorContains: ptr.To("source index 999 not found"), + }, + { + name: "multi-source app with single-source history, valid source index, present version ID", + multiSource: true, + sourceIndex: ptr.To(int32(0)), + history: &struct{ matchesSourceType bool }{false}, + versionId: ptr.To(int32(1)), + }, + { + name: "multi-source app with single-source history, source index 1, present version ID", + multiSource: true, + sourceIndex: ptr.To(int32(1)), + history: &struct{ matchesSourceType bool }{false}, + versionId: ptr.To(int32(1)), + expectErrorContains: ptr.To("source index 1 not found"), + }, + } + + for _, tc := range testCases { + tcc := tc + t.Run(tcc.name, func(t *testing.T) { + t.Parallel() + + app := singleSourceApp.DeepCopy() + if tcc.multiSource { + app = multiSourceApp.DeepCopy() + } + if tcc.history != nil { + if tcc.history.matchesSourceType { + if tcc.multiSource { + app.Status.History = multiSourceHistory + } else { + app.Status.History = singleSourceHistory + } + } else { + if tcc.multiSource { + app.Status.History = singleSourceHistory + } else { + app.Status.History = multiSourceHistory + } + } + } + + s := newTestAppServer(t, app) + + request := &application.RevisionMetadataQuery{ + Name: ptr.To(app.Name), + Revision: ptr.To("HEAD"), + SourceIndex: tcc.sourceIndex, + VersionId: tcc.versionId, + } + + _, err := s.RevisionMetadata(context.Background(), request) + if tcc.expectErrorContains != nil { + require.ErrorContains(t, err, *tcc.expectErrorContains) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/server/application/logs.go b/server/application/logs.go index 9034da9471212..778f04edec66e 100644 --- a/server/application/logs.go +++ b/server/application/logs.go @@ -144,8 +144,8 @@ func mergeLogStreams(streams []chan logEntry, bufferingDuration time.Duration) c _ = send(true) - close(merged) ticker.Stop() + close(merged) }() return merged } diff --git a/server/application/mocks/Broadcaster.go b/server/application/mocks/Broadcaster.go index 4ad9c7cfec2d4..2e5f13bd88c8b 100644 --- a/server/application/mocks/Broadcaster.go +++ b/server/application/mocks/Broadcaster.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks diff --git a/server/application/terminal.go b/server/application/terminal.go index b0fad379e8ae6..e6ddc6d832df3 100644 --- a/server/application/terminal.go +++ b/server/application/terminal.go @@ -33,29 +33,32 @@ import ( type terminalHandler struct { appLister applisters.ApplicationLister db db.ArgoDB - enf *rbac.Enforcer cache *servercache.Cache appResourceTreeFn func(ctx context.Context, app *appv1.Application) (*appv1.ApplicationTree, error) allowedShells []string namespace string enabledNamespaces []string sessionManager *util_session.SessionManager + terminalOptions *TerminalOptions +} + +type TerminalOptions struct { + DisableAuth bool + Enf *rbac.Enforcer } // NewHandler returns a new terminal handler. -func NewHandler(appLister applisters.ApplicationLister, namespace string, enabledNamespaces []string, db db.ArgoDB, enf *rbac.Enforcer, cache *servercache.Cache, - appResourceTree AppResourceTreeFn, allowedShells []string, sessionManager *util_session.SessionManager, -) *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, - enf: enf, cache: cache, appResourceTreeFn: appResourceTree, allowedShells: allowedShells, namespace: namespace, enabledNamespaces: enabledNamespaces, sessionManager: sessionManager, + terminalOptions: terminalOptions, } } @@ -146,12 +149,12 @@ func (s *terminalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := r.Context() appRBACName := security.RBACName(s.namespace, project, appNamespace, app) - if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplications, rbacpolicy.ActionGet, appRBACName); err != nil { + if err := s.terminalOptions.Enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplications, rbacpolicy.ActionGet, appRBACName); err != nil { http.Error(w, err.Error(), http.StatusUnauthorized) return } - if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceExec, rbacpolicy.ActionCreate, appRBACName); err != nil { + if err := s.terminalOptions.Enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceExec, rbacpolicy.ActionCreate, appRBACName); err != nil { http.Error(w, err.Error(), http.StatusUnauthorized) return } @@ -229,7 +232,7 @@ func (s *terminalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { fieldLog.Info("terminal session starting") - session, err := newTerminalSession(w, r, nil, s.sessionManager) + session, err := newTerminalSession(ctx, w, r, nil, s.sessionManager, appRBACName, s.terminalOptions) if err != nil { http.Error(w, "Failed to start terminal session", http.StatusBadRequest) return diff --git a/server/application/websocket.go b/server/application/websocket.go index 4c43daed01e76..86c85749d803b 100644 --- a/server/application/websocket.go +++ b/server/application/websocket.go @@ -1,6 +1,7 @@ package application import ( + "context" "encoding/json" "fmt" "net/http" @@ -8,6 +9,7 @@ import ( "time" "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/server/rbacpolicy" httputil "github.com/argoproj/argo-cd/v2/util/http" util_session "github.com/argoproj/argo-cd/v2/util/session" @@ -32,6 +34,7 @@ var upgrader = func() websocket.Upgrader { // terminalSession implements PtyHandler type terminalSession struct { + ctx context.Context wsConn *websocket.Conn sizeChan chan remotecommand.TerminalSize doneChan chan struct{} @@ -40,6 +43,8 @@ type terminalSession struct { writeLock sync.Mutex sessionManager *util_session.SessionManager token *string + appRBACName string + terminalOpts *TerminalOptions } // getToken get auth token from web socket request @@ -49,7 +54,7 @@ func getToken(r *http.Request) (string, error) { } // newTerminalSession create terminalSession -func newTerminalSession(w http.ResponseWriter, r *http.Request, responseHeader http.Header, sessionManager *util_session.SessionManager) (*terminalSession, error) { +func newTerminalSession(ctx context.Context, w http.ResponseWriter, r *http.Request, responseHeader http.Header, sessionManager *util_session.SessionManager, appRBACName string, terminalOpts *TerminalOptions) (*terminalSession, error) { token, err := getToken(r) if err != nil { return nil, err @@ -60,12 +65,15 @@ func newTerminalSession(w http.ResponseWriter, r *http.Request, responseHeader h return nil, err } session := &terminalSession{ + ctx: ctx, wsConn: conn, tty: true, sizeChan: make(chan remotecommand.TerminalSize), doneChan: make(chan struct{}), sessionManager: sessionManager, token: &token, + appRBACName: appRBACName, + terminalOpts: terminalOpts, } return session, nil } @@ -126,8 +134,35 @@ func (t *terminalSession) reconnect() (int, error) { return 0, nil } -// Read called in a loop from remotecommand as long as the process is running -func (t *terminalSession) Read(p []byte) (int, error) { +func (t *terminalSession) validatePermissions(p []byte) (int, error) { + permissionDeniedMessage, _ := json.Marshal(TerminalMessage{ + Operation: "stdout", + Data: "Permission denied", + }) + if err := t.terminalOpts.Enf.EnforceErr(t.ctx.Value("claims"), rbacpolicy.ResourceApplications, rbacpolicy.ActionGet, t.appRBACName); err != nil { + err = t.wsConn.WriteMessage(websocket.TextMessage, permissionDeniedMessage) + if err != nil { + log.Errorf("permission denied message err: %v", err) + } + return copy(p, EndOfTransmission), permissionDeniedErr + } + + if err := t.terminalOpts.Enf.EnforceErr(t.ctx.Value("claims"), rbacpolicy.ResourceExec, rbacpolicy.ActionCreate, t.appRBACName); err != nil { + err = t.wsConn.WriteMessage(websocket.TextMessage, permissionDeniedMessage) + if err != nil { + log.Errorf("permission denied message err: %v", err) + } + return copy(p, EndOfTransmission), permissionDeniedErr + } + return 0, nil +} + +func (t *terminalSession) performValidationsAndReconnect(p []byte) (int, error) { + // In disable auth mode, no point verifying the token or validating permissions + if t.terminalOpts.DisableAuth { + return 0, nil + } + // check if token still valid _, newToken, err := t.sessionManager.VerifyToken(*t.token) // err in case if token is revoked, newToken in case if refresh happened @@ -135,6 +170,20 @@ func (t *terminalSession) Read(p []byte) (int, error) { // need to send reconnect code in case if token was refreshed return t.reconnect() } + code, err := t.validatePermissions(p) + if err != nil { + return code, err + } + + return 0, nil +} + +// Read called in a loop from remotecommand as long as the process is running +func (t *terminalSession) Read(p []byte) (int, error) { + code, err := t.performValidationsAndReconnect(p) + if err != nil { + return code, err + } t.readLock.Lock() _, message, err := t.wsConn.ReadMessage() diff --git a/server/application/websocket_test.go b/server/application/websocket_test.go index 40b6e98bd68c8..0d048a1727d1b 100644 --- a/server/application/websocket_test.go +++ b/server/application/websocket_test.go @@ -1,25 +1,65 @@ package application import ( + "context" "encoding/json" "net/http" "net/http/httptest" "strings" "testing" + 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/v2/common" + "github.com/argoproj/argo-cd/v2/util/assets" + "github.com/argoproj/argo-cd/v2/util/rbac" + + "github.com/golang-jwt/jwt/v4" "github.com/gorilla/websocket" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func reconnect(w http.ResponseWriter, r *http.Request) { +func newTestTerminalSession(w http.ResponseWriter, r *http.Request) terminalSession { upgrader := websocket.Upgrader{} c, err := upgrader.Upgrade(w, r, nil) if err != nil { - return + return terminalSession{} } - ts := terminalSession{wsConn: c} + return terminalSession{wsConn: c} +} + +func newEnforcer() *rbac.Enforcer { + additionalConfig := make(map[string]string, 0) + kubeclientset := fake.NewSimpleClientset(&v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: testNamespace, + Name: "argocd-cm", + Labels: map[string]string{ + "app.kubernetes.io/part-of": "argocd", + }, + }, + Data: additionalConfig, + }, &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "argocd-secret", + Namespace: testNamespace, + }, + Data: map[string][]byte{ + "admin.password": []byte("test"), + "server.secretkey": []byte("test"), + }, + }) + + enforcer := rbac.NewEnforcer(kubeclientset, testNamespace, common.ArgoCDRBACConfigMapName, nil) + return enforcer +} + +func reconnect(w http.ResponseWriter, r *http.Request) { + ts := newTestTerminalSession(w, r) _, _ = ts.reconnect() } @@ -44,3 +84,83 @@ func TestReconnect(t *testing.T) { require.NoError(t, err) assert.Equal(t, ReconnectMessage, message.Data) } + +func testServerConnection(t *testing.T, testFunc func(w http.ResponseWriter, r *http.Request), expectPermissionDenied bool) { + s := httptest.NewServer(http.HandlerFunc(testFunc)) + defer s.Close() + + u := "ws" + strings.TrimPrefix(s.URL, "http") + + // Connect to the server + ws, _, err := websocket.DefaultDialer.Dial(u, nil) + require.NoError(t, err) + + defer ws.Close() + if expectPermissionDenied { + _, p, _ := ws.ReadMessage() + + var message TerminalMessage + + err = json.Unmarshal(p, &message) + + require.NoError(t, err) + assert.Equal(t, "Permission denied", message.Data) + } +} + +func TestVerifyAndReconnectDisableAuthTrue(t *testing.T) { + validate := func(w http.ResponseWriter, r *http.Request) { + ts := newTestTerminalSession(w, r) + // Currently testing only the usecase of disableAuth: true since the disableAuth: false case + // requires a valid token to be passed in the request. + // Note that running with disableAuth: false will surprisingly succeed as well, because + // the underlying token nil pointer dereference is swallowed in a location I didn't find, + // or even swallowed by the test framework. + ts.terminalOpts = &TerminalOptions{DisableAuth: true} + code, err := ts.performValidationsAndReconnect([]byte{}) + assert.Equal(t, 0, code) + require.NoError(t, err) + } + testServerConnection(t, validate, false) +} + +func TestValidateWithAdminPermissions(t *testing.T) { + validate := func(w http.ResponseWriter, r *http.Request) { + enf := newEnforcer() + _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) + enf.SetDefaultRole("role:admin") + 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(context.Background(), "claims", &jwt.MapClaims{"groups": []string{"admin"}}) + _, err := ts.validatePermissions([]byte{}) + require.NoError(t, err) + } + + testServerConnection(t, validate, false) +} + +func TestValidateWithoutPermissions(t *testing.T) { + validate := func(w http.ResponseWriter, r *http.Request) { + enf := newEnforcer() + _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) + enf.SetDefaultRole("role:test") + 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(context.Background(), "claims", &jwt.MapClaims{"groups": []string{"test"}}) + _, err := ts.validatePermissions([]byte{}) + require.Error(t, err) + assert.Equal(t, permissionDeniedErr.Error(), err.Error()) + } + + testServerConnection(t, validate, true) +} diff --git a/server/applicationset/applicationset.go b/server/applicationset/applicationset.go index 5f2b7508b9a2e..259b59c911321 100644 --- a/server/applicationset/applicationset.go +++ b/server/applicationset/applicationset.go @@ -1,6 +1,7 @@ package applicationset import ( + "bytes" "context" "fmt" "reflect" @@ -17,18 +18,26 @@ import ( apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + 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/server/rbacpolicy" "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" @@ -36,24 +45,36 @@ import ( ) type Server struct { - ns string - db db.ArgoDB - enf *rbac.Enforcer - appclientset appclientset.Interface - appsetInformer cache.SharedIndexInformer - appsetLister applisters.ApplicationSetLister - projLister applisters.AppProjectNamespaceLister - auditLogger *argo.AuditLogger - settings *settings.SettingsManager - projectLock sync.KeyLock - enabledNamespaces []string + ns string + db db.ArgoDB + enf *rbac.Enforcer + k8sClient kubernetes.Interface + dynamicClient dynamic.Interface + client client.Client + repoClientSet repoapiclient.Clientset + appclientset appclientset.Interface + appsetInformer cache.SharedIndexInformer + appsetLister applisters.ApplicationSetLister + projLister applisters.AppProjectNamespaceLister + auditLogger *argo.AuditLogger + settings *settings.SettingsManager + projectLock sync.KeyLock + enabledNamespaces []string + GitSubmoduleEnabled bool + EnableNewGitFileGlobbing bool + ScmRootCAPath string + AllowedScmProviders []string + EnableScmProviders bool } // NewServer returns a new instance of the ApplicationSet service func NewServer( db db.ArgoDB, kubeclientset kubernetes.Interface, + dynamicClientset dynamic.Interface, + kubeControllerClientset client.Client, enf *rbac.Enforcer, + repoClientSet repoapiclient.Clientset, appclientset appclientset.Interface, appsetInformer cache.SharedIndexInformer, appsetLister applisters.ApplicationSetLister, @@ -62,19 +83,34 @@ func NewServer( namespace string, projectLock sync.KeyLock, enabledNamespaces []string, + gitSubmoduleEnabled bool, + enableNewGitFileGlobbing bool, + scmRootCAPath string, + allowedScmProviders []string, + enableScmProviders bool, + enableK8sEvent []string, ) applicationset.ApplicationSetServiceServer { s := &Server{ - ns: namespace, - db: db, - enf: enf, - appclientset: appclientset, - appsetInformer: appsetInformer, - appsetLister: appsetLister, - projLister: projLister, - settings: settings, - projectLock: projectLock, - auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server"), - enabledNamespaces: enabledNamespaces, + ns: namespace, + db: db, + enf: enf, + dynamicClient: dynamicClientset, + client: kubeControllerClientset, + k8sClient: kubeclientset, + repoClientSet: repoClientSet, + appclientset: appclientset, + appsetInformer: appsetInformer, + appsetLister: appsetLister, + projLister: projLister, + settings: settings, + projectLock: projectLock, + auditLogger: argo.NewAuditLogger(namespace, kubeclientset, "argocd-server", enableK8sEvent), + enabledNamespaces: enabledNamespaces, + GitSubmoduleEnabled: gitSubmoduleEnabled, + EnableNewGitFileGlobbing: enableNewGitFileGlobbing, + ScmRootCAPath: scmRootCAPath, + AllowedScmProviders: allowedScmProviders, + EnableScmProviders: enableScmProviders, } return s } @@ -151,7 +187,7 @@ func (s *Server) Create(ctx context.Context, q *applicationset.ApplicationSetCre return nil, fmt.Errorf("error creating ApplicationSets: ApplicationSets is nil in request") } - projectName, err := s.validateAppSet(ctx, appset) + projectName, err := s.validateAppSet(appset) if err != nil { return nil, fmt.Errorf("error validating ApplicationSets: %w", err) } @@ -166,6 +202,23 @@ func (s *Server) Create(ctx context.Context, q *applicationset.ApplicationSetCre return nil, fmt.Errorf("error checking create permissions for ApplicationSets %s : %w", appset.Name, err) } + if q.GetDryRun() { + apps, err := s.generateApplicationSetApps(ctx, log.WithField("applicationset", appset.Name), *appset, namespace) + if err != nil { + return nil, fmt.Errorf("unable to generate Applications of ApplicationSet: %w", err) + } + + statusMap := appsetstatus.GetResourceStatusMap(appset) + statusMap = appsetstatus.BuildResourceStatus(statusMap, apps) + + statuses := []v1alpha1.ResourceStatus{} + for _, status := range statusMap { + statuses = append(statuses, status) + } + appset.Status.Resources = statuses + return appset, nil + } + s.projectLock.RLock(projectName) defer s.projectLock.RUnlock(projectName) @@ -209,6 +262,28 @@ func (s *Server) Create(ctx context.Context, q *applicationset.ApplicationSetCre return updated, nil } +func (s *Server) generateApplicationSetApps(ctx context.Context, logEntry *log.Entry, appset v1alpha1.ApplicationSet, namespace string) ([]v1alpha1.Application, error) { + argoCDDB := s.db + + scmConfig := generators.NewSCMConfig(s.ScmRootCAPath, s.AllowedScmProviders, s.EnableScmProviders, github_app.NewAuthCredentials(argoCDDB.(db.RepoCredsDB))) + + 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) + if err != nil { + return nil, fmt.Errorf("error generating applications: %w", err) + } + return apps, nil +} + 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 @@ -288,10 +363,44 @@ func (s *Server) ResourceTree(ctx context.Context, q *applicationset.Application return nil, err } - return s.buildApplicationSetTree(ctx, a) + return s.buildApplicationSetTree(a) +} + +func (s *Server) Generate(ctx context.Context, q *applicationset.ApplicationSetGenerateRequest) (*applicationset.ApplicationSetGenerateResponse, error) { + appset := q.GetApplicationSet() + + if appset == nil { + return nil, fmt.Errorf("error creating ApplicationSets: ApplicationSets is nil in request") + } + namespace := s.appsetNamespaceOrDefault(appset.Namespace) + + if !s.isNamespaceEnabled(namespace) { + return nil, security.NamespaceNotPermittedError(namespace) + } + projectName, err := s.validateAppSet(appset) + if err != nil { + return nil, fmt.Errorf("error validating ApplicationSets: %w", err) + } + if err := s.checkCreatePermissions(ctx, appset, projectName); err != nil { + return nil, fmt.Errorf("error checking create permissions for ApplicationSets %s : %w", appset.Name, err) + } + + logs := bytes.NewBuffer(nil) + logger := log.New() + logger.SetOutput(logs) + + apps, err := s.generateApplicationSetApps(ctx, logger.WithField("applicationset", appset.Name), *appset, namespace) + if err != nil { + return nil, fmt.Errorf("unable to generate Applications of ApplicationSet: %w\n%s", err, logs.String()) + } + res := &applicationset.ApplicationSetGenerateResponse{} + for i := range apps { + res.Applications = append(res.Applications, &apps[i]) + } + return res, nil } -func (s *Server) buildApplicationSetTree(ctx context.Context, a *v1alpha1.ApplicationSet) (*v1alpha1.ApplicationSetTree, error) { +func (s *Server) buildApplicationSetTree(a *v1alpha1.ApplicationSet) (*v1alpha1.ApplicationSetTree, error) { var tree v1alpha1.ApplicationSetTree gvk := v1alpha1.ApplicationSetSchemaGroupVersionKind @@ -318,7 +427,7 @@ func (s *Server) buildApplicationSetTree(ctx context.Context, a *v1alpha1.Applic return &tree, nil } -func (s *Server) validateAppSet(ctx context.Context, appset *v1alpha1.ApplicationSet) (string, error) { +func (s *Server) validateAppSet(appset *v1alpha1.ApplicationSet) (string, error) { if appset == nil { return "", fmt.Errorf("ApplicationSet cannot be validated for nil value") } diff --git a/server/applicationset/applicationset.proto b/server/applicationset/applicationset.proto index 07ed4e2c89384..e2e4663e94e84 100644 --- a/server/applicationset/applicationset.proto +++ b/server/applicationset/applicationset.proto @@ -37,6 +37,7 @@ message ApplicationSetResponse { message ApplicationSetCreateRequest { github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSet applicationset = 1; bool upsert = 2; + bool dryRun = 3; } @@ -52,14 +53,32 @@ message ApplicationSetTreeQuery { string appsetNamespace = 2; } +// ApplicationSetGetQuery is a query for applicationset resources +message ApplicationSetGenerateRequest { + // the applicationsets + 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.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.v2.pkg.apis.application.v1alpha1.ApplicationSet) { option (google.api.http).get = "/api/v1/applicationsets/{name}"; } + // Generate generates + rpc Generate (ApplicationSetGenerateRequest) returns (ApplicationSetGenerateResponse) { + option (google.api.http) = { + post: "/api/v1/applicationsets" + body: "*" + }; + } + //List returns list of applicationset rpc List (ApplicationSetListQuery) returns (github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSetList) { option (google.api.http).get = "/api/v1/applicationsets"; diff --git a/server/applicationset/applicationset_test.go b/server/applicationset/applicationset_test.go index 031a58cfde62e..0b83dfa2c4c90 100644 --- a/server/applicationset/applicationset_test.go +++ b/server/applicationset/applicationset_test.go @@ -2,12 +2,15 @@ package applicationset import ( "context" + "sort" "testing" "github.com/argoproj/gitops-engine/pkg/health" "github.com/argoproj/pkg/sync" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" 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" @@ -19,6 +22,7 @@ import ( apps "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned/fake" appinformer "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions" "github.com/argoproj/argo-cd/v2/server/rbacpolicy" + "github.com/argoproj/argo-cd/v2/util/argo" "github.com/argoproj/argo-cd/v2/util/assets" "github.com/argoproj/argo-cd/v2/util/db" "github.com/argoproj/argo-cd/v2/util/errors" @@ -31,6 +35,8 @@ const ( fakeRepoURL = "https://git.com/repo.git" ) +var testEnableEventList []string = argo.DefaultEnableEventList() + func fakeRepo() *appsv1.Repository { return &appsv1.Repository{ Repo: fakeRepoURL, @@ -142,7 +148,10 @@ func newTestAppSetServerWithEnforcerConfigure(f func(*rbac.Enforcer), namespace server := NewServer( db, kubeclientset, + nil, + nil, enforcer, + nil, fakeAppsClientset, appInformer, factory.Argoproj().V1alpha1().ApplicationSets().Lister(), @@ -151,6 +160,12 @@ func newTestAppSetServerWithEnforcerConfigure(f func(*rbac.Enforcer), namespace testNamespace, sync.NewKeyLock(), []string{testNamespace, "external-namespace"}, + true, + true, + "", + []string{}, + true, + testEnableEventList, ) return server.(*Server) } @@ -221,7 +236,7 @@ func testListAppsetsWithLabels(t *testing.T, appsetQuery applicationset.Applicat t.Run(validTest.testName, func(t *testing.T) { appsetQuery.Selector = validTest.label res, err := appServer.List(context.Background(), &appsetQuery) - assert.NoError(t, err) + require.NoError(t, err) apps := []string{} for i := range res.Items { apps = append(apps, res.Items[i].Name) @@ -315,7 +330,7 @@ func TestListAppSetsWithoutNamespace(t *testing.T) { appsetQuery := applicationset.ApplicationSetListQuery{} res, err := appSetServer.List(context.Background(), &appsetQuery) - assert.NoError(t, err) + require.NoError(t, err) assert.Empty(t, res.Items) } @@ -331,7 +346,7 @@ func TestCreateAppSet(t *testing.T) { Applicationset: testAppSet, } _, err := appServer.Create(context.Background(), &createReq) - assert.NoError(t, err) + require.NoError(t, err) } func TestCreateAppSetTemplatedProject(t *testing.T) { @@ -357,6 +372,60 @@ func TestCreateAppSetWrongNamespace(t *testing.T) { assert.Equal(t, "namespace 'NOT-ALLOWED' is not permitted", err.Error()) } +func TestCreateAppSetDryRun(t *testing.T) { + testAppSet := newTestAppSet() + appServer := newTestAppSetServer() + testAppSet.Spec.Template.Name = "{{name}}" + testAppSet.Spec.Generators = []appsv1.ApplicationSetGenerator{ + { + List: &appsv1.ListGenerator{ + Elements: []apiextensionsv1.JSON{{Raw: []byte(`{"name": "a"}`)}, {Raw: []byte(`{"name": "b"}`)}}, + }, + }, + } + createReq := applicationset.ApplicationSetCreateRequest{ + Applicationset: testAppSet, + DryRun: true, + } + result, err := appServer.Create(context.Background(), &createReq) + + require.NoError(t, err) + assert.Len(t, result.Status.Resources, 2) + + // Sort resulting application by name + sort.Slice(result.Status.Resources, func(i, j int) bool { + return result.Status.Resources[i].Name < result.Status.Resources[j].Name + }) + + assert.Equal(t, "a", result.Status.Resources[0].Name) + assert.Equal(t, testAppSet.Namespace, result.Status.Resources[0].Namespace) + assert.Equal(t, "b", result.Status.Resources[1].Name) + assert.Equal(t, testAppSet.Namespace, result.Status.Resources[1].Namespace) +} + +func TestCreateAppSetDryRunWithDuplicate(t *testing.T) { + testAppSet := newTestAppSet() + appServer := newTestAppSetServer() + testAppSet.Spec.Template.Name = "{{name}}" + testAppSet.Spec.Generators = []appsv1.ApplicationSetGenerator{ + { + List: &appsv1.ListGenerator{ + Elements: []apiextensionsv1.JSON{{Raw: []byte(`{"name": "a"}`)}, {Raw: []byte(`{"name": "a"}`)}}, + }, + }, + } + createReq := applicationset.ApplicationSetCreateRequest{ + Applicationset: testAppSet, + DryRun: true, + } + result, err := appServer.Create(context.Background(), &createReq) + + require.NoError(t, err) + assert.Len(t, result.Status.Resources, 1) + assert.Equal(t, "a", result.Status.Resources[0].Name) + assert.Equal(t, testAppSet.Namespace, result.Status.Resources[0].Namespace) +} + func TestGetAppSet(t *testing.T) { appSet1 := newTestAppSet(func(appset *appsv1.ApplicationSet) { appset.Name = "AppSet1" @@ -376,7 +445,7 @@ func TestGetAppSet(t *testing.T) { appsetQuery := applicationset.ApplicationSetGetQuery{Name: "AppSet1"} res, err := appSetServer.Get(context.Background(), &appsetQuery) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "AppSet1", res.Name) }) @@ -386,7 +455,7 @@ func TestGetAppSet(t *testing.T) { appsetQuery := applicationset.ApplicationSetGetQuery{Name: "AppSet1", AppsetNamespace: testNamespace} res, err := appSetServer.Get(context.Background(), &appsetQuery) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, "AppSet1", res.Name) }) @@ -419,7 +488,7 @@ func TestDeleteAppSet(t *testing.T) { appsetQuery := applicationset.ApplicationSetDeleteRequest{Name: "AppSet1"} res, err := appSetServer.Delete(context.Background(), &appsetQuery) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, &applicationset.ApplicationSetResponse{}, res) }) @@ -429,7 +498,7 @@ func TestDeleteAppSet(t *testing.T) { appsetQuery := applicationset.ApplicationSetDeleteRequest{Name: "AppSet1", AppsetNamespace: testNamespace} res, err := appSetServer.Delete(context.Background(), &appsetQuery) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, &applicationset.ApplicationSetResponse{}, res) }) } @@ -460,7 +529,7 @@ func TestUpdateAppSet(t *testing.T) { updated, err := appServer.updateAppSet(appSet, newAppSet, context.Background(), true) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, map[string]string{ "annotation-key1": "annotation-value1-updated", "annotation-key2": "annotation-value2", @@ -476,7 +545,7 @@ func TestUpdateAppSet(t *testing.T) { updated, err := appServer.updateAppSet(appSet, newAppSet, context.Background(), false) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, map[string]string{ "annotation-key1": "annotation-value1-updated", }, updated.Annotations) @@ -546,7 +615,7 @@ func TestResourceTree(t *testing.T) { appsetQuery := applicationset.ApplicationSetTreeQuery{Name: "AppSet1"} res, err := appSetServer.ResourceTree(context.Background(), &appsetQuery) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedTree, res) }) @@ -556,7 +625,7 @@ func TestResourceTree(t *testing.T) { appsetQuery := applicationset.ApplicationSetTreeQuery{Name: "AppSet1", AppsetNamespace: testNamespace} res, err := appSetServer.ResourceTree(context.Background(), &appsetQuery) - assert.NoError(t, err) + require.NoError(t, err) assert.Equal(t, expectedTree, res) }) diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go index ed59e90f54f5b..c92600448ed75 100644 --- a/server/cluster/cluster.go +++ b/server/cluster/cluster.go @@ -165,7 +165,7 @@ func (s *Server) Create(ctx context.Context, q *cluster.ClusterCreateRequest) (* } else if q.Upsert { return s.Update(ctx, &cluster.ClusterUpdateRequest{Cluster: c}) } else { - return nil, status.Errorf(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("cluster", existing, c)) + return nil, status.Error(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("cluster", existing, c)) } } else { return nil, err @@ -471,7 +471,9 @@ func (s *Server) toAPIResponse(clust *appv1.Cluster) *appv1.Cluster { clust.Config.ExecProviderConfig.Args = nil } // populate deprecated fields for backward compatibility + // nolint:staticcheck clust.ServerVersion = clust.Info.ServerVersion + // nolint:staticcheck clust.ConnectionState = clust.Info.ConnectionState return clust } diff --git a/server/deeplinks/deeplinks.go b/server/deeplinks/deeplinks.go index 13d332072ce40..933dcde42decb 100644 --- a/server/deeplinks/deeplinks.go +++ b/server/deeplinks/deeplinks.go @@ -6,8 +6,8 @@ import ( "text/template" "github.com/Masterminds/sprig/v3" - "github.com/antonmedv/expr" "github.com/argoproj/gitops-engine/pkg/utils/kube" + "github.com/expr-lang/expr" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/utils/ptr" @@ -84,45 +84,41 @@ func EvaluateDeepLinksResponse(obj map[string]interface{}, name string, links [] finalLinks := []*application.LinkInfo{} errors := []string{} for _, link := range links { - t, err := template.New("deep-link").Funcs(sprigFuncMap).Parse(link.URL) - if err != nil { - errors = append(errors, fmt.Sprintf("failed to parse link template '%v', error=%v", link.URL, err.Error())) - continue - } - finalURL := bytes.Buffer{} - err = t.Execute(&finalURL, obj) - if err != nil { - errors = append(errors, fmt.Sprintf("failed to evaluate link template '%v' with resource %v, error=%v", link.URL, name, err.Error())) - continue - } if link.Condition != nil { out, err := expr.Eval(*link.Condition, obj) if err != nil { errors = append(errors, fmt.Sprintf("failed to evaluate link condition '%v' with resource %v, error=%v", *link.Condition, name, err.Error())) continue } - switch resOut := out.(type) { + switch condResult := out.(type) { case bool: - if resOut { - finalLinks = append(finalLinks, &application.LinkInfo{ - Title: ptr.To(link.Title), - Url: ptr.To(finalURL.String()), - Description: link.Description, - IconClass: link.IconClass, - }) + if !condResult { + continue } default: errors = append(errors, fmt.Sprintf("link condition '%v' evaluated to non-boolean value for resource %v", *link.Condition, name)) continue } - } else { - finalLinks = append(finalLinks, &application.LinkInfo{ - Title: ptr.To(link.Title), - Url: ptr.To(finalURL.String()), - Description: link.Description, - IconClass: link.IconClass, - }) } + + t, err := template.New("deep-link").Funcs(sprigFuncMap).Parse(link.URL) + if err != nil { + errors = append(errors, fmt.Sprintf("failed to parse link template '%v', error=%v", link.URL, err.Error())) + continue + } + finalURL := bytes.Buffer{} + err = t.Execute(&finalURL, obj) + if err != nil { + errors = append(errors, fmt.Sprintf("failed to evaluate link template '%v' with resource %v, error=%v", link.URL, name, err.Error())) + continue + } + + finalLinks = append(finalLinks, &application.LinkInfo{ + Title: ptr.To(link.Title), + Url: ptr.To(finalURL.String()), + Description: link.Description, + IconClass: link.IconClass, + }) } return &application.LinksResponse{ Items: finalLinks, diff --git a/server/deeplinks/deeplinks_test.go b/server/deeplinks/deeplinks_test.go index 8458a72770f50..217b8b93b7dbe 100644 --- a/server/deeplinks/deeplinks_test.go +++ b/server/deeplinks/deeplinks_test.go @@ -19,6 +19,7 @@ import ( ) type deepLinkTC struct { + name string appObj *unstructured.Unstructured clusterObj *unstructured.Unstructured resourceObj *unstructured.Unstructured @@ -70,6 +71,7 @@ func TestDeepLinks(t *testing.T) { require.NoError(t, err) testTable := []deepLinkTC{ { + name: "link to git repo per cluster", appObj: appObj, resourceObj: resourceObj, projectObj: projectObj, @@ -86,6 +88,7 @@ func TestDeepLinks(t *testing.T) { error: []string{}, }, { + name: "link to git repo per cluster with abbreviated name", appObj: appObj, resourceObj: resourceObj, projectObj: projectObj, @@ -102,6 +105,7 @@ func TestDeepLinks(t *testing.T) { error: []string{}, }, { + name: "condition on missing key", appObj: appObj, resourceObj: resourceObj, projectObj: projectObj, @@ -126,9 +130,10 @@ func TestDeepLinks(t *testing.T) { Title: ptr.To("link"), Url: ptr.To("http://example.com/test&testns"), }}, - error: []string{"failed to evaluate link condition 'application.metadata.test matches \"test\"' with resource test, error=interface conversion: interface {} is nil, not string (1:27)\n | application.metadata.test matches \"test\"\n | ..........................^"}, + error: []string{}, }, { + name: "condition on invalid expression", appObj: appObj, resourceObj: resourceObj, projectObj: projectObj, @@ -151,6 +156,7 @@ func TestDeepLinks(t *testing.T) { error: []string{"link condition '1 + 1' evaluated to non-boolean value for resource test"}, }, { + name: "condition on app and project name", appObj: appObj, resourceObj: resourceObj, projectObj: projectObj, @@ -166,12 +172,38 @@ func TestDeepLinks(t *testing.T) { }}, error: []string{}, }, + { + name: "evaluate template for valid condition", + appObj: appObj, + resourceObj: resourceObj, + projectObj: projectObj, + inputLinks: []settings.DeepLink{ + { + Title: "link", + URL: "http://not-evaluated.com/{{ index \"invalid\" .application.metadata.labels }}", + Condition: ptr.To(`false`), + }, + { + Title: "link", + URL: "http://evaluated.com/{{ index \"invalid\" .application.metadata.labels }}", + Condition: ptr.To(`true`), + }, + }, + outputLinks: []*application.LinkInfo{}, + error: []string{ + "failed to evaluate link template 'http://evaluated.com/{{ index \"invalid\" .application.metadata.labels }}' with resource test, error=template: deep-link:1:24: executing \"deep-link\" at : error calling index: cannot index slice/array with nil", + }, + }, } for _, tc := range testTable { - objs := CreateDeepLinksObject(tc.resourceObj, tc.appObj, tc.clusterObj, tc.projectObj) - output, err := EvaluateDeepLinksResponse(objs, tc.appObj.GetName(), tc.inputLinks) - assert.Equal(t, tc.error, err, strings.Join(err, ",")) - assert.True(t, reflect.DeepEqual(output.Items, tc.outputLinks)) + tcc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + objs := CreateDeepLinksObject(tcc.resourceObj, tcc.appObj, tcc.clusterObj, tcc.projectObj) + output, err := EvaluateDeepLinksResponse(objs, tcc.appObj.GetName(), tcc.inputLinks) + assert.Equal(t, tcc.error, err, strings.Join(err, ",")) + assert.True(t, reflect.DeepEqual(output.Items, tcc.outputLinks)) + }) } } diff --git a/server/extension/extension.go b/server/extension/extension.go index 95dc539a70af1..706dfbbb31abd 100644 --- a/server/extension/extension.go +++ b/server/extension/extension.go @@ -22,6 +22,7 @@ import ( "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" ) @@ -64,6 +65,14 @@ const ( // the client, its value will be overridden by the extension // handler. HeaderArgoCDTargetClusterName = "Argocd-Target-Cluster-Name" + + // HeaderArgoCDUsername is the header name that defines the logged + // in user authenticated by Argo CD. + HeaderArgoCDUsername = "Argocd-Username" + + // HeaderArgoCDGroups is the header name that provides the 'groups' + // claim from the users authenticated in Argo CD. + HeaderArgoCDGroups = "Argocd-User-Groups" ) // RequestResources defines the authorization scope for @@ -265,6 +274,34 @@ func (p *DefaultProjectGetter) GetClusters(project string) ([]*v1alpha1.Cluster, return p.db.GetProjectClusters(context.TODO(), project) } +// UserGetter defines the contract to retrieve info from the logged in user. +type UserGetter interface { + GetUser(ctx context.Context) string + GetGroups(ctx context.Context) []string +} + +// DefaultUserGetter is the main UserGetter implementation. +type DefaultUserGetter struct { + policyEnf *rbacpolicy.RBACPolicyEnforcer +} + +// NewDefaultUserGetter return a new default UserGetter +func NewDefaultUserGetter(policyEnf *rbacpolicy.RBACPolicyEnforcer) *DefaultUserGetter { + return &DefaultUserGetter{ + policyEnf: policyEnf, + } +} + +// GetUser will return the current logged in user +func (u *DefaultUserGetter) GetUser(ctx context.Context) string { + return session.Username(ctx) +} + +// GetGroups will return the groups associated with the logged in user. +func (u *DefaultUserGetter) GetGroups(ctx context.Context) []string { + return session.Groups(ctx, u.policyEnf.GetScopes()) +} + // ApplicationGetter defines the contract to retrieve the application resource. type ApplicationGetter interface { Get(ns, name string) (*v1alpha1.Application, error) @@ -282,7 +319,7 @@ func NewDefaultApplicationGetter(al applisters.ApplicationLister) *DefaultApplic } } -// Get will retrieve the application resorce for the given namespace and name. +// Get will retrieve the application resource for the given namespace and name. func (a *DefaultApplicationGetter) Get(ns, name string) (*v1alpha1.Application, error) { return a.appLister.Applications(ns).Get(name) } @@ -302,6 +339,7 @@ type Manager struct { rbac RbacEnforcer registry ExtensionRegistry metricsReg ExtensionMetricsRegistry + userGetter UserGetter } // ExtensionMetricsRegistry exposes operations to update http metrics in the Argo CD @@ -317,13 +355,14 @@ type ExtensionMetricsRegistry interface { } // NewManager will initialize a new manager. -func NewManager(log *log.Entry, sg SettingsGetter, ag ApplicationGetter, pg ProjectGetter, rbac RbacEnforcer) *Manager { +func NewManager(log *log.Entry, sg SettingsGetter, ag ApplicationGetter, pg ProjectGetter, rbac RbacEnforcer, ug UserGetter) *Manager { return &Manager{ log: log, settings: sg, application: ag, project: pg, rbac: rbac, + userGetter: ug, } } @@ -699,7 +738,9 @@ func (m *Manager) CallExtension() func(http.ResponseWriter, *http.Request) { return } - prepareRequest(r, extName, app) + user := m.userGetter.GetUser(r.Context()) + groups := m.userGetter.GetGroups(r.Context()) + prepareRequest(r, extName, app, user, groups) m.log.Debugf("proxing request for extension %q", extName) // httpsnoop package is used to properly wrap the responseWriter // and avoid optional intefaces issue: @@ -719,9 +760,13 @@ func registerMetrics(extName string, metrics httpsnoop.Metrics, extensionMetrics } // prepareRequest is responsible for cleaning the incoming request URL removing -// the Argo CD extension API section from it. It will set the cluster destination name -// and cluster destination server in the headers as it is defined in the given app. -func prepareRequest(r *http.Request, extName string, app *v1alpha1.Application) { +// the Argo CD extension API section from it. It provides additional information to +// the backend service appending them in the outgoing request headers. The appended +// headers are: +// - Cluster destination name +// - Cluster destination server +// - Argo CD authenticated username +func prepareRequest(r *http.Request, extName string, app *v1alpha1.Application, username string, groups []string) { r.URL.Path = strings.TrimPrefix(r.URL.Path, fmt.Sprintf("%s/%s", URLPrefix, extName)) if app.Spec.Destination.Name != "" { r.Header.Set(HeaderArgoCDTargetClusterName, app.Spec.Destination.Name) @@ -729,6 +774,12 @@ func prepareRequest(r *http.Request, extName string, app *v1alpha1.Application) if app.Spec.Destination.Server != "" { r.Header.Set(HeaderArgoCDTargetClusterURL, app.Spec.Destination.Server) } + if username != "" { + r.Header.Set(HeaderArgoCDUsername, username) + } + if len(groups) > 0 { + r.Header.Set(HeaderArgoCDGroups, strings.Join(groups, ",")) + } } // AddMetricsRegistry will associate the given metricsReg in the Manager. diff --git a/server/extension/extension_test.go b/server/extension/extension_test.go index 7d6a8e5ffb02b..300e1e89a490d 100644 --- a/server/extension/extension_test.go +++ b/server/extension/extension_test.go @@ -150,7 +150,7 @@ func TestRegisterExtensions(t *testing.T) { logger, _ := test.NewNullLogger() logEntry := logger.WithContext(context.Background()) - m := extension.NewManager(logEntry, settMock, nil, nil, nil) + m := extension.NewManager(logEntry, settMock, nil, nil, nil, nil) return &fixture{ settingsGetterMock: settMock, @@ -245,6 +245,7 @@ func TestCallExtension(t *testing.T) { rbacMock *mocks.RbacEnforcer projMock *mocks.ProjectGetter metricsMock *mocks.ExtensionMetricsRegistry + userMock *mocks.UserGetter manager *extension.Manager } defaultProjectName := "project-name" @@ -255,10 +256,11 @@ func TestCallExtension(t *testing.T) { rbacMock := &mocks.RbacEnforcer{} projMock := &mocks.ProjectGetter{} metricsMock := &mocks.ExtensionMetricsRegistry{} + userMock := &mocks.UserGetter{} logger, _ := test.NewNullLogger() logEntry := logger.WithContext(context.Background()) - m := extension.NewManager(logEntry, settMock, appMock, projMock, rbacMock) + m := extension.NewManager(logEntry, settMock, appMock, projMock, rbacMock, userMock) m.AddMetricsRegistry(metricsMock) mux := http.NewServeMux() @@ -272,6 +274,7 @@ func TestCallExtension(t *testing.T) { rbacMock: rbacMock, projMock: projMock, metricsMock: metricsMock, + userMock: userMock, manager: m, } } @@ -347,6 +350,11 @@ func TestCallExtension(t *testing.T) { f.rbacMock.On("EnforceErr", mock.Anything, rbacpolicy.ResourceExtensions, rbacpolicy.ActionInvoke, mock.Anything).Return(extAccessError) } + withUser := func(f *fixture, username string, groups []string) { + f.userMock.On("GetUser", mock.Anything).Return(username) + f.userMock.On("GetGroups", mock.Anything).Return(groups) + } + withExtensionConfig := func(configYaml string, f *fixture) { secrets := make(map[string]string) secrets["extension.auth.header"] = "Bearer some-bearer-token" @@ -403,6 +411,7 @@ func TestCallExtension(t *testing.T) { })) defer backendSrv.Close() withRbac(f, true, true) + withUser(f, "some-user", []string{"group1", "group2"}) withExtensionConfig(getExtensionConfig(backendEndpoint, backendSrv.URL), f) ts := startTestServer(t, f) defer ts.Close() @@ -437,6 +446,8 @@ func TestCallExtension(t *testing.T) { assert.Equal(t, backendResponse, actual) assert.Equal(t, clusterURL, resp.Header.Get(extension.HeaderArgoCDTargetClusterURL)) assert.Equal(t, "Bearer some-bearer-token", resp.Header.Get("Authorization")) + assert.Equal(t, "some-user", resp.Header.Get(extension.HeaderArgoCDUsername)) + assert.Equal(t, "group1,group2", resp.Header.Get(extension.HeaderArgoCDGroups)) // waitgroup is necessary to make sure assertions aren't executed before // the goroutine initiated by extension.CallExtension concludes which would @@ -452,6 +463,7 @@ func TestCallExtension(t *testing.T) { withExtensionConfig(getExtensionConfigString(), f) withRbac(f, true, true) withMetrics(f) + withUser(f, "some-user", []string{"group1", "group2"}) cluster1Name := "cluster1" f.appGetterMock.On("Get", "namespace", "app-name").Return(getApp(cluster1Name, "", defaultProjectName), nil) withProject(getProjectWithDestinations("project-name", []string{cluster1Name}, []string{"some-url"}), f) @@ -492,6 +504,7 @@ func TestCallExtension(t *testing.T) { withExtensionConfig(getExtensionConfigWith2Backends(extName, beSrv1.URL, cluster1Name, beSrv2.URL, cluster2URL), f) withProject(getProjectWithDestinations("project-name", []string{cluster1Name}, []string{cluster2URL}), f) withMetrics(f) + withUser(f, "some-user", []string{"group1", "group2"}) ts := startTestServer(t, f) defer ts.Close() @@ -538,6 +551,7 @@ func TestCallExtension(t *testing.T) { withRbac(f, allowApp, allowExtension) withExtensionConfig(getExtensionConfig(extName, "http://fake"), f) withMetrics(f) + withUser(f, "some-user", []string{"group1", "group2"}) ts := startTestServer(t, f) defer ts.Close() r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/%s/", ts.URL, extName)) @@ -561,6 +575,7 @@ func TestCallExtension(t *testing.T) { withRbac(f, allowApp, allowExtension) withExtensionConfig(getExtensionConfig(extName, "http://fake"), f) withMetrics(f) + withUser(f, "some-user", []string{"group1", "group2"}) ts := startTestServer(t, f) defer ts.Close() r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/%s/", ts.URL, extName)) @@ -585,6 +600,7 @@ func TestCallExtension(t *testing.T) { withRbac(f, allowApp, allowExtension) withExtensionConfig(getExtensionConfig(extName, "http://fake"), f) withMetrics(f) + withUser(f, "some-user", []string{"group1", "group2"}) ts := startTestServer(t, f) defer ts.Close() r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/%s/", ts.URL, extName)) @@ -610,6 +626,7 @@ func TestCallExtension(t *testing.T) { withRbac(f, allowApp, allowExtension) withExtensionConfig(getExtensionConfig(extName, "http://fake"), f) withMetrics(f) + withUser(f, "some-user", []string{"group1", "group2"}) ts := startTestServer(t, f) defer ts.Close() r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/%s/", ts.URL, extName)) @@ -635,6 +652,7 @@ func TestCallExtension(t *testing.T) { withRbac(f, allowApp, allowExtension) withExtensionConfig(getExtensionConfig(extName, "http://fake"), f) withMetrics(f) + withUser(f, "some-user", []string{"group1", "group2"}) ts := startTestServer(t, f) defer ts.Close() r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/%s/", ts.URL, extName)) @@ -666,6 +684,7 @@ func TestCallExtension(t *testing.T) { withExtensionConfig(getExtensionConfigWith2Backends(extName, "url1", "clusterName", "url2", "clusterURL"), f) withProject(getProjectWithDestinations("project-name", nil, []string{"srv1", destinationServer}), f) withMetrics(f) + withUser(f, "some-user", []string{"group1", "group2"}) ts := startTestServer(t, f) defer ts.Close() @@ -699,6 +718,7 @@ func TestCallExtension(t *testing.T) { withRbac(f, allowApp, allowExtension) withExtensionConfig(getExtensionConfig(extName, "http://fake"), f) withMetrics(f) + withUser(f, "some-user", []string{"group1", "group2"}) ts := startTestServer(t, f) defer ts.Close() r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/", ts.URL)) diff --git a/server/extension/mocks/ApplicationGetter.go b/server/extension/mocks/ApplicationGetter.go index bad203f47ebfe..1b742bdf320ae 100644 --- a/server/extension/mocks/ApplicationGetter.go +++ b/server/extension/mocks/ApplicationGetter.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.15.0. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks @@ -16,7 +16,15 @@ type ApplicationGetter struct { 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 { @@ -25,7 +33,6 @@ func (_m *ApplicationGetter) Get(ns string, name string) (*v1alpha1.Application, } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(ns, name) } else { @@ -35,13 +42,12 @@ func (_m *ApplicationGetter) Get(ns string, name string) (*v1alpha1.Application, return r0, r1 } -type mockConstructorTestingTNewApplicationGetter interface { +// 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 { mock.TestingT Cleanup(func()) -} - -// 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. -func NewApplicationGetter(t mockConstructorTestingTNewApplicationGetter) *ApplicationGetter { +}) *ApplicationGetter { mock := &ApplicationGetter{} mock.Mock.Test(t) diff --git a/server/extension/mocks/ExtensionMetricsRegistry.go b/server/extension/mocks/ExtensionMetricsRegistry.go index 78e583929f74d..be1d5285dd4de 100644 --- a/server/extension/mocks/ExtensionMetricsRegistry.go +++ b/server/extension/mocks/ExtensionMetricsRegistry.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.38.0. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks diff --git a/server/extension/mocks/ProjectGetter.go b/server/extension/mocks/ProjectGetter.go index d70b0c70ccfc6..f3e156aa30182 100644 --- a/server/extension/mocks/ProjectGetter.go +++ b/server/extension/mocks/ProjectGetter.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.15.0. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks @@ -16,7 +16,15 @@ type ProjectGetter struct { 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 { @@ -25,7 +33,6 @@ func (_m *ProjectGetter) Get(name string) (*v1alpha1.AppProject, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -39,7 +46,15 @@ func (_m *ProjectGetter) Get(name string) (*v1alpha1.AppProject, error) { 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 { @@ -48,7 +63,6 @@ func (_m *ProjectGetter) GetClusters(project string) ([]*v1alpha1.Cluster, error } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(project) } else { @@ -58,13 +72,12 @@ func (_m *ProjectGetter) GetClusters(project string) ([]*v1alpha1.Cluster, error return r0, r1 } -type mockConstructorTestingTNewProjectGetter interface { +// 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 { mock.TestingT Cleanup(func()) -} - -// 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. -func NewProjectGetter(t mockConstructorTestingTNewProjectGetter) *ProjectGetter { +}) *ProjectGetter { mock := &ProjectGetter{} mock.Mock.Test(t) diff --git a/server/extension/mocks/RbacEnforcer.go b/server/extension/mocks/RbacEnforcer.go index 01fb0c7421c69..d247ccb72f649 100644 --- a/server/extension/mocks/RbacEnforcer.go +++ b/server/extension/mocks/RbacEnforcer.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.15.0. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks @@ -15,6 +15,10 @@ func (_m *RbacEnforcer) EnforceErr(rvals ...interface{}) error { _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...) @@ -25,13 +29,12 @@ func (_m *RbacEnforcer) EnforceErr(rvals ...interface{}) error { return r0 } -type mockConstructorTestingTNewRbacEnforcer interface { +// 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. +func NewRbacEnforcer(t interface { mock.TestingT Cleanup(func()) -} - -// 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. -func NewRbacEnforcer(t mockConstructorTestingTNewRbacEnforcer) *RbacEnforcer { +}) *RbacEnforcer { mock := &RbacEnforcer{} mock.Mock.Test(t) diff --git a/server/extension/mocks/SettingsGetter.go b/server/extension/mocks/SettingsGetter.go index 303de9c5eeebf..4880ac861b75d 100644 --- a/server/extension/mocks/SettingsGetter.go +++ b/server/extension/mocks/SettingsGetter.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.15.0. DO NOT EDIT. +// Code generated by mockery v2.43.2. DO NOT EDIT. package mocks @@ -16,7 +16,15 @@ type SettingsGetter struct { 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 { @@ -25,7 +33,6 @@ func (_m *SettingsGetter) Get() (*settings.ArgoCDSettings, error) { } } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -35,13 +42,12 @@ func (_m *SettingsGetter) Get() (*settings.ArgoCDSettings, error) { return r0, r1 } -type mockConstructorTestingTNewSettingsGetter interface { +// 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 { mock.TestingT Cleanup(func()) -} - -// 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. -func NewSettingsGetter(t mockConstructorTestingTNewSettingsGetter) *SettingsGetter { +}) *SettingsGetter { mock := &SettingsGetter{} mock.Mock.Test(t) diff --git a/server/extension/mocks/UserGetter.go b/server/extension/mocks/UserGetter.go new file mode 100644 index 0000000000000..efd7e9ec412be --- /dev/null +++ b/server/extension/mocks/UserGetter.go @@ -0,0 +1,66 @@ +// Code generated by mockery v2.43.2. DO NOT EDIT. + +package mocks + +import ( + 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 { + mock.TestingT + Cleanup(func()) +}) *UserGetter { + mock := &UserGetter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/server/logout/logout.go b/server/logout/logout.go index e49f815931596..6129e2f9a85be 100644 --- a/server/logout/logout.go +++ b/server/logout/logout.go @@ -65,7 +65,10 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - argoURL := argoCDSettings.URL + argoURL, err := argoCDSettings.ArgoURLForRequest(r) + if err != nil { + log.Warnf("unable to find ArgoCD URL from config: %v", err) + } if argoURL == "" { // 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 diff --git a/server/logout/logout_test.go b/server/logout/logout_test.go index 78a735c528beb..3d2bab2d3662d 100644 --- a/server/logout/logout_test.go +++ b/server/logout/logout_test.go @@ -36,6 +36,7 @@ var ( oidcToken = "eyJraWQiOiJYQi1MM3ZFdHhYWXJLcmRSQnVEV0NwdnZsSnk3SEJVb2d5N253M1U1Z1ZZIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIwMHVqNnM1NDVyNU5peVNLcjVkNSIsIm5hbWUiOiJqZCByIiwiZW1haWwiOiJqYWlkZWVwMTdydWx6QGdtYWlsLmNvbSIsInZlciI6MSwiaXNzIjoiaHR0cHM6Ly9kZXYtNTY5NTA5OC5va3RhLmNvbSIsImF1ZCI6IjBvYWowM2FmSEtqN3laWXJwNWQ1IiwiaWF0IjoxNjA1NTcyMzU5LCJleHAiOjE2MDU1NzU5NTksImp0aSI6IklELl9ORDJxVG5iREFtc3hIZUt2U2ZHeVBqTXRicXFEQXdkdlRQTDZCTnpfR3ciLCJhbXIiOlsicHdkIl0sImlkcCI6IjAwb2lnaGZmdkpRTDYzWjhoNWQ1IiwicHJlZmVycmVkX3VzZXJuYW1lIjoiamFpZGVlcDE3cnVsekBnbWFpbC5jb20iLCJhdXRoX3RpbWUiOjE2MDU1NzIzNTcsImF0X2hhc2giOiJqZVEwRml2ak9nNGI2TUpXRDIxOWxnIn0.GHkqwXgW-lrAhJdypW7SVjW0YdNLFQiRL8iwgT6DHJxP9Nb0OtkH2NKcBYAA5N6bTPLRQUHgYwWcgm5zSXmvqa7ciIgPF3tiQI8UmJA9VFRRDR-x9ExX15nskCbXfiQ67MriLslUrQUyzSCfUrSjXKwnDxbKGQncrtmRsh5asfCzJFb9excn311W9HKbT3KA0Ot7eOMnVS6V7SGfXxnKs6szcXIEMa_FhB4zDAVLr-dnxvSG_uuWcHrAkLTUVhHbdQQXF7hXIEfyr5lkMJN-drjdz-bn40GaYulEmUvO1bjcL9toCVQ3Ismypyr0b8phj4w3uRsLDZQxTxK7jAXlyQ" nonOidcToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2MDU1NzQyMTIsImlzcyI6ImFyZ29jZCIsIm5iZiI6MTYwNTU3NDIxMiwic3ViIjoiYWRtaW4ifQ.zDJ4piwWnwsHON-oPusHMXWINlnrRDTQykYogT7afeE" expectedNonOIDCLogoutURL = "http://localhost:4000" + expectedNonOIDCLogoutURLOnSecondHost = "http://argocd.my-corp.tld" expectedOIDCLogoutURL = "https://dev-5695098.okta.com/oauth2/v1/logout?id_token_hint=" + oidcToken + "&post_logout_redirect_uri=" + baseURL expectedOIDCLogoutURLWithRootPath = "https://dev-5695098.okta.com/oauth2/v1/logout?id_token_hint=" + oidcToken + "&post_logout_redirect_uri=" + baseURL + "/" + rootPath ) @@ -181,6 +182,34 @@ func TestHandlerConstructLogoutURL(t *testing.T) { }, }, ) + kubeClientWithoutOIDCAndMultipleURLs := fake.NewSimpleClientset( + &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: common.ArgoCDConfigMapName, + Namespace: "default", + Labels: map[string]string{ + "app.kubernetes.io/part-of": "argocd", + }, + }, + Data: map[string]string{ + "url": "http://localhost:4000", + "additionalUrls": "- http://argocd.my-corp.tld", + }, + }, + &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, + }, + }, + ) kubeClientWithoutOIDCConfig := fake.NewSimpleClientset( &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ @@ -212,6 +241,7 @@ func TestHandlerConstructLogoutURL(t *testing.T) { 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)) @@ -237,6 +267,13 @@ func TestHandlerConstructLogoutURL(t *testing.T) { } return &jwt.RegisteredClaims{Issuer: "okta"}, "", nil } + nonoidcHandlerWithMultipleURLs := NewHandler(appclientset.NewSimpleClientset(), settingsManagerWithoutOIDCAndMultipleURLs, sessionManager, "", baseHRef, "default") + nonoidcHandlerWithMultipleURLs.verifyToken = func(tokenString string) (jwt.Claims, string, error) { + if !validJWTPattern.MatchString(tokenString) { + return nil, "", errors.New("invalid jwt") + } + return &jwt.RegisteredClaims{Issuer: "okta"}, "", nil + } oidcHandlerWithoutBaseURL := NewHandler(appclientset.NewSimpleClientset(), settingsManagerWithOIDCConfigButNoURL, sessionManager, "argocd", baseHRef, "default") oidcHandlerWithoutBaseURL.verifyToken = func(tokenString string) (jwt.Claims, string, error) { @@ -258,7 +295,10 @@ func TestHandlerConstructLogoutURL(t *testing.T) { nonoidcRequest, err := http.NewRequest(http.MethodGet, "http://localhost:4000/api/logout", nil) require.NoError(t, err) nonoidcRequest.Header = nonOidcTokenHeader - require.NoError(t, err) + nonoidcRequestOnSecondHost, err := http.NewRequest(http.MethodGet, "http://argocd.my-corp.tld/api/logout", nil) + assert.NoError(t, err) + nonoidcRequestOnSecondHost.Header = nonOidcTokenHeader + assert.NoError(t, err) requestWithInvalidToken, err := http.NewRequest(http.MethodGet, "http://localhost:4000/api/logout", nil) require.NoError(t, err) requestWithInvalidToken.Header = invalidHeader @@ -322,14 +362,30 @@ func TestHandlerConstructLogoutURL(t *testing.T) { expectedLogoutURL: expectedNonOIDCLogoutURL, wantErr: false, }, + { + name: "Case:non-OIDC Logout request on the first supported URL", + handler: nonoidcHandlerWithMultipleURLs, + request: nonoidcRequest, + responseRecorder: httptest.NewRecorder(), + expectedLogoutURL: expectedNonOIDCLogoutURL, + wantErr: false, + }, + { + name: "Case:non-OIDC Logout request on the second supported URL", + handler: nonoidcHandlerWithMultipleURLs, + request: nonoidcRequestOnSecondHost, + responseRecorder: httptest.NewRecorder(), + expectedLogoutURL: expectedNonOIDCLogoutURLOnSecondHost, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.handler.ServeHTTP(tt.responseRecorder, tt.request) if status := tt.responseRecorder.Code; status != http.StatusSeeOther { if !tt.wantErr { - t.Errorf(tt.responseRecorder.Body.String()) - t.Errorf("handler returned wrong status code: " + fmt.Sprintf("%d", tt.responseRecorder.Code)) + t.Error(tt.responseRecorder.Body.String()) + t.Error("handler returned wrong status code: " + fmt.Sprintf("%d", tt.responseRecorder.Code)) } } else { if tt.wantErr { diff --git a/server/metrics/metrics.go b/server/metrics/metrics.go index 4afac9da26c02..3056a4e3e9332 100644 --- a/server/metrics/metrics.go +++ b/server/metrics/metrics.go @@ -9,6 +9,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/util/profile" ) @@ -18,6 +19,7 @@ type MetricsServer struct { redisRequestHistogram *prometheus.HistogramVec extensionRequestCounter *prometheus.CounterVec extensionRequestDuration *prometheus.HistogramVec + argoVersion *prometheus.GaugeVec } var ( @@ -51,6 +53,13 @@ var ( }, []string{"extension"}, ) + argoVersion = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "argocd_info", + Help: "ArgoCD version information", + }, + []string{"version"}, + ) ) // NewMetricsServer returns a new prometheus server which collects api server metrics @@ -61,12 +70,15 @@ func NewMetricsServer(host string, port int) *MetricsServer { registry, prometheus.DefaultGatherer, }, promhttp.HandlerOpts{})) + argoVersion.WithLabelValues(common.GetVersion().Version).Set(1) + profile.RegisterProfiler(mux) registry.MustRegister(redisRequestCounter) registry.MustRegister(redisRequestHistogram) registry.MustRegister(extensionRequestCounter) registry.MustRegister(extensionRequestDuration) + registry.MustRegister(argoVersion) return &MetricsServer{ Server: &http.Server{ @@ -77,6 +89,7 @@ func NewMetricsServer(host string, port int) *MetricsServer { redisRequestHistogram: redisRequestHistogram, extensionRequestCounter: extensionRequestCounter, extensionRequestDuration: extensionRequestDuration, + argoVersion: argoVersion, } } diff --git a/server/project/project.go b/server/project/project.go index 74e7cf7bf0008..02d393564ddf0 100644 --- a/server/project/project.go +++ b/server/project/project.go @@ -58,9 +58,9 @@ type Server struct { // NewServer returns a new instance of the Project service func NewServer(ns string, kubeclientset kubernetes.Interface, appclientset appclientset.Interface, enf *rbac.Enforcer, projectLock sync.KeyLock, sessionMgr *session.SessionManager, policyEnf *rbacpolicy.RBACPolicyEnforcer, - projInformer cache.SharedIndexInformer, settingsMgr *settings.SettingsManager, db db.ArgoDB, + projInformer cache.SharedIndexInformer, settingsMgr *settings.SettingsManager, db db.ArgoDB, enableK8sEvent []string, ) *Server { - auditLogger := argo.NewAuditLogger(ns, kubeclientset, "argocd-server") + auditLogger := argo.NewAuditLogger(ns, kubeclientset, "argocd-server", enableK8sEvent) return &Server{ enf: enf, policyEnf: policyEnf, appclientset: appclientset, kubeclientset: kubeclientset, ns: ns, projectLock: projectLock, auditLogger: auditLogger, sessionMgr: sessionMgr, projInformer: projInformer, settingsMgr: settingsMgr, db: db, @@ -114,7 +114,7 @@ func (s *Server) createToken(ctx context.Context, q *project.ProjectTokenCreateR } id := q.Id if err := prj.ValidateJWTTokenID(q.Role, q.Id); err != nil { - return nil, status.Errorf(codes.InvalidArgument, err.Error()) + return nil, status.Error(codes.InvalidArgument, err.Error()) } if id == "" { uniqueId, _ := uuid.NewRandom() @@ -273,7 +273,7 @@ func (s *Server) Create(ctx context.Context, q *project.ProjectCreateRequest) (* 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.Errorf(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("project", existing.Spec, q.GetProject().Spec)) + return nil, status.Error(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("project", existing.Spec, q.GetProject().Spec)) } return existing, nil } diff --git a/server/project/project_test.go b/server/project/project_test.go index a03f472696f5a..41b8af9241e39 100644 --- a/server/project/project_test.go +++ b/server/project/project_test.go @@ -6,6 +6,7 @@ import ( "strings" "testing" + "github.com/argoproj/argo-cd/v2/util/argo" "github.com/argoproj/argo-cd/v2/util/db" "github.com/argoproj/pkg/sync" @@ -37,6 +38,8 @@ import ( const testNamespace = "default" +var testEnableEventList []string = argo.DefaultEnableEventList() + func TestProjectServer(t *testing.T) { kubeclientset := fake.NewSimpleClientset(&corev1.ConfigMap{ ObjectMeta: v1.ObjectMeta{ @@ -91,7 +94,7 @@ func TestProjectServer(t *testing.T) { role1 := v1alpha1.ProjectRole{Name: roleName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: 1}}} projectWithRole.Spec.Roles = append(projectWithRole.Spec.Roles, role1) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB, testEnableEventList) err := projectServer.NormalizeProjs() require.NoError(t, err) @@ -105,7 +108,7 @@ func TestProjectServer(t *testing.T) { enforcer.SetDefaultRole("role:projects") _ = enforcer.SetBuiltinPolicy("p, role:projects, projects, update, *, allow") argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.Destinations = nil @@ -119,7 +122,7 @@ func TestProjectServer(t *testing.T) { enforcer.SetDefaultRole("role:projects") _ = enforcer.SetBuiltinPolicy("p, role:projects, projects, update, *, allow") argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.SourceRepos = nil @@ -133,7 +136,7 @@ func TestProjectServer(t *testing.T) { enforcer.SetDefaultRole("role:projects") _ = enforcer.SetBuiltinPolicy("p, role:projects, projects, update, *, allow") argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.ClusterResourceWhitelist = []metav1.GroupKind{{}} @@ -147,7 +150,7 @@ func TestProjectServer(t *testing.T) { enforcer.SetDefaultRole("role:projects") _ = enforcer.SetBuiltinPolicy("p, role:projects, projects, update, *, allow") argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.NamespaceResourceBlacklist = []metav1.GroupKind{{}} @@ -166,7 +169,7 @@ func TestProjectServer(t *testing.T) { } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.Destinations = updatedProj.Spec.Destinations[1:] @@ -183,7 +186,7 @@ func TestProjectServer(t *testing.T) { } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.Destinations = updatedProj.Spec.Destinations[1:] @@ -202,7 +205,7 @@ func TestProjectServer(t *testing.T) { } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.SourceRepos = []string{} @@ -219,7 +222,7 @@ func TestProjectServer(t *testing.T) { } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := existingProj.DeepCopy() updatedProj.Spec.SourceRepos = []string{} @@ -239,7 +242,7 @@ func TestProjectServer(t *testing.T) { Spec: v1alpha1.ApplicationSpec{Project: "test", Source: &v1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argo-cd.git"}}, } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := proj.DeepCopy() updatedProj.Spec.SourceRepos = []string{"https://github.com/argoproj/*"} @@ -266,7 +269,7 @@ func TestProjectServer(t *testing.T) { argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) updatedProj := proj.DeepCopy() updatedProj.Spec.Destinations = []v1alpha1.ApplicationDestination{ @@ -281,7 +284,7 @@ func TestProjectServer(t *testing.T) { t.Run("TestDeleteProjectSuccessful", func(t *testing.T) { argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.Delete(context.Background(), &project.ProjectQuery{Name: "test"}) @@ -294,7 +297,7 @@ func TestProjectServer(t *testing.T) { Spec: v1alpha1.AppProjectSpec{}, } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&defaultProj), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&defaultProj), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.Delete(context.Background(), &project.ProjectQuery{Name: defaultProj.Name}) statusCode, _ := status.FromError(err) @@ -308,7 +311,7 @@ func TestProjectServer(t *testing.T) { } argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(&existingProj, &existingApp), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.Delete(context.Background(), &project.ProjectQuery{Name: "test"}) @@ -335,7 +338,7 @@ func TestProjectServer(t *testing.T) { projectWithRole.Spec.Roles = []v1alpha1.ProjectRole{{Name: tokenName}} argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.CreateToken(ctx, &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1}) assert.EqualError(t, err, "rpc error: code = PermissionDenied desc = permission denied: projects, update, test") }) @@ -345,7 +348,7 @@ func TestProjectServer(t *testing.T) { projectWithRole := existingProj.DeepCopy() projectWithRole.Spec.Roles = []v1alpha1.ProjectRole{{Name: tokenName, Groups: []string{"my-group"}}} argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithRole), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.CreateToken(ctx, &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1}) require.NoError(t, err) }) @@ -359,7 +362,7 @@ func TestProjectServer(t *testing.T) { sessionMgr := session.NewSessionManager(settingsMgr, test.NewFakeProjListerFromInterface(clientset.ArgoprojV1alpha1().AppProjects("default")), "", nil, session.NewUserStateStorage(nil)) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) tokenResponse, err := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 100}) require.NoError(t, err) claims, _, err := sessionMgr.Parse(tokenResponse.Token) @@ -380,7 +383,7 @@ func TestProjectServer(t *testing.T) { sessionMgr := session.NewSessionManager(settingsMgr, test.NewFakeProjListerFromInterface(clientset.ArgoprojV1alpha1().AppProjects("default")), "", nil, session.NewUserStateStorage(nil)) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) tokenResponse, err := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1, Id: id}) require.NoError(t, err) claims, _, err := sessionMgr.Parse(tokenResponse.Token) @@ -401,7 +404,7 @@ func TestProjectServer(t *testing.T) { sessionMgr := session.NewSessionManager(settingsMgr, test.NewFakeProjListerFromInterface(clientset.ArgoprojV1alpha1().AppProjects("default")), "", nil, session.NewUserStateStorage(nil)) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), clientset, enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) tokenResponse, err := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projectWithRole.Name, Role: tokenName, ExpiresIn: 1, Id: id}) require.NoError(t, err) @@ -430,7 +433,7 @@ func TestProjectServer(t *testing.T) { token := v1alpha1.ProjectRole{Name: tokenName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: issuedAt}, {IssuedAt: secondIssuedAt}}} projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.DeleteToken(ctx, &project.ProjectTokenDeleteRequest{Project: projWithToken.Name, Role: tokenName, Iat: issuedAt}) assert.EqualError(t, err, "rpc error: code = PermissionDenied desc = permission denied: projects, update, test") }) @@ -443,7 +446,7 @@ func TestProjectServer(t *testing.T) { token := v1alpha1.ProjectRole{Name: tokenName, Groups: []string{"my-group"}, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: issuedAt}, {IssuedAt: secondIssuedAt}}} projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.DeleteToken(ctx, &project.ProjectTokenDeleteRequest{Project: projWithToken.Name, Role: tokenName, Iat: issuedAt}) require.NoError(t, err) }) @@ -459,7 +462,7 @@ p, role:admin, projects, update, *, allow`) token := v1alpha1.ProjectRole{Name: tokenName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: issuedAt}, {IssuedAt: secondIssuedAt}}} projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.DeleteToken(ctx, &project.ProjectTokenDeleteRequest{Project: projWithToken.Name, Role: tokenName, Iat: issuedAt}) require.NoError(t, err) projWithoutToken, err := projectServer.Get(context.Background(), &project.ProjectQuery{Name: projWithToken.Name}) @@ -483,7 +486,7 @@ p, role:admin, projects, update, *, allow`) token := v1alpha1.ProjectRole{Name: tokenName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: issuedAt, ID: id}, {IssuedAt: secondIssuedAt, ID: secondId}}} projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.DeleteToken(ctx, &project.ProjectTokenDeleteRequest{Project: projWithToken.Name, Role: tokenName, Iat: secondIssuedAt, Id: id}) require.NoError(t, err) projWithoutToken, err := projectServer.Get(context.Background(), &project.ProjectQuery{Name: projWithToken.Name}) @@ -502,7 +505,7 @@ p, role:admin, projects, update, *, allow`) token := v1alpha1.ProjectRole{Name: tokenName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: 1}}} projWithToken.Spec.Roles = append(projWithToken.Spec.Roles, token) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithToken), enforcer, sync.NewKeyLock(), sessionMgr, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.CreateToken(context.Background(), &project.ProjectTokenCreateRequest{Project: projWithToken.Name, Role: tokenName}) require.NoError(t, err) projWithTwoTokens, err := projectServer.Get(context.Background(), &project.ProjectQuery{Name: projWithToken.Name}) @@ -516,7 +519,7 @@ p, role:admin, projects, update, *, allow`) wildSourceRepo := "*" proj.Spec.SourceRepos = append(proj.Spec.SourceRepos, wildSourceRepo) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj), enforcer, sync.NewKeyLock(), nil, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(proj), enforcer, sync.NewKeyLock(), nil, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: proj} updatedProj, err := projectServer.Update(context.Background(), request) require.NoError(t, err) @@ -535,7 +538,7 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, policy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, policyEnf, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, policyEnf, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: projWithRole} _, err := projectServer.Update(context.Background(), request) require.NoError(t, err) @@ -557,7 +560,7 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, policy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: projWithRole} _, err := projectServer.Update(context.Background(), request) expectedErr := fmt.Sprintf("rpc error: code = AlreadyExists desc = policy '%s' already exists for role '%s'", policy, roleName) @@ -577,7 +580,7 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, policy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: projWithRole} _, err := projectServer.Update(context.Background(), request) assert.Contains(t, err.Error(), "object must be of form 'test/*', 'test[/]/' or 'test/'") @@ -596,7 +599,7 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, invalidPolicy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: projWithRole} _, err := projectServer.Update(context.Background(), request) assert.Contains(t, err.Error(), "policy subject must be: 'proj:test:testRole'") @@ -615,7 +618,7 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, invalidPolicy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: projWithRole} _, err := projectServer.Update(context.Background(), request) assert.Contains(t, err.Error(), "policy subject must be: 'proj:test:testRole'") @@ -633,7 +636,7 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, invalidPolicy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: projWithRole} _, err := projectServer.Update(context.Background(), request) assert.Contains(t, err.Error(), "effect must be: 'allow' or 'deny'") @@ -652,7 +655,7 @@ p, role:admin, projects, update, *, allow`) role.Policies = append(role.Policies, invalidPolicy) projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, sync.NewKeyLock(), nil, nil, projInformer, settingsMgr, argoDB, testEnableEventList) request := &project.ProjectUpdateRequest{Project: projWithRole} updateProj, err := projectServer.Update(context.Background(), request) require.NoError(t, err) @@ -667,7 +670,7 @@ p, role:admin, projects, update, *, allow`) win := &v1alpha1.SyncWindow{Kind: "allow", Schedule: "* * * * *", Duration: "1h"} projectWithSyncWindows.Spec.SyncWindows = append(projectWithSyncWindows.Spec.SyncWindows, win) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB, testEnableEventList) res, err := projectServer.GetSyncWindowsState(ctx, &project.SyncWindowsQuery{Name: projectWithSyncWindows.Name}) require.NoError(t, err) assert.Len(t, res.Windows, 1) @@ -680,7 +683,7 @@ p, role:admin, projects, update, *, allow`) win := &v1alpha1.SyncWindow{Kind: "allow", Schedule: "* * * * *", Duration: "1h"} projectWithSyncWindows.Spec.SyncWindows = append(projectWithSyncWindows.Spec.SyncWindows, win) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB, testEnableEventList) res, err := projectServer.GetSyncWindowsState(ctx, &project.SyncWindowsQuery{Name: "incorrect"}) assert.Contains(t, err.Error(), "not found") assert.Nil(t, res) @@ -698,7 +701,7 @@ p, role:admin, projects, update, *, allow`) win := &v1alpha1.SyncWindow{Kind: "allow", Schedule: "* * * * *", Duration: "1h"} projectWithSyncWindows.Spec.SyncWindows = append(projectWithSyncWindows.Spec.SyncWindows, win) argoDB := db.NewDB("default", settingsMgr, kubeclientset) - projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB) + projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projectWithSyncWindows), enforcer, sync.NewKeyLock(), sessionMgr, nil, projInformer, settingsMgr, argoDB, testEnableEventList) _, err := projectServer.GetSyncWindowsState(ctx, &project.SyncWindowsQuery{Name: projectWithSyncWindows.Name}) assert.EqualError(t, err, "rpc error: code = PermissionDenied desc = permission denied: projects, get, test") }) diff --git a/server/rbacpolicy/rbacpolicy.go b/server/rbacpolicy/rbacpolicy.go index 940f5bfe70844..0be623ae7819f 100644 --- a/server/rbacpolicy/rbacpolicy.go +++ b/server/rbacpolicy/rbacpolicy.go @@ -141,7 +141,11 @@ func (p *RBACPolicyEnforcer) EnforceClaims(claims jwt.Claims, rvals ...interface groups := jwtutil.GetScopeValues(mapClaims, scopes) // Get groups to reduce the amount to checking groups - groupingPolicies := enforcer.GetGroupingPolicy() + groupingPolicies, err := enforcer.GetGroupingPolicy() + if err != nil { + log.WithError(err).Error("failed to get grouping policy") + return false + } for gidx := range groups { for gpidx := range groupingPolicies { // Prefilter user groups by groups defined in the model diff --git a/server/repocreds/repocreds.go b/server/repocreds/repocreds.go index d4706f6bb9970..5c0c819598fb3 100644 --- a/server/repocreds/repocreds.go +++ b/server/repocreds/repocreds.go @@ -93,7 +93,7 @@ func (s *Server) CreateRepositoryCredentials(ctx context.Context, q *repocredspk } else if q.Upsert { return s.UpdateRepositoryCredentials(ctx, &repocredspkg.RepoCredsUpdateRequest{Creds: r}) } else { - return nil, status.Errorf(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("repository credentials", existing, r)) + return nil, status.Error(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("repository credentials", existing, r)) } } return &appsv1.RepoCreds{URL: r.URL}, err diff --git a/server/repository/repository.go b/server/repository/repository.go index 5507b91bffb7f..2e25f87ce19d1 100644 --- a/server/repository/repository.go +++ b/server/repository/repository.go @@ -196,6 +196,7 @@ func (s *Server) ListRepositories(ctx context.Context, q *repositorypkg.RepoQuer EnableLFS: repo.EnableLFS, EnableOCI: repo.EnableOCI, Proxy: repo.Proxy, + NoProxy: repo.NoProxy, Project: repo.Project, ForceHttpBasicAuth: repo.ForceHttpBasicAuth, InheritedCreds: repo.InheritedCreds, @@ -350,6 +351,15 @@ func (s *Server) GetAppDetails(ctx context.Context, q *repositorypkg.RepoAppDeta return nil, err } + 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) + if err != nil { + return nil, fmt.Errorf("failed to get ref sources: %w", err) + } + } + return repoClient.GetAppDetails(ctx, &apiclient.RepoServerAppDetailsQuery{ Repo: repo, Source: q.Source, @@ -357,6 +367,7 @@ func (s *Server) GetAppDetails(ctx context.Context, q *repositorypkg.RepoAppDeta KustomizeOptions: kustomizeOptions, HelmOptions: helmOptions, AppName: q.AppName, + RefSources: refSources, }) } @@ -432,7 +443,7 @@ func (s *Server) CreateRepository(ctx context.Context, q *repositorypkg.RepoCrea r.Project = q.Repo.Project return s.UpdateRepository(ctx, &repositorypkg.RepoUpdateRequest{Repo: r}) } else { - return nil, status.Errorf(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("repository", existing, r)) + return nil, status.Error(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("repository", existing, r)) } } if err != nil { diff --git a/server/server.go b/server/server.go index 862ad4075c4f9..7ded3951a37c3 100644 --- a/server/server.go +++ b/server/server.go @@ -54,8 +54,10 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "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/v2/common" "github.com/argoproj/argo-cd/v2/pkg/apiclient" @@ -167,6 +169,7 @@ func init() { // ArgoCDServer is the API server for Argo CD type ArgoCDServer struct { ArgoCDServerOpts + ApplicationSetOpts ssoClientApp *oidc.ClientApp settings *settings_util.ArgoCDSettings @@ -198,31 +201,43 @@ type ArgoCDServer struct { } type ArgoCDServerOpts struct { - DisableAuth bool - ContentTypes []string - EnableGZip bool - Insecure bool - StaticAssetsDir string - ListenPort int - ListenHost string - MetricsPort int - MetricsHost string - Namespace string - DexServerAddr string - DexTLSConfig *dexutil.DexTLSConfig - BaseHRef string - RootPath string - KubeClientset kubernetes.Interface - AppClientset appclientset.Interface - RepoClientset repoapiclient.Clientset - Cache *servercache.Cache - RepoServerCache *repocache.Cache - RedisClient *redis.Client - TLSConfigCustomizer tlsutil.ConfigCustomizer - XFrameOptions string - ContentSecurityPolicy string - ApplicationNamespaces []string - EnableProxyExtension bool + DisableAuth bool + ContentTypes []string + EnableGZip bool + Insecure bool + StaticAssetsDir string + ListenPort int + ListenHost string + MetricsPort int + MetricsHost string + Namespace string + DexServerAddr string + DexTLSConfig *dexutil.DexTLSConfig + BaseHRef string + RootPath string + DynamicClientset dynamic.Interface + KubeControllerClientset client.Client + KubeClientset kubernetes.Interface + AppClientset appclientset.Interface + RepoClientset repoapiclient.Clientset + Cache *servercache.Cache + RepoServerCache *repocache.Cache + RedisClient *redis.Client + TLSConfigCustomizer tlsutil.ConfigCustomizer + XFrameOptions string + ContentSecurityPolicy string + ApplicationNamespaces []string + EnableProxyExtension bool + WebhookParallelism int + EnableK8sEvent []string +} + +type ApplicationSetOpts struct { + GitSubmoduleEnabled bool + EnableNewGitFileGlobbing bool + ScmRootCAPath string + AllowedScmProviders []string + EnableScmProviders bool } // HTTPMetricsRegistry exposes operations to update http metrics in the Argo CD @@ -259,7 +274,7 @@ func initializeDefaultProject(opts ArgoCDServerOpts) error { } // NewServer returns a new instance of the Argo CD API server -func NewServer(ctx context.Context, opts ArgoCDServerOpts) *ArgoCDServer { +func NewServer(ctx context.Context, opts ArgoCDServerOpts, appsetOpts ApplicationSetOpts) *ArgoCDServer { settingsMgr := settings_util.NewSettingsManager(ctx, opts.KubeClientset, opts.Namespace) settings, err := settingsMgr.InitializeSettings(opts.Insecure) errorsutil.CheckError(err) @@ -312,29 +327,31 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts) *ArgoCDServer { sg := extension.NewDefaultSettingsGetter(settingsMgr) ag := extension.NewDefaultApplicationGetter(appLister) pg := extension.NewDefaultProjectGetter(projLister, dbInstance) - em := extension.NewManager(logger, sg, ag, pg, enf) + ug := extension.NewDefaultUserGetter(policyEnf) + em := extension.NewManager(logger, sg, ag, pg, enf, ug) a := &ArgoCDServer{ - ArgoCDServerOpts: opts, - log: logger, - settings: settings, - sessionMgr: sessionMgr, - settingsMgr: settingsMgr, - enf: enf, - projInformer: projInformer, - projLister: projLister, - appInformer: appInformer, - appLister: appLister, - appsetInformer: appsetInformer, - appsetLister: appsetLister, - policyEnforcer: policyEnf, - userStateStorage: userStateStorage, - staticAssets: http.FS(staticFS), - db: dbInstance, - apiFactory: apiFactory, - secretInformer: secretInformer, - configMapInformer: configMapInformer, - extensionManager: em, + ArgoCDServerOpts: opts, + ApplicationSetOpts: appsetOpts, + log: logger, + settings: settings, + sessionMgr: sessionMgr, + settingsMgr: settingsMgr, + enf: enf, + projInformer: projInformer, + projLister: projLister, + appInformer: appInformer, + appLister: appLister, + appsetInformer: appsetInformer, + appsetLister: appsetLister, + policyEnforcer: policyEnf, + userStateStorage: userStateStorage, + staticAssets: http.FS(staticFS), + db: dbInstance, + apiFactory: apiFactory, + secretInformer: secretInformer, + configMapInformer: configMapInformer, + extensionManager: em, } err = a.logInClusterWarnings() @@ -474,6 +491,7 @@ func (a *ArgoCDServer) Listen() (*Listeners, error) { } else { dOpts = append(dOpts, grpc.WithTransportCredentials(insecure.NewCredentials())) } + // nolint:staticcheck conn, err := grpc.Dial(fmt.Sprintf("localhost:%d", a.ListenPort), dOpts...) if err != nil { io.Close(mainLn) @@ -632,6 +650,7 @@ func (a *ArgoCDServer) watchSettings() { a.settingsMgr.Subscribe(updateCh) 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) @@ -663,6 +682,10 @@ func (a *ArgoCDServer) watchSettings() { log.Infof("url modified. restarting") break } + if !reflect.DeepEqual(prevAdditionalURLs, a.settings.AdditionalURLs) { + log.Infof("additionalURLs modified. restarting") + break + } if prevGitHubSecret != a.settings.WebhookGitHubSecret { log.Infof("github secret modified. restarting") break @@ -717,7 +740,7 @@ func (a *ArgoCDServer) rbacPolicyLoader(ctx context.Context) { scopes = make([]string, 0) err := yaml.Unmarshal([]byte(scopesStr), &scopes) if err != nil { - return err + return fmt.Errorf("error unmarshalling scopes: %w", err) } } @@ -863,12 +886,17 @@ func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet { projectLock, a.settingsMgr, a.projInformer, - a.ApplicationNamespaces) + a.ApplicationNamespaces, + a.EnableK8sEvent, + ) applicationSetService := applicationset.NewServer( a.db, a.KubeClientset, + a.DynamicClientset, + a.KubeControllerClientset, a.enf, + a.RepoClientset, a.AppClientset, a.appsetInformer, a.appsetLister, @@ -876,9 +904,16 @@ func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet { a.settingsMgr, a.Namespace, projectLock, - a.ApplicationNamespaces) - - projectService := project.NewServer(a.Namespace, a.KubeClientset, a.AppClientset, a.enf, projectLock, a.sessionMgr, a.policyEnforcer, a.projInformer, a.settingsMgr, a.db) + a.ApplicationNamespaces, + a.GitSubmoduleEnabled, + a.EnableNewGitFileGlobbing, + a.ScmRootCAPath, + a.AllowedScmProviders, + a.EnableScmProviders, + a.EnableK8sEvent, + ) + + projectService := project.NewServer(a.Namespace, a.KubeClientset, a.AppClientset, a.enf, projectLock, a.sessionMgr, a.policyEnforcer, a.projInformer, a.settingsMgr, a.db, a.EnableK8sEvent) appsInAnyNamespaceEnabled := len(a.ArgoCDServerOpts.ApplicationNamespaces) > 0 settingsService := settings.NewServer(a.settingsMgr, a.RepoClientset, a, a.DisableAuth, appsInAnyNamespaceEnabled) accountService := account.NewServer(a.sessionMgr, a.settingsMgr, a.enf) @@ -921,7 +956,7 @@ func (a *ArgoCDServer) translateGrpcCookieHeader(ctx context.Context, w http.Res token := sessionResp.Token err := a.setTokenCookie(token, w) if err != nil { - return err + return fmt.Errorf("error setting token cookie from session response: %w", err) } } else if md, ok := runtime.ServerMetadataFromContext(ctx); ok { renewToken := md.HeaderMD[renewTokenKey] @@ -941,7 +976,7 @@ func (a *ArgoCDServer) setTokenCookie(token string, w http.ResponseWriter) error } cookies, err := httputil.MakeCookieMetadata(common.AuthCookieName, token, flags...) if err != nil { - return err + return fmt.Errorf("error creating cookie metadata: %w", err) } for _, cookie := range cookies { w.Header().Add("Set-Cookie", cookie) @@ -1012,7 +1047,9 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl } mux.Handle("/api/", handler) - terminal := application.NewHandler(a.appLister, a.Namespace, a.ApplicationNamespaces, a.db, a.enf, a.Cache, appResourceTreeFn, a.settings.ExecShells, a.sessionMgr). + terminalOpts := application.TerminalOptions{DisableAuth: a.ArgoCDServerOpts.DisableAuth, Enf: a.enf} + + 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) @@ -1049,7 +1086,7 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl // 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(a.Namespace, a.settingsMgr, a.KubeClientset) - acdWebhookHandler := webhook.NewHandler(a.Namespace, a.ArgoCDServerOpts.ApplicationNamespaces, a.AppClientset, a.settings, a.settingsMgr, a.RepoServerCache, a.Cache, argoDB) + 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) @@ -1513,7 +1550,7 @@ func bug21955WorkaroundInterceptor(ctx context.Context, req interface{}, _ *grpc return handler(ctx, req) } -// allowedNamespacesAsString returns a string containing comma-separated list +// allowedApplicationNamespacesAsString returns a string containing comma-separated list // of allowed application namespaces func (a *ArgoCDServer) allowedApplicationNamespacesAsString() string { ns := a.Namespace diff --git a/server/server_test.go b/server/server_test.go index 13bb3d6770753..7923db7f3e9d6 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -19,9 +19,13 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/grpc/metadata" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/fake" "sigs.k8s.io/yaml" + dynfake "k8s.io/client-go/dynamic/fake" + clientfake "sigs.k8s.io/controller-runtime/pkg/client/fake" + "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/pkg/apiclient" "github.com/argoproj/argo-cd/v2/pkg/apiclient/session" @@ -52,10 +56,12 @@ func fakeServer(t *testing.T) (*FakeArgoCDServer, func()) { kubeclientset := fake.NewSimpleClientset(cm, secret) appClientSet := apps.NewSimpleClientset() redis, closer := test.NewInMemoryRedis() - port, err := test.GetFreePort() mockRepoClient := &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}} tmpAssetsDir := t.TempDir() + dynamicClient := dynfake.NewSimpleDynamicClient(runtime.NewScheme()) + fakeClient := clientfake.NewClientBuilder().Build() + port, err := test.GetFreePort() if err != nil { panic(err) } @@ -78,11 +84,13 @@ func fakeServer(t *testing.T) (*FakeArgoCDServer, func()) { 1*time.Minute, 1*time.Minute, ), - RedisClient: redis, - RepoClientset: mockRepoClient, - StaticAssetsDir: tmpAssetsDir, + RedisClient: redis, + RepoClientset: mockRepoClient, + StaticAssetsDir: tmpAssetsDir, + DynamicClientset: dynamicClient, + KubeControllerClientset: fakeClient, } - srv := NewServer(context.Background(), argoCDOpts) + srv := NewServer(context.Background(), argoCDOpts, ApplicationSetOpts{}) fakeSrv := &FakeArgoCDServer{srv, tmpAssetsDir} return fakeSrv, closer } @@ -118,7 +126,7 @@ func TestEnforceProjectToken(t *testing.T) { mockRepoClient := &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}} t.Run("TestEnforceProjectTokenSuccessful", func(t *testing.T) { - s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}) + 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} @@ -127,21 +135,21 @@ func TestEnforceProjectToken(t *testing.T) { }) t.Run("TestEnforceProjectTokenWithDiffCreateAtFailure", func(t *testing.T) { - s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}) + 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(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}) + 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(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}) + 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} @@ -151,7 +159,7 @@ func TestEnforceProjectToken(t *testing.T) { t.Run("TestEnforceProjectTokenNotJWTTokenFailure", func(t *testing.T) { proj := existingProj.DeepCopy() proj.Spec.Roles[0].JWTTokens = nil - s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(proj), RepoClientset: mockRepoClient}) + 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)) }) @@ -164,7 +172,7 @@ func TestEnforceProjectToken(t *testing.T) { proj := existingProj.DeepCopy() proj.Spec.Roles[0] = role - s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(proj), RepoClientset: mockRepoClient}) + 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} @@ -175,7 +183,7 @@ func TestEnforceProjectToken(t *testing.T) { }) t.Run("TestEnforceProjectTokenWithIdSuccessful", func(t *testing.T) { - s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}) + 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} @@ -184,7 +192,7 @@ func TestEnforceProjectToken(t *testing.T) { }) t.Run("TestEnforceProjectTokenWithInvalidIdFailure", func(t *testing.T) { - s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}) + 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) @@ -268,7 +276,7 @@ func TestInitializingExistingDefaultProject(t *testing.T) { RepoClientset: mockRepoClient, } - argocd := NewServer(context.Background(), argoCDOpts) + argocd := NewServer(context.Background(), argoCDOpts, ApplicationSetOpts{}) assert.NotNil(t, argocd) proj, err := appClientSet.ArgoprojV1alpha1().AppProjects(test.FakeArgoCDNamespace).Get(context.Background(), v1alpha1.DefaultAppProjectName, metav1.GetOptions{}) @@ -291,7 +299,7 @@ func TestInitializingNotExistingDefaultProject(t *testing.T) { RepoClientset: mockRepoClient, } - argocd := NewServer(context.Background(), argoCDOpts) + argocd := NewServer(context.Background(), argoCDOpts, ApplicationSetOpts{}) assert.NotNil(t, argocd) proj, err := appClientSet.ArgoprojV1alpha1().AppProjects(test.FakeArgoCDNamespace).Get(context.Background(), v1alpha1.DefaultAppProjectName, metav1.GetOptions{}) @@ -333,7 +341,7 @@ func TestEnforceProjectGroups(t *testing.T) { } mockRepoClient := &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}} kubeclientset := fake.NewSimpleClientset(test.NewFakeConfigMap(), test.NewFakeSecret()) - s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}) + 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{ @@ -395,7 +403,7 @@ func TestRevokedToken(t *testing.T) { }, } - s := NewServer(context.Background(), ArgoCDServerOpts{Namespace: test.FakeArgoCDNamespace, KubeClientset: kubeclientset, AppClientset: apps.NewSimpleClientset(&existingProj), RepoClientset: mockRepoClient}) + 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} @@ -450,7 +458,7 @@ func TestAuthenticate(t *testing.T) { AppClientset: appClientSet, RepoClientset: mockRepoClient, } - argocd := NewServer(context.Background(), argoCDOpts) + argocd := NewServer(context.Background(), argoCDOpts, ApplicationSetOpts{}) ctx := context.Background() if testData.user != "" { token, err := argocd.sessionMgr.Create(testData.user, 0, "abc") @@ -587,7 +595,7 @@ connectors: if withFakeSSO && useDexForSSO { argoCDOpts.DexServerAddr = ts.URL } - argocd = NewServer(context.Background(), argoCDOpts) + 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) @@ -1071,7 +1079,7 @@ func TestTranslateGrpcCookieHeader(t *testing.T) { AppClientset: apps.NewSimpleClientset(), RepoClientset: &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}}, } - argocd := NewServer(context.Background(), argoCDOpts) + argocd := NewServer(context.Background(), argoCDOpts, ApplicationSetOpts{}) t.Run("TokenIsNotEmpty", func(t *testing.T) { recorder := httptest.NewRecorder() diff --git a/server/settings/settings.go b/server/settings/settings.go index 131ddc1924b27..a598b5284f743 100644 --- a/server/settings/settings.go +++ b/server/settings/settings.go @@ -112,6 +112,7 @@ func (s *Server) Get(ctx context.Context, q *settingspkg.SettingsQuery) (*settin TrackingMethod: trackingMethod, ExecEnabled: argoCDSettings.ExecEnabled, AppsInAnyNamespaceEnabled: s.appsInAnyNamespaceEnabled, + ImpersonationEnabled: argoCDSettings.ImpersonationEnabled, } if sessionmgr.LoggedIn(ctx) || s.disableAuth { diff --git a/server/settings/settings.proto b/server/settings/settings.proto index a6aa97120c8de..4b2396d5a22a4 100644 --- a/server/settings/settings.proto +++ b/server/settings/settings.proto @@ -42,6 +42,7 @@ message Settings { bool execEnabled = 22; string controllerNamespace = 23; bool appsInAnyNamespaceEnabled = 24; + bool impersonationEnabled = 25; } message GoogleAnalyticsConfig { diff --git a/sonar-project.properties b/sonar-project.properties index c4bc672dfe0c0..21dad92e68837 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -19,7 +19,7 @@ sonar.host.url=https://sonarcloud.io sonar.coverage.exclusions=**/*.pb.go,**/*.pb.gw.go,**/mocks/**,**/*.ts*,**/vendor/**,**/openapi_generated.go,**/*_test.go,**/*_generated*,test/**,pkg/client/**,pkg/apiclient/**,docs/** # Exclude following set of patterns from code analysis -sonar.go.exclusions=**/vendor/**,*/*.pb.go,**/*_test.go,**/*.pb.gw.go,**/mocks/**,**/openapi_generated.go,**/*_generated*.go,docs/** +sonar.go.exclusions=**/vendor/**,**/*.pb.go,**/*_test.go,**/*.pb.gw.go,**/mocks/**,**/openapi_generated.go,**/*_generated*.go,docs/** # Exclude following set of patterns from duplication detection sonar.cpd.exclusions=**/*.pb.go,**/*.g.cs,**/*.gw.go,**/mocks/*,docs/** diff --git a/test/container/Dockerfile b/test/container/Dockerfile index 71cbdaaad3f6f..ad22c720bbb81 100644 --- a/test/container/Dockerfile +++ b/test/container/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/redis:7.2.5@sha256:01afb31d6d633451d84475ff3eb95f8c48bf0ee59ec9c948b161adb4da882053 as redis +FROM docker.io/library/redis:7.4.0@sha256:eadf354977d428e347d93046bb1a5569d701e8deb68f090215534a99dbcb23b9 as redis # There are libraries we will want to copy from here in the final stage of the # build, but the COPY directive does not have a way to determine system @@ -6,13 +6,13 @@ FROM docker.io/library/redis:7.2.5@sha256:01afb31d6d633451d84475ff3eb95f8c48bf0e 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.3.0@sha256:5e4044ff6001d06e7748e35bfa4f80c73cf5f5a7360a1b782995e038a01b0585 as node +FROM docker.io/library/node:22.9.0@sha256:cbe2d5f94110cea9817dd8c5809d05df49b4bd1aac5203f3594d88665ad37988 as node -FROM docker.io/library/golang:1.22.4@sha256:a0679accac8685cc5389bd2298e045e570100940e6bdcca666a8ca7b32a1276c as golang +FROM docker.io/library/golang:1.23@sha256:2fe82a3f3e006b4f2a316c6a21f62b66e1330ae211d039bb8d1128e12ed57bf1 as golang -FROM docker.io/library/registry:2.8@sha256:4fac7a8257b1d7a86599043fcc181dfbdf9c8f57e337db763ac94b0e67c6cfb5 as registry +FROM docker.io/library/registry:2.8@sha256:ac0192b549007e22998eb74e8d8488dcfe70f1489520c3b144a6047ac5efbe90 as registry -FROM docker.io/bitnami/kubectl:1.30@sha256:e704ebf9f6974d506d2dbff33dea28b6e996887e60c4ab298c78e10a3d81e249 as kubectl +FROM docker.io/bitnami/kubectl:1.31@sha256:da4a9868e20d941636087cb8624a4bb441f5249d69e8f3d27e53c7d4d280a5f3 as kubectl FROM docker.io/library/ubuntu:24.04@sha256:3f85b7caad41a95462cf5b787d8a04604c8262cdcdf9a472b8c52ef83375fe15 @@ -93,7 +93,8 @@ COPY ./test/container/entrypoint.sh /usr/local/bin ARG UID # Prepare user configuration & build environments -RUN useradd -l -u ${UID} -d /home/user -s /bin/bash user && \ +RUN userdel -r ubuntu && \ + 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 && \ @@ -101,6 +102,7 @@ RUN useradd -l -u ${UID} -d /home/user -s /bin/bash user && \ chgrp -R user /home/user && \ 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 '*' && \ mkdir -p /go/pkg && \ mkdir -p /var/run/sshd && \ mkdir -p /root/.ssh && \ diff --git a/test/container/Procfile b/test/container/Procfile index 3ec9add44d5a7..4cebac203f76d 100644 --- a/test/container/Procfile +++ b/test/container/Procfile @@ -1,6 +1,6 @@ controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''}" api-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_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} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} " -dex: sh -c "test $ARGOCD_IN_CI = true && exit 0; ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/cmd gendexcfg -o `pwd`/dist/dex.yaml && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:v2.38.0 serve /dex.yaml" +dex: sh -c "test $ARGOCD_IN_CI = true && exit 0; ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/cmd gendexcfg -o `pwd`/dist/dex.yaml && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:v2.41.1 serve /dex.yaml" redis: sh -c "/usr/local/bin/redis-server --save "" --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}" repo-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} ARGOCD_BINARY_NAME=argocd-repo-server $COMMAND --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}" ui: sh -c "test $ARGOCD_IN_CI = true && exit 0; cd ui && ARGOCD_E2E_YARN_HOST=0.0.0.0 ${ARGOCD_E2E_YARN_CMD:-yarn} start" diff --git a/test/e2e/accounts_test.go b/test/e2e/accounts_test.go index c238aacb728b5..7f3f056a952c9 100644 --- a/test/e2e/accounts_test.go +++ b/test/e2e/accounts_test.go @@ -2,7 +2,6 @@ package e2e import ( "context" - "strings" "testing" "github.com/argoproj/pkg/errors" @@ -50,7 +49,7 @@ func TestCanIGetLogsAllowNoSwitch(t *testing.T) { CanIGetLogs(). Then(). AndCLIOutput(func(output string, err error) { - assert.True(t, strings.Contains(output, "yes")) + assert.Contains(t, output, "yes") }) } @@ -65,7 +64,7 @@ func TestCanIGetLogsDenySwitchOn(t *testing.T) { CanIGetLogs(). Then(). AndCLIOutput(func(output string, err error) { - assert.True(t, strings.Contains(output, "no")) + assert.Contains(t, output, "no") }) } @@ -93,7 +92,7 @@ func TestCanIGetLogsAllowSwitchOn(t *testing.T) { CanIGetLogs(). Then(). AndCLIOutput(func(output string, err error) { - assert.True(t, strings.Contains(output, "yes")) + assert.Contains(t, output, "yes") }) } @@ -108,7 +107,7 @@ func TestCanIGetLogsAllowSwitchOff(t *testing.T) { CanIGetLogs(). Then(). AndCLIOutput(func(output string, err error) { - assert.True(t, strings.Contains(output, "yes")) + assert.Contains(t, output, "yes") }) } diff --git a/test/e2e/admin_test.go b/test/e2e/admin_test.go new file mode 100644 index 0000000000000..a896888b1b55f --- /dev/null +++ b/test/e2e/admin_test.go @@ -0,0 +1,79 @@ +package e2e + +import ( + "context" + "testing" + + "github.com/argoproj/gitops-engine/pkg/utils/kube" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + . "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) { + var exportRawOutput string + ctx := Given(t) + // Create application in argocd namespace + appctx := appfixture.GivenWithSameState(t) + + // Create application in test namespace + appctx. + Path(guestbookPath). + Name("exported-app1"). + When(). + CreateApp(). + Then(). + And(func(app *Application) { + assert.Equal(t, "exported-app1", app.Name) + assert.Equal(t, fixture.TestNamespace(), app.Namespace) + }) + + // Create app in other namespace + appctx. + Path(guestbookPath). + Name("exported-app-other-namespace"). + SetAppNamespace(fixture.AppNamespace()). + When(). + CreateApp(). + Then(). + And(func(app *Application) { + assert.Equal(t, "exported-app-other-namespace", app.Name) + assert.Equal(t, fixture.AppNamespace(), app.Namespace) + }) + + ctx. + When(). + RunExport(). + Then(). + AndCLIOutput(func(output string, err error) { + require.NoError(t, err, "export finished with error") + exportRawOutput = output + }). + AndExportedResources(func(exportResources *ExportedResources, err error) { + require.NoError(t, err, "export format not valid") + assert.True(t, exportResources.HasResource(kube.NewResourceKey("", "ConfigMap", "", "argocd-cm")), "argocd-cm not found in export") + assert.True(t, exportResources.HasResource(kube.NewResourceKey(ApplicationSchemaGroupVersionKind.Group, ApplicationSchemaGroupVersionKind.Kind, "", "exported-app1")), "test namespace application not in export") + assert.True(t, exportResources.HasResource(kube.NewResourceKey(ApplicationSchemaGroupVersionKind.Group, ApplicationSchemaGroupVersionKind.Kind, fixture.AppNamespace(), "exported-app-other-namespace")), "app namespace application not in export") + }) + + // Test import - clean state + ctx = Given(t) + + ctx. + When(). + RunImport(exportRawOutput). + Then(). + AndCLIOutput(func(output string, err error) { + require.NoError(t, err, "import finished with error") + _, 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(context.Background(), "exported-app-other-namespace", v1.GetOptions{}) + require.NoError(t, err, "failed getting app namespace application after import") + }) +} diff --git a/test/e2e/app_k8s_events_test.go b/test/e2e/app_k8s_events_test.go new file mode 100644 index 0000000000000..7438adfe7001c --- /dev/null +++ b/test/e2e/app_k8s_events_test.go @@ -0,0 +1,65 @@ +package e2e + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + . "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 +func TestLabelsOnAppK8sEvents(t *testing.T) { + expectedLabels := map[string]string{"app": "test", "environment": "dev"} + + Given(t). + Timeout(60). + Path("two-nice-pods"). + When(). + SetParamInSettingConfigMap("resource.includeEventLabelKeys", "app,team,env*"). + SetParamInSettingConfigMap("resource.excludeEventLabelKeys", "team"). + CreateApp("--label=app=test", "--label=environment=dev", "--label=team=A", "--label=tier=ui"). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + And(func(app *Application) { + 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) + for _, event := range events.Items { + for k, v := range event.Labels { + ev, found := expectedLabels[k] + assert.True(t, found) + assert.Equal(t, ev, v) + } + } + }) +} + +// resource.includeEventLabelKeys keys not set in argocd-cm +func TestNoLabelsOnAppK8sEvents(t *testing.T) { + Given(t). + Timeout(60). + Path("two-nice-pods"). + When(). + CreateApp("--label=app=test", "--label=environment=dev", "--label=team=A", "--label=tier=ui"). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + And(func(app *Application) { + 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) + for _, event := range events.Items { + assert.Nil(t, event.Labels) + } + }) +} diff --git a/test/e2e/app_management_ns_test.go b/test/e2e/app_management_ns_test.go index 4257e59bf9a62..d4717f57d0f7f 100644 --- a/test/e2e/app_management_ns_test.go +++ b/test/e2e/app_management_ns_test.go @@ -2291,6 +2291,7 @@ definitions: } func TestNamespacedAppLogs(t *testing.T) { + t.SkipNow() // Too flaky. https://github.com/argoproj/argo-cd/issues/13834 SkipOnEnv(t, "OPENSHIFT") Given(t). SetAppNamespace(AppNamespace()). diff --git a/test/e2e/app_management_test.go b/test/e2e/app_management_test.go index c34ed635e71bd..67e1b4b03397c 100644 --- a/test/e2e/app_management_test.go +++ b/test/e2e/app_management_test.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "reflect" - "regexp" "testing" "time" @@ -770,7 +769,7 @@ func assetSecretDataHidden(t *testing.T, manifest string) { require.NoError(t, err) assert.True(t, hasData) for _, v := range secretData { - assert.Regexp(t, regexp.MustCompile(`[*]*`), v) + assert.Regexp(t, `[*]*`, v) } var lastAppliedConfigAnnotation string annotations := secret.GetAnnotations() @@ -2420,6 +2419,7 @@ definitions: } func TestAppLogs(t *testing.T) { + t.SkipNow() // Too flaky. https://github.com/argoproj/argo-cd/issues/13834 SkipOnEnv(t, "OPENSHIFT") Given(t). Path("guestbook-logs"). @@ -2880,3 +2880,46 @@ func TestAnnotationTrackingExtraResources(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(HealthIs(health.HealthStatusHealthy)) } + +func TestCreateConfigMapsAndWaitForUpdate(t *testing.T) { + Given(t). + Path("config-map"). + When(). + CreateApp(). + Sync(). + Then(). + And(func(app *Application) { + _, err := RunCli("app", "set", app.Name, "--sync-policy", "automated") + require.NoError(t, err) + }). + When(). + AddFile("other-configmap.yaml", ` +apiVersion: v1 +kind: ConfigMap +metadata: + name: other-map + annotations: + argocd.argoproj.io/sync-wave: "1" +data: + foo2: bar2`). + AddFile("yet-another-configmap.yaml", ` +apiVersion: v1 +kind: ConfigMap +metadata: + name: yet-another-map + annotations: + argocd.argoproj.io/sync-wave: "2" +data: + foo3: bar3`). + PatchFile("kustomization.yaml", `[{"op": "add", "path": "/resources/-", "value": "other-configmap.yaml"}, {"op": "add", "path": "/resources/-", "value": "yet-another-configmap.yaml"}]`). + Refresh(RefreshTypeNormal). + Wait(). + Then(). + Expect(OperationPhaseIs(OperationSucceeded)). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + Expect(HealthIs(health.HealthStatusHealthy)). + 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)) +} diff --git a/test/e2e/applicationset_test.go b/test/e2e/applicationset_test.go index 0b32f528023a6..5df36d591b1d9 100644 --- a/test/e2e/applicationset_test.go +++ b/test/e2e/applicationset_test.go @@ -522,101 +522,6 @@ func TestSimpleListGeneratorGoTemplate(t *testing.T) { Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewMetadata})) } -func TestCreateApplicationDespiteParamsError(t *testing.T) { - expectedErrorMessage := `failed to execute go template {{.cluster}}-guestbook: template: :1:2: executing "" at <.cluster>: map has no entry for key "cluster"` - expectedConditionsParamsError := []v1alpha1.ApplicationSetCondition{ - { - Type: v1alpha1.ApplicationSetConditionErrorOccurred, - Status: v1alpha1.ApplicationSetConditionStatusTrue, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonRenderTemplateParamsError, - }, - { - Type: v1alpha1.ApplicationSetConditionParametersGenerated, - Status: v1alpha1.ApplicationSetConditionStatusFalse, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonErrorOccurred, - }, - { - Type: v1alpha1.ApplicationSetConditionResourcesUpToDate, - Status: v1alpha1.ApplicationSetConditionStatusFalse, - Message: expectedErrorMessage, - Reason: v1alpha1.ApplicationSetReasonRenderTemplateParamsError, - }, - } - expectedApp := argov1alpha1.Application{ - TypeMeta: metav1.TypeMeta{ - Kind: application.ApplicationKind, - APIVersion: "argoproj.io/v1alpha1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "my-cluster-guestbook", - 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", - }, - }, - } - - Given(t). - // Create a ListGenerator-based ApplicationSet - When().Create(v1alpha1.ApplicationSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "simple-list-generator", - }, - Spec: v1alpha1.ApplicationSetSpec{ - GoTemplate: true, - GoTemplateOptions: []string{"missingkey=error"}, - Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-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: "{{.url}}", - Namespace: "guestbook", - }, - }, - }, - Generators: []v1alpha1.ApplicationSetGenerator{ - { - List: &v1alpha1.ListGenerator{ - Elements: []apiextensionsv1.JSON{ - { - Raw: []byte(`{"cluster": "my-cluster","url": "https://kubernetes.default.svc"}`), - }, - { - Raw: []byte(`{"invalidCluster": "invalid-cluster","url": "https://kubernetes.default.svc"}`), - }, - }, - }, - }, - }, - }, - }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). - - // verify the ApplicationSet status conditions were set correctly - Expect(ApplicationSetHasConditions("simple-list-generator", expectedConditionsParamsError)). - - // Delete the ApplicationSet, and verify it deletes the Applications - When(). - Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedApp})) -} - func TestRenderHelmValuesObject(t *testing.T) { expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ @@ -940,7 +845,10 @@ func TestSyncPolicyCreateUpdate(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ GoTemplate: true, Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook-sync-policy-create-update"}, + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ + Name: "{{.cluster}}-guestbook-sync-policy-create-update", + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", Source: &argov1alpha1.ApplicationSource{ @@ -1008,9 +916,11 @@ func TestSyncPolicyCreateUpdate(t *testing.T) { // verify the ApplicationSet status conditions were set correctly Expect(ApplicationSetHasConditions("sync-policy-create-update", ExpectedConditions)). - // Delete the ApplicationSet, and verify it deletes the Applications + // Delete the ApplicationSet, and verify it not deletes the Applications + // 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(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewMetadata})) + Delete().Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})) } func TestSyncPolicyCreateDelete(t *testing.T) { @@ -1147,7 +1057,10 @@ func TestSyncPolicyCreateOnly(t *testing.T) { Spec: v1alpha1.ApplicationSetSpec{ GoTemplate: true, Template: v1alpha1.ApplicationSetTemplate{ - ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook-sync-policy-create-only"}, + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ + Name: "{{.cluster}}-guestbook-sync-policy-create-only", + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, Spec: argov1alpha1.ApplicationSpec{ Project: "default", Source: &argov1alpha1.ApplicationSource{ @@ -1206,9 +1119,11 @@ func TestSyncPolicyCreateOnly(t *testing.T) { // verify the ApplicationSet status conditions were set correctly Expect(ApplicationSetHasConditions("sync-policy-create-only", ExpectedConditions)). - // Delete the ApplicationSet, and verify it deletes the Applications + // Delete the ApplicationSet, and verify it not deletes the Applications + // 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(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewNamespace})) + Delete().Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})) } func TestSimpleGitDirectoryGenerator(t *testing.T) { @@ -2761,6 +2676,7 @@ func githubPullMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request _, err := io.WriteString(w, `[ { "number": 1, + "title": "title1", "labels": [ { "name": "preview" @@ -2773,7 +2689,10 @@ func githubPullMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request "head": { "ref": "pull-request", "sha": "824a5c987fdfb2b0629e9dbf5f31636c69ba4772" - } + }, + "user": { + "login": "testName" + } } ]`) if err != nil { diff --git a/test/e2e/cluster_test.go b/test/e2e/cluster_test.go index 81399c0a01022..d09df7d0cc812 100644 --- a/test/e2e/cluster_test.go +++ b/test/e2e/cluster_test.go @@ -3,7 +3,6 @@ package e2e import ( "fmt" "net/url" - "strings" "testing" "time" @@ -171,8 +170,8 @@ func TestClusterSet(t *testing.T) { GetByName("in-cluster"). Then(). AndCLIOutput(func(output string, err error) { - assert.True(t, strings.Contains(output, "namespace-edit-1")) - assert.True(t, strings.Contains(output, "namespace-edit-2")) + assert.Contains(t, output, "namespace-edit-1") + assert.Contains(t, output, "namespace-edit-2") }) } diff --git a/test/e2e/fixture/admin/actions.go b/test/e2e/fixture/admin/actions.go new file mode 100644 index 0000000000000..4519d228f9c1a --- /dev/null +++ b/test/e2e/fixture/admin/actions.go @@ -0,0 +1,67 @@ +package admin + +import ( + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" +) + +// this implements the "when" part of given/when/then +// +// none of the func implement error checks, and that is complete intended, you should check for errors +// using the Then() +type Actions struct { + context *Context + ignoreErrors bool + lastOutput string + lastError error +} + +func (a *Actions) prepareExportCommand() []string { + a.context.t.Helper() + args := []string{"export", "--application-namespaces", fixture.AppNamespace()} + + return args +} + +func (a *Actions) prepareImportCommand() []string { + a.context.t.Helper() + args := []string{"import", "--application-namespaces", fixture.AppNamespace(), "-"} + + return args +} + +func (a *Actions) RunExport() *Actions { + a.context.t.Helper() + a.runCli(a.prepareExportCommand()...) + return a +} + +func (a *Actions) RunImport(stdin string) *Actions { + a.context.t.Helper() + a.runCliWithStdin(stdin, a.prepareImportCommand()...) + return a +} + +func (a *Actions) IgnoreErrors() *Actions { + a.ignoreErrors = true + return a +} + +func (a *Actions) DoNotIgnoreErrors() *Actions { + a.ignoreErrors = false + return a +} + +func (a *Actions) runCli(args ...string) { + a.context.t.Helper() + a.lastOutput, a.lastError = RunCli(args...) +} + +func (a *Actions) runCliWithStdin(stdin string, args ...string) { + a.context.t.Helper() + a.lastOutput, a.lastError = RunCliWithStdin(stdin, args...) +} + +func (a *Actions) Then() *Consequences { + a.context.t.Helper() + return &Consequences{a.context, a} +} diff --git a/test/e2e/fixture/admin/consequences.go b/test/e2e/fixture/admin/consequences.go new file mode 100644 index 0000000000000..bc65f3a532794 --- /dev/null +++ b/test/e2e/fixture/admin/consequences.go @@ -0,0 +1,37 @@ +package admin + +import ( + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/admin/utils" +) + +// this implements the "then" part of given/when/then +type Consequences struct { + context *Context + actions *Actions +} + +func (c *Consequences) And(block func()) *Consequences { + c.context.t.Helper() + block() + return c +} + +func (c *Consequences) AndCLIOutput(block func(output string, err error)) *Consequences { + c.context.t.Helper() + block(c.actions.lastOutput, c.actions.lastError) + return c +} + +// For use after running export with the exported resources desirialized +func (c *Consequences) AndExportedResources(block func(resources *ExportedResources, err error)) { + result, err := GetExportedResourcesFromOutput(c.actions.lastOutput) + block(&result, err) +} + +func (c *Consequences) Given() *Context { + return c.context +} + +func (c *Consequences) When() *Actions { + return c.actions +} diff --git a/test/e2e/fixture/admin/context.go b/test/e2e/fixture/admin/context.go new file mode 100644 index 0000000000000..aed58cb1a7b79 --- /dev/null +++ b/test/e2e/fixture/admin/context.go @@ -0,0 +1,41 @@ +package admin + +import ( + "testing" + + "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 +} + +func Given(t *testing.T) *Context { + fixture.EnsureCleanState(t) + return GivenWithSameState(t) +} + +func GivenWithSameState(t *testing.T) *Context { + // ARGOCE_E2E_DEFAULT_TIMEOUT can be used to override the default timeout + // for any context. + timeout := env.ParseNumFromEnv("ARGOCD_E2E_DEFAULT_TIMEOUT", 20, 0, 180) + return &Context{ + t: t, + name: fixture.Name(), + timeout: timeout, + } +} + +func (c *Context) And(block func()) *Context { + block() + return c +} + +func (c *Context) When() *Actions { + return &Actions{context: c} +} diff --git a/test/e2e/fixture/admin/fixture.go b/test/e2e/fixture/admin/fixture.go new file mode 100644 index 0000000000000..92216c58d42fe --- /dev/null +++ b/test/e2e/fixture/admin/fixture.go @@ -0,0 +1,15 @@ +package admin + +import ( + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" +) + +// For admin CLI with kubernetes context +func RunCli(args ...string) (string, error) { + return RunCliWithStdin("", args...) +} + +func RunCliWithStdin(stdin string, args ...string) (string, error) { + args = append([]string{"admin", "--namespace", fixture.TestNamespace()}, args...) + return fixture.RunCliWithStdin(stdin, true, args...) +} diff --git a/test/e2e/fixture/admin/utils/backup.go b/test/e2e/fixture/admin/utils/backup.go new file mode 100644 index 0000000000000..79bd890518603 --- /dev/null +++ b/test/e2e/fixture/admin/utils/backup.go @@ -0,0 +1,48 @@ +package utils + +import ( + "fmt" + "strings" + + kube "github.com/argoproj/gitops-engine/pkg/utils/kube" + yaml "gopkg.in/yaml.v3" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +type ExportedResources []unstructured.Unstructured + +func GetExportedResourcesFromOutput(output string) (ExportedResources, error) { + var resources []unstructured.Unstructured + docs := strings.Split(output, "---") + + for _, doc := range docs { + doc = strings.TrimSpace(doc) + if len(doc) == 0 { + continue + } + + var resourceData map[string]interface{} + + if err := yaml.Unmarshal([]byte(doc), &resourceData); err != nil { + return nil, fmt.Errorf("error unmarshaling YAML: %w", err) + } + + resource := unstructured.Unstructured{Object: resourceData} + resources = append(resources, resource) + } + + return resources, nil +} + +func (e ExportedResources) HasResource(resource kube.ResourceKey) bool { + for _, res := range e { + if res.GetObjectKind().GroupVersionKind().Group == resource.Group && + res.GetKind() == resource.Kind && + res.GetName() == resource.Name && + res.GetNamespace() == resource.Namespace { + return true + } + } + + return false +} diff --git a/test/e2e/fixture/app/expectation.go b/test/e2e/fixture/app/expectation.go index 8546a4eed7be9..b5e83a664085c 100644 --- a/test/e2e/fixture/app/expectation.go +++ b/test/e2e/fixture/app/expectation.go @@ -143,14 +143,28 @@ func ResourceSyncStatusWithNamespaceIs(kind, resource, namespace string, expecte func ResourceHealthIs(kind, resource string, expected health.HealthStatusCode) Expectation { return func(c *Consequences) (state, string) { - actual := c.resource(kind, resource, "").Health.Status + var actual health.HealthStatusCode + resourceHealth := c.resource(kind, resource, "").Health + if resourceHealth != nil { + actual = resourceHealth.Status + } else { + // Some resources like ConfigMap may not have health status when they are okay + actual = health.HealthStatusHealthy + } return simple(actual == expected, fmt.Sprintf("resource '%s/%s' health should be %s, is %s", kind, resource, expected, actual)) } } func ResourceHealthWithNamespaceIs(kind, resource, namespace string, expected health.HealthStatusCode) Expectation { return func(c *Consequences) (state, string) { - actual := c.resource(kind, resource, namespace).Health.Status + var actual health.HealthStatusCode + resourceHealth := c.resource(kind, resource, namespace).Health + if resourceHealth != nil { + actual = resourceHealth.Status + } else { + // Some resources like ConfigMap may not have health status when they are okay + actual = health.HealthStatusHealthy + } return simple(actual == expected, fmt.Sprintf("resource '%s/%s' health should be %s, is %s", kind, resource, expected, actual)) } } diff --git a/test/e2e/fixture/applicationsets/utils/fixture.go b/test/e2e/fixture/applicationsets/utils/fixture.go index e447f9d455433..1ff0fbbfd6137 100644 --- a/test/e2e/fixture/applicationsets/utils/fixture.go +++ b/test/e2e/fixture/applicationsets/utils/fixture.go @@ -268,7 +268,7 @@ func cleanUpNamespace(fixtureClient *E2EFixtureK8sClient, namespace string) erro msg = err.Error() } - return fmt.Errorf(msg) + return fmt.Errorf("%s", msg) } // waitForSuccess waits for the condition to return a non-error value. diff --git a/test/e2e/fixture/cluster/actions.go b/test/e2e/fixture/cluster/actions.go index bd8fb33184379..ac114bad0cdf9 100644 --- a/test/e2e/fixture/cluster/actions.go +++ b/test/e2e/fixture/cluster/actions.go @@ -3,7 +3,6 @@ package cluster import ( "context" "errors" - "fmt" "log" "strings" @@ -60,7 +59,7 @@ func (a *Actions) Create(args ...string) *Actions { }) if err != nil { if !a.ignoreErrors { - log.Fatalf(fmt.Sprintf("Failed to upsert cluster %v", err.Error())) + log.Fatalf("Failed to upsert cluster %v", err.Error()) } a.lastError = errors.New(err.Error()) } diff --git a/test/e2e/fixture/fixture.go b/test/e2e/fixture/fixture.go index e9e2c351c3df9..24d0e4ce74d71 100644 --- a/test/e2e/fixture/fixture.go +++ b/test/e2e/fixture/fixture.go @@ -741,15 +741,20 @@ func RunCliWithRetry(maxRetries int, args ...string) (string, error) { } func RunCli(args ...string) (string, error) { - return RunCliWithStdin("", args...) + return RunCliWithStdin("", false, args...) } -func RunCliWithStdin(stdin string, args ...string) (string, error) { +func RunCliWithStdin(stdin string, isKubeConextOnlyCli bool, args ...string) (string, error) { if plainText { args = append(args, "--plaintext") } - args = append(args, "--server", apiServerAddress, "--auth-token", token, "--insecure") + // For commands executed with Kubernetes context server argument causes a conflict (for those commands server argument is for KubeAPI server), also authentication is not required + if !isKubeConextOnlyCli { + args = append(args, "--server", apiServerAddress, "--auth-token", token) + } + + args = append(args, "--insecure") return RunWithStdin(stdin, "", "../../dist/argocd", args...) } @@ -1010,3 +1015,11 @@ func RecordTestRun(t *testing.T) { t.Fatalf("could not write to %s: %v", rf, err) } } + +func GetApiServerAddress() string { + return apiServerAddress +} + +func GetToken() string { + return token +} diff --git a/test/e2e/git_test.go b/test/e2e/git_test.go index d231ab2034311..7c92274dab56a 100644 --- a/test/e2e/git_test.go +++ b/test/e2e/git_test.go @@ -27,6 +27,21 @@ func TestGitSemverResolutionNotUsingConstraint(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)) } +func TestGitSemverResolutionNotUsingConstraintWithLeadingZero(t *testing.T) { + Given(t). + Path("deployment"). + CustomSSHKnownHostsAdded(). + SSHRepoURLAdded(true). + RepoURLType(fixture.RepoURLTypeSSH). + Revision("0.1.0"). + When(). + AddTag("0.1.0"). + CreateApp(). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)) +} + func TestGitSemverResolutionUsingConstraint(t *testing.T) { Given(t). Path("deployment"). @@ -51,3 +66,28 @@ func TestGitSemverResolutionUsingConstraint(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(Pod(func(p v1.Pod) bool { return strings.HasPrefix(p.Name, "new-app") })) } + +func TestGitSemverResolutionUsingConstraintWithLeadingZero(t *testing.T) { + Given(t). + Path("deployment"). + CustomSSHKnownHostsAdded(). + SSHRepoURLAdded(true). + RepoURLType(fixture.RepoURLTypeSSH). + Revision("0.1.*"). + When(). + AddTag("0.1.0"). + CreateApp(). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + When(). + PatchFile("deployment.yaml", `[ + {"op": "replace", "path": "/metadata/name", "value": "new-app"}, + {"op": "replace", "path": "/spec/replicas", "value": 1} +]`). + AddTag("0.1.2"). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + Expect(Pod(func(p v1.Pod) bool { return strings.HasPrefix(p.Name, "new-app") })) +} diff --git a/test/e2e/helm_test.go b/test/e2e/helm_test.go index 06e0c8ea9e622..9a95829c33c50 100644 --- a/test/e2e/helm_test.go +++ b/test/e2e/helm_test.go @@ -362,9 +362,64 @@ func TestKubeVersion(t *testing.T) { "-o", "jsonpath={.data.kubeVersion}")).(string) // Capabilities.KubeVersion defaults to 1.9.0, we assume here you are running a later version assert.LessOrEqual(t, GetVersions().ServerVersion.Format("v%s.%s.0"), kubeVersion) + }). + When(). + // Make sure override works. + AppSet("--helm-kube-version", "999.999.999"). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + 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) { + SkipOnEnv(t, "HELM") + Given(t). + Path("helm-api-versions"). + When(). + CreateApp(). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + 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") + }). + When(). + // Make sure override works. + AppSet("--helm-api-versions", "v1/MyTestResource"). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + 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) { + SkipOnEnv(t, "HELM") + Given(t). + Path("helm-namespace"). + When(). + CreateApp(). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + When(). + AppSet("--helm-namespace", "does-not-exist"). + Then(). + // The app should go out of sync, because the resource's target namespace changed. + Expect(SyncStatusIs(SyncStatusCodeOutOfSync)) +} + func TestHelmValuesHiddenDirectory(t *testing.T) { SkipOnEnv(t, "HELM") Given(t). diff --git a/test/e2e/hook_test.go b/test/e2e/hook_test.go index 7c3860b47c8f2..5fe2248051737 100644 --- a/test/e2e/hook_test.go +++ b/test/e2e/hook_test.go @@ -68,7 +68,7 @@ func TestPostDeleteHook(t *testing.T) { }) } -// make sure that that hooks do not appear in "argocd app diff" +// make sure that hooks do not appear in "argocd app diff" func TestHookDiff(t *testing.T) { Given(t). Path("hook"). diff --git a/test/e2e/kustomize_test.go b/test/e2e/kustomize_test.go index 8936d591cfb65..923b9d46fee9e 100644 --- a/test/e2e/kustomize_test.go +++ b/test/e2e/kustomize_test.go @@ -11,8 +11,10 @@ import ( . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" . "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) { @@ -286,3 +288,88 @@ func TestKustomizeUnsetOverrideDeployment(t *testing.T) { assert.Nil(t, app.Spec.Source.Kustomize) }) } + +// make sure kube-version gets passed down to resources +func TestKustomizeKubeVersion(t *testing.T) { + Given(t). + Path("kustomize-kube-version"). + And(func() { + errors.FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", + "-n", fixture.TestNamespace(), + "-p", `{ "data": { "kustomize.buildOptions": "--enable-helm" } }`)) + }). + When(). + CreateApp(). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + 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, GetVersions().ServerVersion.Format("v%s.%s.0"), kubeVersion) + }). + When(). + // Make sure override works. + AppSet("--kustomize-kube-version", "999.999.999"). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + 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 TestKustomizeApiVersions(t *testing.T) { + Given(t). + Path("kustomize-api-versions"). + And(func() { + errors.FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", + "-n", fixture.TestNamespace(), + "-p", `{ "data": { "kustomize.buildOptions": "--enable-helm" } }`)) + }). + When(). + CreateApp(). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + 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") + }). + When(). + // Make sure override works. + AppSet("--kustomize-api-versions", "v1/MyTestResource"). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + 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 TestKustomizeNamespaceOverride(t *testing.T) { + Given(t). + Path("kustomize-kube-version"). + And(func() { + errors.FailOnErr(fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", + "-n", fixture.TestNamespace(), + "-p", `{ "data": { "kustomize.buildOptions": "--enable-helm" } }`)) + }). + When(). + CreateApp(). + Sync(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + When(). + AppSet("--kustomize-namespace", "does-not-exist"). + Then(). + // The app should go out of sync, because the resource's target namespace changed. + Expect(SyncStatusIs(SyncStatusCodeOutOfSync)) +} diff --git a/test/e2e/multiarch-container/Dockerfile b/test/e2e/multiarch-container/Dockerfile index 54ae46ffed69a..ad49d66dc585c 100644 --- a/test/e2e/multiarch-container/Dockerfile +++ b/test/e2e/multiarch-container/Dockerfile @@ -1,2 +1,2 @@ -FROM docker.io/library/busybox@sha256:9ae97d36d26566ff84e8893c64a6dc4fe8ca6d1144bf5b87b2b85a32def253c7 +FROM docker.io/library/busybox@sha256:c230832bd3b0be59a6c47ed64294f9ce71e91b327957920b6929a0caa8353140 CMD exec sh -c "trap : TERM INT; echo 'Hi' && tail -f /dev/null" diff --git a/test/e2e/project_management_test.go b/test/e2e/project_management_test.go index 5e8b42a94442d..f00c4e3eeba62 100644 --- a/test/e2e/project_management_test.go +++ b/test/e2e/project_management_test.go @@ -80,12 +80,12 @@ func TestProjectCreation(t *testing.T) { require.NoError(t, err) // fail without upsert flag - _, err = fixture.RunCliWithStdin(stdinString, "proj", "create", + _, err = fixture.RunCliWithStdin(stdinString, false, "proj", "create", "-f", "-") require.Error(t, err) // succeed with the upsert flag - _, err = fixture.RunCliWithStdin(stdinString, "proj", "create", + _, err = fixture.RunCliWithStdin(stdinString, false, "proj", "create", "-f", "-", "--upsert") require.NoError(t, err) proj, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) @@ -164,21 +164,21 @@ func TestAddProjectDestination(t *testing.T) { "test1", ) require.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "already defined")) + assert.Contains(t, err.Error(), "already defined") _, err = fixture.RunCli("proj", "add-destination", projectName, "!*", "test1", ) require.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "server has an invalid format, '!*'")) + assert.Contains(t, err.Error(), "server has an invalid format, '!*'") _, err = fixture.RunCli("proj", "add-destination", projectName, "https://192.168.99.100:8443", "!*", ) require.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "namespace has an invalid format, '!*'")) + assert.Contains(t, err.Error(), "namespace has an invalid format, '!*'") proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) require.NoError(t, err) @@ -383,7 +383,7 @@ func TestUseJWTToken(t *testing.T) { roleGetResult, err = fixture.RunCli("proj", "role", "get", projectName, roleName) require.NoError(t, err) - assert.True(t, strings.Contains(roleGetResult, strconv.FormatInt(newProj.Status.JWTTokensByRole[roleName].Items[0].IssuedAt, 10))) + assert.Contains(t, roleGetResult, strconv.FormatInt(newProj.Status.JWTTokensByRole[roleName].Items[0].IssuedAt, 10)) _, err = fixture.RunCli("proj", "role", "delete-token", projectName, roleName, strconv.FormatInt(newProj.Status.JWTTokensByRole[roleName].Items[0].IssuedAt, 10)) require.NoError(t, err) @@ -420,7 +420,7 @@ func TestAddOrphanedIgnore(t *testing.T) { "name", ) require.Error(t, err) - assert.True(t, strings.Contains(err.Error(), "already defined")) + assert.Contains(t, err.Error(), "already defined") proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) require.NoError(t, err) diff --git a/test/e2e/scoped_repository_test.go b/test/e2e/scoped_repository_test.go index 1a459af06736d..d1da08b0a434d 100644 --- a/test/e2e/scoped_repository_test.go +++ b/test/e2e/scoped_repository_test.go @@ -1,7 +1,6 @@ package e2e import ( - "strings" "testing" "github.com/argoproj/argo-cd/v2/test/e2e/fixture" @@ -57,7 +56,7 @@ func TestCreateRepositoryNonAdminUserPermissionDenied(t *testing.T) { Create(). Then(). AndCLIOutput(func(output string, err error) { - assert.True(t, strings.Contains(err.Error(), "PermissionDenied desc = permission denied: repositories, create")) + assert.Contains(t, err.Error(), "PermissionDenied desc = permission denied: repositories, create") }) } @@ -84,7 +83,7 @@ func TestCreateRepositoryNonAdminUserWithWrongProject(t *testing.T) { Create(). Then(). AndCLIOutput(func(output string, err error) { - assert.True(t, strings.Contains(err.Error(), "PermissionDenied desc = permission denied: repositories, create")) + assert.Contains(t, err.Error(), "PermissionDenied desc = permission denied: repositories, create") }) } @@ -127,7 +126,7 @@ func TestDeleteRepositoryRbacAllowed(t *testing.T) { Delete(). Then(). AndCLIOutput(func(output string, err error) { - assert.True(t, strings.Contains(output, "Repository 'https://github.com/argoproj/argo-cd.git' removed")) + assert.Contains(t, output, "Repository 'https://github.com/argoproj/argo-cd.git' removed") }) } @@ -171,7 +170,7 @@ func TestDeleteRepositoryRbacDenied(t *testing.T) { Delete(). Then(). AndCLIOutput(func(output string, err error) { - assert.True(t, strings.Contains(err.Error(), "PermissionDenied desc = permission denied: repositories, delete")) + assert.Contains(t, err.Error(), "PermissionDenied desc = permission denied: repositories, delete") }) } diff --git a/test/e2e/sync_with_impersonate_test.go b/test/e2e/sync_with_impersonate_test.go new file mode 100644 index 0000000000000..7bb57af1156d3 --- /dev/null +++ b/test/e2e/sync_with_impersonate_test.go @@ -0,0 +1,309 @@ +package e2e + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + 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/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" +) + +func TestSyncWithImpersonateDisable(t *testing.T) { + Given(t). + Path("guestbook"). + When(). + SetParamInSettingConfigMap("application.sync.impersonation.enabled", "false"). + CreateFromFile(func(app *v1alpha1.Application) { + app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{Automated: &v1alpha1.SyncPolicyAutomated{}} + }). + Then(). + Expect(SyncStatusIs(v1alpha1.SyncStatusCodeSynced)) +} + +func TestSyncWithImpersonateDefaultNamespaceServiceAccountNoRBAC(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{}} + }). + Then(). + Expect(SyncStatusIs(v1alpha1.SyncStatusCodeOutOfSync)) +} + +func TestSyncWithImpersonateDefaultNamespaceServiceAccountWithRBAC(t *testing.T) { + roleName := "default-sa-role" + Given(t). + Path("guestbook"). + When(). + SetParamInSettingConfigMap("application.sync.impersonation.enabled", "true"). + CreateFromFile(func(app *v1alpha1.Application) { + app.Spec.SyncPolicy = &v1alpha1.SyncPolicy{Automated: &v1alpha1.SyncPolicyAutomated{}} + }). + And(func() { + err := createTestRole(roleName, fixture.DeploymentNamespace(), []rbac.PolicyRule{ + { + APIGroups: []string{"apps", ""}, + Resources: []string{"deployments"}, + Verbs: []string{"*"}, + }, + { + APIGroups: []string{""}, + Resources: []string{"services"}, + Verbs: []string{"*"}, + }, + }) + require.NoError(t, err) + err = createTestRoleBinding(roleName, "default", fixture.DeploymentNamespace()) + require.NoError(t, err) + }). + Then(). + Expect(SyncStatusIs(v1alpha1.SyncStatusCodeOutOfSync)) +} + +func TestSyncWithImpersonateWithSyncServiceAccount(t *testing.T) { + projectName := "sync-test-project" + serviceAccountName := "test-account" + roleName := "test-account-sa-role" + Given(t). + SetTrackingMethod("annotation"). + Path("guestbook"). + When(). + SetParamInSettingConfigMap("application.sync.impersonation.enabled", "true"). + And(func() { + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "*", + Namespace: fixture.DeploymentNamespace(), + DefaultServiceAccount: serviceAccountName, + }, + { + Server: "*", + Namespace: fixture.DeploymentNamespace(), + DefaultServiceAccount: "false-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{}} + app.Spec.Project = projectName + }). + Then(). + Expect(SyncStatusIs(v1alpha1.SyncStatusCodeSynced)) +} + +func TestSyncWithImpersonateWithFalseServiceAccount(t *testing.T) { + projectName := "false-test-project" + serviceAccountName := "test-account" + roleName := "test-account-sa-role" + Given(t). + SetTrackingMethod("annotation"). + Path("guestbook"). + When(). + SetParamInSettingConfigMap("application.sync.impersonation.enabled", "true"). + And(func() { + destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{ + { + Server: "*", + Namespace: fixture.DeploymentNamespace(), + DefaultServiceAccount: "false-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{}} + app.Spec.Project = projectName + }). + Then(). + Expect(SyncStatusIs(v1alpha1.SyncStatusCodeOutOfSync)) +} + +func TestSyncWithNegationApplicationDestinationNamespace(t *testing.T) { + projectName := "nagation-test-project" + serviceAccountName := "test-account" + roleName := "test-account-sa-role" + Given(t). + SetTrackingMethod("annotation"). + Path("guestbook"). + When(). + 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{}} + app.Spec.Project = projectName + }). + Then(). + Expect(SyncStatusIs(v1alpha1.SyncStatusCodeSynced)). + When(). + And(func() { + patch := []byte(fmt.Sprintf(`{"spec": {"destinations": [{"namespace": "%s"}]}}`, "!"+fixture.DeploymentNamespace())) + + _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Patch(context.Background(), projectName, types.MergePatchType, patch, metav1.PatchOptions{}) + require.NoError(t, err) + }). + Refresh(v1alpha1.RefreshTypeNormal). + Then(). + Expect(SyncStatusIs(v1alpha1.SyncStatusCodeUnknown)) +} + +// 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/helm-api-versions/Chart.yaml b/test/e2e/testdata/helm-api-versions/Chart.yaml new file mode 100644 index 0000000000000..4859bf0726b5f --- /dev/null +++ b/test/e2e/testdata/helm-api-versions/Chart.yaml @@ -0,0 +1,3 @@ +version: 1.0.0 +name: helm-api-versions +kubeVersion: ">=1.0.0" \ No newline at end of file diff --git a/test/e2e/testdata/helm-api-versions/templates/config-map.yaml b/test/e2e/testdata/helm-api-versions/templates/config-map.yaml new file mode 100644 index 0000000000000..5ec9e07025b61 --- /dev/null +++ b/test/e2e/testdata/helm-api-versions/templates/config-map.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: my-map +data: + apiVersions: | + {{.Capabilities.APIVersions | toJson}} diff --git a/test/e2e/testdata/helm-namespace/Chart.yaml b/test/e2e/testdata/helm-namespace/Chart.yaml new file mode 100644 index 0000000000000..a3becea5ac11b --- /dev/null +++ b/test/e2e/testdata/helm-namespace/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +version: 1.0.0 +name: helm \ No newline at end of file diff --git a/test/e2e/testdata/helm-namespace/baz.yaml b/test/e2e/testdata/helm-namespace/baz.yaml new file mode 100644 index 0000000000000..26a745ddb6d38 --- /dev/null +++ b/test/e2e/testdata/helm-namespace/baz.yaml @@ -0,0 +1 @@ +a: b diff --git a/test/e2e/testdata/helm-namespace/templates/config-map.yaml b/test/e2e/testdata/helm-namespace/templates/config-map.yaml new file mode 100644 index 0000000000000..776432f4d8265 --- /dev/null +++ b/test/e2e/testdata/helm-namespace/templates/config-map.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: my-map + namespace: {{.Release.Namespace}} +data: + foo: bar \ No newline at end of file diff --git a/test/e2e/testdata/helm-namespace/values.yaml b/test/e2e/testdata/helm-namespace/values.yaml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/test/e2e/testdata/kustomize-api-versions/helm-chart/Chart.yaml b/test/e2e/testdata/kustomize-api-versions/helm-chart/Chart.yaml new file mode 100644 index 0000000000000..62a5a8dccc5ad --- /dev/null +++ b/test/e2e/testdata/kustomize-api-versions/helm-chart/Chart.yaml @@ -0,0 +1,3 @@ +version: 1.0.0 +name: helm-kube-version +kubeVersion: ">=1.0.0" \ No newline at end of file diff --git a/test/e2e/testdata/kustomize-api-versions/helm-chart/templates/config-map.yaml b/test/e2e/testdata/kustomize-api-versions/helm-chart/templates/config-map.yaml new file mode 100644 index 0000000000000..1237da4ffd0be --- /dev/null +++ b/test/e2e/testdata/kustomize-api-versions/helm-chart/templates/config-map.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: my-map +data: + apiVersions: | + {{.Capabilities.APIVersions}} diff --git a/test/e2e/testdata/kustomize-api-versions/helm-chart/values.yaml b/test/e2e/testdata/kustomize-api-versions/helm-chart/values.yaml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/test/e2e/testdata/kustomize-api-versions/kustomization.yaml b/test/e2e/testdata/kustomize-api-versions/kustomization.yaml new file mode 100644 index 0000000000000..ed97d250133a7 --- /dev/null +++ b/test/e2e/testdata/kustomize-api-versions/kustomization.yaml @@ -0,0 +1,7 @@ +helmGlobals: + chartHome: . + +helmCharts: +- releaseName: test + name: helm-chart + version: v1.0.0 diff --git a/test/e2e/testdata/kustomize-kube-version/helm-chart/Chart.yaml b/test/e2e/testdata/kustomize-kube-version/helm-chart/Chart.yaml new file mode 100644 index 0000000000000..62a5a8dccc5ad --- /dev/null +++ b/test/e2e/testdata/kustomize-kube-version/helm-chart/Chart.yaml @@ -0,0 +1,3 @@ +version: 1.0.0 +name: helm-kube-version +kubeVersion: ">=1.0.0" \ No newline at end of file diff --git a/test/e2e/testdata/kustomize-kube-version/helm-chart/templates/config-map.yaml b/test/e2e/testdata/kustomize-kube-version/helm-chart/templates/config-map.yaml new file mode 100644 index 0000000000000..34ee852195ea4 --- /dev/null +++ b/test/e2e/testdata/kustomize-kube-version/helm-chart/templates/config-map.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: my-map +data: + kubeVersion: {{.Capabilities.KubeVersion}} diff --git a/test/e2e/testdata/kustomize-kube-version/helm-chart/values.yaml b/test/e2e/testdata/kustomize-kube-version/helm-chart/values.yaml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/test/e2e/testdata/kustomize-kube-version/kustomization.yaml b/test/e2e/testdata/kustomize-kube-version/kustomization.yaml new file mode 100644 index 0000000000000..ed97d250133a7 --- /dev/null +++ b/test/e2e/testdata/kustomize-kube-version/kustomization.yaml @@ -0,0 +1,7 @@ +helmGlobals: + chartHome: . + +helmCharts: +- releaseName: test + name: helm-chart + version: v1.0.0 diff --git a/test/remote/Dockerfile b/test/remote/Dockerfile index 139bd696437ce..fa649805767cc 100644 --- a/test/remote/Dockerfile +++ b/test/remote/Dockerfile @@ -1,6 +1,6 @@ ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:3f85b7caad41a95462cf5b787d8a04604c8262cdcdf9a472b8c52ef83375fe15 -FROM docker.io/library/golang:1.22.0@sha256:7b297d9abee021bab9046e492506b3c2da8a3722cbf301653186545ecc1e00bb AS go +FROM docker.io/library/golang:1.23.1@sha256:2fe82a3f3e006b4f2a316c6a21f62b66e1330ae211d039bb8d1128e12ed57bf1 AS go RUN go install github.com/mattn/goreman@latest && \ go install github.com/kisielk/godepgraph@latest diff --git a/ui-test/Dockerfile b/ui-test/Dockerfile index 88bf92ec46261..c0fbd1be9b711 100644 --- a/ui-test/Dockerfile +++ b/ui-test/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/node:22.3.0@sha256:5e4044ff6001d06e7748e35bfa4f80c73cf5f5a7360a1b782995e038a01b0585 as node +FROM docker.io/library/node:22.9.0@sha256:cbe2d5f94110cea9817dd8c5809d05df49b4bd1aac5203f3594d88665ad37988 as node RUN apt-get update && apt-get install --no-install-recommends -y \ software-properties-common diff --git a/ui-test/package.json b/ui-test/package.json index 90b1d8b95363e..a37fb07511461 100644 --- a/ui-test/package.json +++ b/ui-test/package.json @@ -12,21 +12,21 @@ "author": "Keith Chong", "license": "Apache-2.0", "dependencies": { - "@types/selenium-webdriver": "^4.1.23", + "@types/selenium-webdriver": "^4.1.26", "assert": "^2.1.0", - "chromedriver": "^126.0.0", - "selenium-webdriver": "^4.21.0" + "chromedriver": "^129.0.0", + "selenium-webdriver": "^4.24.1" }, "devDependencies": { - "@types/mocha": "^10.0.6", - "@types/node": "^20.14.2", + "@types/mocha": "^10.0.8", + "@types/node": "^22.5.5", "dotenv": "^16.4.5", - "mocha": "^10.4.0", + "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.4.5", + "typescript": "^5.6.2", "yarn": "^1.22.22" } } diff --git a/ui-test/yarn.lock b/ui-test/yarn.lock index 53e040160e378..e937e6532293e 100644 --- a/ui-test/yarn.lock +++ b/ui-test/yarn.lock @@ -23,6 +23,11 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@bazel/runfiles@^5.8.1": + version "5.8.1" + resolved "https://registry.yarnpkg.com/@bazel/runfiles/-/runfiles-5.8.1.tgz#737d5b3dc9739767054820265cfe432a80564c82" + integrity sha512-NDdfpdQ6rZlylgv++iMn5FkObC/QlBQvipinGLSOguTYpRywmieOyJ29XHvUilspwTFSILWpoE9CqMGkHXug1g== + "@testim/chrome-version@^1.1.4": version "1.1.4" resolved "https://registry.yarnpkg.com/@testim/chrome-version/-/chrome-version-1.1.4.tgz#86e04e677cd6c05fa230dd15ac223fa72d1d7090" @@ -33,22 +38,22 @@ resolved "https://registry.yarnpkg.com/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz#db4ecfd499a9765ab24002c3b696d02e6d32a12c" integrity sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA== -"@types/mocha@^10.0.6": - version "10.0.6" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.6.tgz#818551d39113081048bdddbef96701b4e8bb9d1b" - integrity sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg== +"@types/mocha@^10.0.8": + version "10.0.8" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.8.tgz#a7eff5816e070c3b4d803f1d3cd780c4e42934a1" + integrity sha512-HfMcUmy9hTMJh66VNcmeC9iVErIZJli2bszuXc6julh5YGuRb/W5OnkHjwLNYdFlMis0sY3If5SEAp+PktdJjw== -"@types/node@*", "@types/node@^20.14.2": - version "20.14.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.2.tgz#a5f4d2bcb4b6a87bffcaa717718c5a0f208f4a18" - integrity sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q== +"@types/node@*", "@types/node@^22.5.5": + version "22.5.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.5.tgz#52f939dd0f65fc552a4ad0b392f3c466cc5d7a44" + integrity sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA== dependencies: - undici-types "~5.26.4" + undici-types "~6.19.2" -"@types/selenium-webdriver@^4.1.23": - version "4.1.23" - resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.1.23.tgz#05a2794927db661f075ab443d5504b679b32f7f7" - integrity sha512-PgreEfCfafYLyTwvJTZvOspCq3JABnS51e+NSFFL5yoiMO7h04lWgLfr10NA7nl/yZbz4m76rBfOOdDfleb7pQ== +"@types/selenium-webdriver@^4.1.26": + version "4.1.26" + resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.1.26.tgz#09c696a341cf8cfc1641cded11d14813350b6ca9" + integrity sha512-PUgqsyNffal0eAU0bzGlh37MJo558aporAPZoKqBeB/pF7zhKl1S3zqza0GpwFqgoigNxWhEIJzru75eeYco/w== dependencies: "@types/node" "*" "@types/ws" "*" @@ -74,10 +79,10 @@ agent-base@^7.0.2, agent-base@^7.1.0, agent-base@^7.1.1: dependencies: debug "^4.3.4" -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +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" @@ -153,10 +158,10 @@ available-typed-arrays@^1.0.2: dependencies: array-filter "^1.0.0" -axios@^1.6.7: - version "1.7.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.1.tgz#522145622a09dfaf49359837db9649ff245a35b9" - integrity sha512-+LV37nQcd1EpFalkXksWNBiA17NZ5m5/WspmHGmZmdx1qBOg/VNq/c4eRJiA9VQQHBOs+N0ZhhdU10h2TyNK7Q== +axios@^1.7.4: + 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" @@ -199,9 +204,9 @@ braces@~3.0.2: dependencies: fill-range "^7.1.1" -browser-stdout@1.3.1: +browser-stdout@^1.3.1: version "1.3.1" - resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== buffer-crc32@~0.2.3: @@ -247,10 +252,10 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chokidar@3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== +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: anymatch "~3.1.2" braces "~3.0.2" @@ -262,13 +267,13 @@ chokidar@3.5.3: optionalDependencies: fsevents "~2.3.2" -chromedriver@^126.0.0: - version "126.0.0" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-126.0.0.tgz#a92f116fc9a9f45b531adb708d5e00f97722cd56" - integrity sha512-rzwKp1okI9RmFtSyIzkk9+GTlTK62ai5P3/AS2qMwl86+gw84d2S/IyLkQMm5cqieFs4dgDAuqqPu0AqQACScg== +chromedriver@^129.0.0: + version "129.0.0" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-129.0.0.tgz#28d7ede5ab372b868ac0db5efff7036646b4d603" + integrity sha512-B1ccqD6hDjNrw94FeqdynIotn1ZV/TnFrkRz2Rync2kzSnq6D6IrSkN1w5Pnuvnc98QhN2xujxDXxkqEqy/PWg== dependencies: "@testim/chrome-version" "^1.1.4" - axios "^1.6.7" + axios "^1.7.4" compare-versions "^6.1.0" extract-zip "^2.0.1" proxy-agent "^6.4.0" @@ -340,12 +345,12 @@ data-uri-to-buffer@^6.0.2: resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz#8a58bb67384b261a38ef18bea1810cb01badd28b" integrity sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw== -debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== +debug@4, debug@^4.1.1, debug@^4.3.4, debug@^4.3.5: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== dependencies: - ms "2.1.2" + ms "^2.1.3" debug@4.3.1: version "4.3.1" @@ -403,16 +408,16 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - diff@^4.0.1: version "4.0.2" resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +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.4.5: version "16.4.5" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" @@ -474,16 +479,16 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + escodegen@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" @@ -548,9 +553,9 @@ fill-range@^7.1.1: dependencies: to-regex-range "^5.0.1" -find-up@5.0.0: +find-up@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" @@ -649,17 +654,6 @@ glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -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" - glob@^7.1.1: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" @@ -672,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" @@ -730,9 +735,9 @@ hasown@^2.0.0: dependencies: function-bind "^1.1.2" -he@1.2.0: +he@^1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== http-proxy-agent@^7.0.0, http-proxy-agent@^7.0.1: @@ -924,13 +929,6 @@ js-tokens@^4.0.0: resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - js-yaml@^3.13.1: version "3.14.0" resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz" @@ -939,6 +937,13 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsbn@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" @@ -982,7 +987,7 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -log-symbols@4.1.0: +log-symbols@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== @@ -1007,13 +1012,6 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" -minimatch@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== - dependencies: - brace-expansion "^2.0.1" - minimatch@^3.0.4: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -1021,7 +1019,7 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimatch@^5.0.1: +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== @@ -1040,38 +1038,38 @@ mkdirp@^0.5.3: dependencies: minimist "^1.2.5" -mocha@^10.4.0: - version "10.4.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.4.0.tgz#ed03db96ee9cfc6d20c56f8e2af07b961dbae261" - integrity sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA== - dependencies: - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "8.1.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" +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 "^3.5.3" + debug "^4.3.5" + diff "^5.2.0" + escape-string-regexp "^4.0.0" + find-up "^5.0.0" + 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" + serialize-javascript "^6.0.2" + strip-json-comments "^3.1.1" + supports-color "^8.1.1" + workerpool "^6.5.1" + yargs "^16.2.0" + yargs-parser "^20.2.9" + yargs-unparser "^2.0.0" ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: +ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -1274,24 +1272,25 @@ safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -selenium-webdriver@^4.21.0: - version "4.21.0" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.21.0.tgz#d38aebfc34770421a880afcfdb7bd8fe85ce9174" - integrity sha512-WaEJHZjOWNth1QG5FEpxpREER0qptZBMonFU6GtAqdCNLJVxbtC3E7oS/I/+Q1sf1W032Wg0Ebk+m46lANOXyQ== +selenium-webdriver@^4.24.1: + version "4.24.1" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.24.1.tgz#4315214420cc26dddaa21ae26863dd452aec2829" + integrity sha512-fcK5BTI/54cSqIhiVtrd9li1YL6LW109yIwuVw6V+FlVE6y4riGiX2qdZxVzHq+sm2TJyps+D2sjzXrpDZe1Og== dependencies: + "@bazel/runfiles" "^5.8.1" jszip "^3.10.1" tmp "^0.2.3" - ws ">=8.16.0" + ws "^8.18.0" semver@^5.3.0: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== +serialize-javascript@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== dependencies: randombytes "^2.1.0" @@ -1388,18 +1387,11 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-json-comments@3.1.1: +strip-json-comments@^3.1.1: version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - supports-color@^5.3.0: version "5.5.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" @@ -1414,6 +1406,13 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + tcp-port-used@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/tcp-port-used/-/tcp-port-used-1.0.2.tgz#9652b7436eb1f4cfae111c79b558a25769f6faea" @@ -1484,15 +1483,15 @@ tsutils@^2.29.0: dependencies: tslib "^1.8.1" -typescript@^5.4.5: - version "5.4.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" - integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== +typescript@^5.6.2: + version "5.6.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0" + integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw== -undici-types@~5.26.4: - version "5.26.5" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" - integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.19.2: + 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" @@ -1528,10 +1527,10 @@ which-typed-array@^1.1.2: has-symbols "^1.0.1" is-typed-array "^1.1.3" -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== +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@^7.0.0: version "7.0.0" @@ -1547,29 +1546,24 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@>=8.16.0: - version "8.17.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.0.tgz#d145d18eca2ed25aaf791a183903f7be5e295fea" - integrity sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow== +ws@^8.18.0: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: +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: +yargs-unparser@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== dependencies: camelcase "^6.0.0" @@ -1577,7 +1571,7 @@ yargs-unparser@2.0.0: flat "^5.0.2" is-plain-obj "^2.1.0" -yargs@16.2.0: +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== diff --git a/ui/package.json b/ui/package.json index a7ec12f6d0071..e5b5b0a874a47 100644 --- a/ui/package.json +++ b/ui/package.json @@ -69,6 +69,7 @@ "@babel/preset-env": "^7.7.1", "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.7.2", + "@codecov/webpack-plugin": "^0.0.1-beta.10", "@eslint/js": "^9.1.1", "@types/classnames": "^2.2.3", "@types/cookie": "^0.5.1", @@ -79,7 +80,7 @@ "@types/js-yaml": "^4.0.9", "@types/lodash-es": "^4.17.6", "@types/minimatch": "^3.0.3", - "@types/node": "20.6.3", + "@types/node": "20.14.12", "@types/prop-types": "^15.7.5", "@types/react": "^16.8.5", "@types/react-autocomplete": "^1.8.10", @@ -121,9 +122,9 @@ "ts-node": "10.9.2", "typescript": "^4.9.5", "typescript-eslint": "^7.8.0", - "webpack": "^5.84.1", + "webpack": "^5.94.0", "webpack-cli": "^4.9.2", "webpack-dev-server": "^4.7.4", - "yarn": "^1.22.21" + "yarn": "^1.22.22" } } diff --git a/ui/src/app/app.tsx b/ui/src/app/app.tsx index fb52e54e03ddc..7a9bfb21635bb 100644 --- a/ui/src/app/app.tsx +++ b/ui/src/app/app.tsx @@ -19,6 +19,7 @@ import {Banner} from './ui-banner/ui-banner'; import userInfo from './user-info'; import {AuthSettings} from './shared/models'; import {PKCEVerification} from './login/components/pkce-verify'; +import {SystemLevelExtension} from './shared/services/extensions-service'; services.viewPreferences.init(); const bases = document.getElementsByTagName('base'); @@ -134,6 +135,7 @@ export class App extends React.Component< this.navigationManager = new NavigationManager(history); this.navItems = navItems; this.routes = routes; + services.extensions.addEventListener('systemLevel', this.onAddSystemLevelExtension.bind(this)); } public async componentDidMount() { @@ -162,31 +164,7 @@ export class App extends React.Component< document.head.appendChild(link); } - const systemExtensions = services.extensions.getSystemExtensions(); - const extendedNavItems = this.navItems; - const extendedRoutes = this.routes; - for (const extension of systemExtensions) { - extendedNavItems.push({ - title: extension.title, - path: extension.path, - iconClassName: `fa ${extension.icon}` - }); - const component = () => ( - <> - - {extension.title} - Argo CD - - - - - - ); - extendedRoutes[extension.path] = { - component: component as React.ComponentType> - }; - } - - this.setState({...this.state, navItems: extendedNavItems, routes: extendedRoutes, extensionsLoaded: true, authSettings}); + this.setState({...this.state, navItems: this.navItems, routes: this.routes, extensionsLoaded: false, authSettings}); } public render() { @@ -263,4 +241,28 @@ export class App extends React.Component< public getChildContext() { return {history, apis: {popup: this.popupManager, notifications: this.notificationsManager, navigation: this.navigationManager}}; } + + private onAddSystemLevelExtension(extension: SystemLevelExtension) { + const extendedNavItems = this.navItems; + const extendedRoutes = this.routes; + extendedNavItems.push({ + title: extension.title, + path: extension.path, + iconClassName: `fa ${extension.icon}` + }); + const component = () => ( + <> + + {extension.title} - Argo CD + + + + + + ); + extendedRoutes[extension.path] = { + component: component as React.ComponentType> + }; + 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 10f05e4cf80fe..f580fd6f66b35 100644 --- a/ui/src/app/applications/components/__snapshots__/utils.test.tsx.snap +++ b/ui/src/app/applications/components/__snapshots__/utils.test.tsx.snap @@ -50,7 +50,7 @@ exports[`ComparisonStatusIcon.Unknown 1`] = ` exports[`HealthStatusIcon.Degraded 1`] = ` { + debouncedOnAppChanged.cancel(); + }; + }, [debouncedOnAppChanged]); function normalizeTypeFields(formApi: FormApi, type: models.AppSourceType) { const appToNormalize = formApi.getFormState().values; diff --git a/ui/src/app/applications/components/application-deployment-history/application-deployment-history-details.tsx b/ui/src/app/applications/components/application-deployment-history/application-deployment-history-details.tsx new file mode 100644 index 0000000000000..e98f46fc60e06 --- /dev/null +++ b/ui/src/app/applications/components/application-deployment-history/application-deployment-history-details.tsx @@ -0,0 +1,125 @@ +import * as moment from 'moment'; +import * as React from 'react'; +import * as models from '../../../shared/models'; +import './application-deployment-history.scss'; +import {DataLoader} from 'argo-ui'; +import {Revision} from '../../../shared/components'; +import {services} from '../../../shared/services'; +import {ApplicationParameters} from '../application-parameters/application-parameters'; +import {RevisionMetadataRows} from './revision-metadata-rows'; + +type props = { + app: models.Application; + info: models.RevisionHistory; + index: number; +}; + +export const ApplicationDeploymentHistoryDetails = ({app, info, index}: props) => { + const deployments = (app.status.history || []).slice().reverse(); + const recentDeployments = deployments.map((info, i) => { + const nextDeployedAt = i === 0 ? null : deployments[i - 1].deployedAt; + const runEnd = nextDeployedAt ? moment(nextDeployedAt) : moment(); + return {...info, nextDeployedAt, durationMs: runEnd.diff(moment(info.deployedAt)) / 1000}; + }); + + const [showParameterDetails, setShowParameterDetails] = React.useState(Boolean); + + return ( + <> + {info.sources === undefined ? ( + +
    +
    +
    Revision:
    +
    + +
    +
    +
    + + + + {showParameterDetails && ( + services.repos.appDetails(src, src.appName, app.spec.project, 0, recentDeployments[index].id)}> + {(details: models.RepoAppDetails) => ( +
    + +
    + )} +
    + )} +
    + ) : ( + info.sources.map((source, i) => ( + + {i > 0 ?
    : null} +
    +
    +
    Revision:
    +
    + +
    +
    +
    + + + + {showParameterDetails && ( + services.repos.appDetails(src, src.appName, app.spec.project, i, recentDeployments[index].id)}> + {(details: models.RepoAppDetails) => ( +
    + +
    + )} +
    + )} + + )) + )} + + ); +}; diff --git a/ui/src/app/applications/components/application-deployment-history/application-deployment-history.scss b/ui/src/app/applications/components/application-deployment-history/application-deployment-history.scss index b370878a36520..abacf037f48e5 100644 --- a/ui/src/app/applications/components/application-deployment-history/application-deployment-history.scss +++ b/ui/src/app/applications/components/application-deployment-history/application-deployment-history.scss @@ -3,7 +3,6 @@ .application-deployment-history { &__item { - cursor: pointer; position: relative; @include themify($themes) { background: themed('background-2'); @@ -34,6 +33,10 @@ right: 1em; } + &__show-parameter-details { + margin: 20px 0px; + } + .white-box { margin-top: 1em; padding: 0; diff --git a/ui/src/app/applications/components/application-deployment-history/application-deployment-history.tsx b/ui/src/app/applications/components/application-deployment-history/application-deployment-history.tsx index 2e4514821d0d0..69adefe598216 100644 --- a/ui/src/app/applications/components/application-deployment-history/application-deployment-history.tsx +++ b/ui/src/app/applications/components/application-deployment-history/application-deployment-history.tsx @@ -1,22 +1,18 @@ -import {DataLoader, DropDownMenu, Duration} from 'argo-ui'; +import {DropDownMenu, Duration} from 'argo-ui'; import {InitiatedBy} from './initiated-by'; import * as moment from 'moment'; import * as React from 'react'; -import {Revision, Timestamp} from '../../../shared/components'; +import {Timestamp} from '../../../shared/components'; import * as models from '../../../shared/models'; -import {services} from '../../../shared/services'; -import {ApplicationParameters} from '../application-parameters/application-parameters'; -import {RevisionMetadataRows} from './revision-metadata-rows'; import './application-deployment-history.scss'; +import {ApplicationDeploymentHistoryDetails} from './application-deployment-history-details'; export const ApplicationDeploymentHistory = ({ app, rollbackApp, - selectedRollbackDeploymentIndex, selectDeployment }: { app: models.Application; - selectedRollbackDeploymentIndex: number; rollbackApp: (info: models.RevisionHistory) => any; selectDeployment: (index: number) => any; }) => { @@ -26,6 +22,7 @@ export const ApplicationDeploymentHistory = ({ const runEnd = nextDeployedAt ? moment(nextDeployedAt) : moment(); return {...info, nextDeployedAt, durationMs: runEnd.diff(moment(info.deployedAt)) / 1000}; }); + return (
    {recentDeployments.map((info, index) => ( @@ -75,85 +72,8 @@ export const ApplicationDeploymentHistory = ({
    - {selectedRollbackDeploymentIndex === index ? ( - info.sources === undefined ? ( - -
    -
    -
    Revision:
    -
    - -
    -
    -
    - - services.repos.appDetails(src, src.appName, app.spec.project, 0, recentDeployments[index].id)}> - {(details: models.RepoAppDetails) => ( -
    - -
    - )} -
    -
    - ) : ( - info.sources.map((source, i) => ( - - {i > 0 ?
    : null} -
    -
    -
    Revision:
    -
    - -
    -
    -
    - - services.repos.appDetails(src, src.appName, app.spec.project, i, recentDeployments[index].id)}> - {(details: models.RepoAppDetails) => ( -
    - -
    - )} -
    - - )) - ) - ) : null} +
    ))} diff --git a/ui/src/app/applications/components/application-details/application-details-app-dropdown.tsx b/ui/src/app/applications/components/application-details/application-details-app-dropdown.tsx index 7ada4d6a66707..905785765540c 100644 --- a/ui/src/app/applications/components/application-details/application-details-app-dropdown.tsx +++ b/ui/src/app/applications/components/application-details/application-details-app-dropdown.tsx @@ -34,7 +34,7 @@ export const ApplicationsDetailsAppDropdown = (props: {appName: string}) => { } /> - services.applications.list([], {fields: ['items.metadata.name']})}> + services.applications.list([], {fields: ['items.metadata.name', 'items.metadata.namespace']})}> {apps => apps.items .filter(app => { @@ -42,7 +42,7 @@ export const ApplicationsDetailsAppDropdown = (props: {appName: string}) => { }) .slice(0, 100) // take top 100 results after filtering to avoid performance issues .map(app => ( -
  • ctx.navigation.goto(`/applications/${app.metadata.name}`)}> +
  • ctx.navigation.goto(`/applications/${app.metadata.namespace}/${app.metadata.name}`)}> {app.metadata.name} {app.metadata.name === props.appName && ' (current)'}
  • )) diff --git a/ui/src/app/applications/components/application-details/application-details.tsx b/ui/src/app/applications/components/application-details/application-details.tsx index 53e9a9d77914f..c364e939054fb 100644 --- a/ui/src/app/applications/components/application-details/application-details.tsx +++ b/ui/src/app/applications/components/application-details/application-details.tsx @@ -30,7 +30,7 @@ import {ApplicationsDetailsAppDropdown} from './application-details-app-dropdown import {useSidebarTarget} from '../../../sidebar/sidebar'; import './application-details.scss'; -import {AppViewExtension, StatusPanelExtension} from '../../../shared/services/extensions-service'; +import {TopBarActionMenuExt, AppViewExtension, StatusPanelExtension} from '../../../shared/services/extensions-service'; interface ApplicationDetailsState { page: number; @@ -44,6 +44,8 @@ interface ApplicationDetailsState { extensionsMap?: {[key: string]: AppViewExtension}; statusExtensions?: StatusPanelExtension[]; statusExtensionsMap?: {[key: string]: StatusPanelExtension}; + topBarActionMenuExts?: TopBarActionMenuExt[]; + topBarActionMenuExtsMap?: {[key: string]: TopBarActionMenuExt}; } interface FilterInput { @@ -94,6 +96,11 @@ export class ApplicationDetails extends React.Component { statusExtensionsMap[ext.id] = ext; }); + const topBarActionMenuExts = services.extensions.getActionMenuExtensions(); + const topBarActionMenuExtsMap: {[key: string]: TopBarActionMenuExt} = {}; + topBarActionMenuExts.forEach(ext => { + topBarActionMenuExtsMap[ext.id] = ext; + }); this.state = { page: 0, groupedResources: [], @@ -104,7 +111,9 @@ export class ApplicationDetails extends React.Component { + const getContentForChart = ( + aRevision: string, + aSourceIndex: number | null, + aVersionId: number | null, + indx: number, + aSource: models.ApplicationSource, + sourceHeader?: JSX.Element + ) => { const showChartNonMetadataInfo = (aRevision: string, aRepoUrl: string) => { return ( <> @@ -366,9 +382,9 @@ export class ApplicationDetails extends React.Component{cont}; } else if (application.spec.source) { if (source.chart) { - cont.push(getContentForChart(revision, 0, 0, 0, source)); + cont.push(getContentForChart(revision, null, null, 0, source)); } else { - cont.push(getContentForNonChart(revision, 0, getAppCurrentVersion(application), 0, source)); + cont.push(getContentForNonChart(revision, null, getAppCurrentVersion(application), 0, source)); } return <>{cont}; } else { @@ -393,7 +409,7 @@ export class ApplicationDetails extends React.Component Loading...} input={this.props.match.params.name} load={name => - combineLatest([this.loadAppInfo(name, this.appNamespace), services.viewPreferences.getPreferences(), q]).pipe( + combineLatest([this.loadAppInfo(name, this.props.match.params.appnamespace), services.viewPreferences.getPreferences(), q]).pipe( map(items => { const application = items[0].application; const pref = items[1].appDetails; @@ -560,7 +576,8 @@ export class ApplicationDetails extends React.Component @@ -573,7 +590,14 @@ export class ApplicationDetails extends React.Component} ], - actionMenu: {items: this.getApplicationActionMenu(application, true)}, + actionMenu: { + items: [ + ...this.getApplicationActionMenu(application, true), + ...(this.state.topBarActionMenuExts + ?.filter(ext => ext.shouldDisplay?.(application)) + .map(ext => this.renderActionMenuItem(ext, tree, application, this.setExtensionPanelVisible)) || []) + ] + }, tools: (
    @@ -818,6 +842,7 @@ export class ApplicationDetails extends React.Component this.updateApp(app, query)} selectedNode={selectedNode} + appCxt={this.context} tab={tab} /> @@ -830,7 +855,6 @@ export class ApplicationDetails extends React.Component -1 && ( this.rollbackApplication(info, application)} selectDeployment={i => this.setRollbackPanelVisible(i)} /> @@ -859,10 +883,16 @@ export class ApplicationDetails extends React.Component this.setExtensionPanelVisible('')}> - {this.selectedExtension !== '' && activeExtension && activeExtension.flyout && ( - + {this.selectedExtension !== '' && activeStatusExt?.flyout && } + + this.setExtensionPanelVisible('')}> + {this.selectedExtension !== '' && activeTopBarActionMenuExt?.flyout && ( + )} @@ -874,7 +904,13 @@ export class ApplicationDetails extends React.Component ); } - + private renderActionMenuItem(ext: TopBarActionMenuExt, tree: appModels.ApplicationTree, application: appModels.Application, showExtension?: (id: string) => any): any { + return { + action: () => this.setExtensionPanelVisible(ext.id), + title: showExtension && showExtension(ext.id)} />, + iconClassName: ext.iconClassName + }; + } private getApplicationActionMenu(app: appModels.Application, needOverlapLabelOnNarrowScreen: boolean) { const refreshing = app.metadata.annotations && app.metadata.annotations[appModels.AnnotationRefreshKey]; const fullName = AppUtils.nodeKey({group: 'argoproj.io', kind: app.kind, name: app.metadata.name, namespace: app.metadata.namespace}); diff --git a/ui/src/app/applications/components/application-details/application-resource-filter.tsx b/ui/src/app/applications/components/application-details/application-resource-filter.tsx index a3d99f92488f3..242189ff0a9ef 100644 --- a/ui/src/app/applications/components/application-details/application-resource-filter.tsx +++ b/ui/src/app/applications/components/application-details/application-resource-filter.tsx @@ -145,7 +145,7 @@ export const Filters = (props: FiltersProps) => { {ResourceFilter({ label: 'HEALTH STATUS', prefix: 'health', - options: ['Healthy', 'Progressing', 'Degraded', 'Suspended', 'Missing', 'Unknown'].map(label => ({ + options: ['Progressing', 'Suspended', 'Healthy', 'Degraded', 'Missing', 'Unknown'].map(label => ({ label, count: getOptionCount(label, 'Health'), icon: diff --git a/ui/src/app/applications/components/application-fullscreen-logs/application-fullscreen-logs.scss b/ui/src/app/applications/components/application-fullscreen-logs/application-fullscreen-logs.scss index c735215f0cae8..80b2312a7b3d3 100644 --- a/ui/src/app/applications/components/application-fullscreen-logs/application-fullscreen-logs.scss +++ b/ui/src/app/applications/components/application-fullscreen-logs/application-fullscreen-logs.scss @@ -10,4 +10,9 @@ height: 100%; padding: 20px 30px; background-color: $argo-color-gray-3; -} + + .theme-dark & { + background-color: #28292a; + color: #fff; + } +} \ No newline at end of file diff --git a/ui/src/app/applications/components/application-node-info/application-node-info.tsx b/ui/src/app/applications/components/application-node-info/application-node-info.tsx index edd787e0240c1..4d1f2720bf9a9 100644 --- a/ui/src/app/applications/components/application-node-info/application-node-info.tsx +++ b/ui/src/app/applications/components/application-node-info/application-node-info.tsx @@ -22,17 +22,18 @@ const RenderContainerState = (props: {container: any}) => { return (
    - {props.container.state?.running && ( + {props.container.state?.running ? ( - )} - {(props.container.state.terminated && props.container.state.terminated?.exitCode !== 0) || + ) : ( + (props.container.state.terminated && props.container.state.terminated?.exitCode !== 0) || (lastState && lastState?.exitCode !== 0 && ( - ))} + )) + )} {props.container.name}
    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 57ec1f122f915..f6284258b238e 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} 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,6 +15,7 @@ interface Props { application: models.Application; operationState: models.OperationState; } +const buildResourceUniqueId = (res: Omit) => `${res.group}-${res.kind}-${res.version}-${res.namespace}-${res.name}`; const Filter = (props: {filters: string[]; setFilters: (f: string[]) => void; options: string[]; title: string; style?: React.CSSProperties}) => { const {filters, setFilters, options, title, style} = props; @@ -126,18 +127,60 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl } } const [filters, setFilters] = React.useState([]); + const [healthFilters, setHealthFilters] = React.useState([]); + const Healths = Object.keys(models.HealthStatuses); const Statuses = Object.keys(models.ResultCodes); const OperationPhases = Object.keys(models.OperationPhases); // const syncPhases = ['PreSync', 'Sync', 'PostSync', 'SyncFail']; // const hookPhases = ['Running', 'Terminating', 'Failed', 'Error', 'Succeeded']; + const resourceHealth = application.status.resources.reduce( + (acc, res) => { + if (res.health) { + acc[buildResourceUniqueId(res)] = res.health; + } - let filtered: models.ResourceResult[] = []; - if (syncResult) { - if (syncResult.resources && syncResult.resources.length > 0) { - filtered = syncResult.resources.filter(r => filters.length === 0 || filters.includes(getStatus(r))); + return acc; + }, + {} as Record + ); + + const combinedHealthSyncResult: models.SyncResourceResult[] = syncResult?.resources?.map(syncResultItem => { + const uniqueResourceName = buildResourceUniqueId(syncResultItem); + + const healthStatus = resourceHealth[uniqueResourceName]; + + const syncResultWithHealth: models.SyncResourceResult = { + ...syncResultItem + }; + + if (healthStatus) { + syncResultWithHealth.health = healthStatus; } + + return syncResultWithHealth; + }); + let filtered: models.SyncResourceResult[] = []; + + if (combinedHealthSyncResult && combinedHealthSyncResult.length > 0) { + filtered = combinedHealthSyncResult.filter(r => { + if (filters.length === 0 && healthFilters.length === 0) { + return true; + } + + let pass = true; + if (filters.length !== 0 && !filters.includes(getStatus(r))) { + pass = false; + } + + if (pass && healthFilters.length !== 0 && !healthFilters.includes(r.health?.status)) { + pass = false; + } + + return pass; + }); } + return (
    @@ -155,6 +198,7 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl
    +
    @@ -166,6 +210,7 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl
    NAMESPACE
    NAME
    STATUS
    +
    HEALTH
    HOOK
    MESSAGE
    @@ -189,6 +234,16 @@ export const ApplicationOperationState: React.StatelessComponent = ({appl
    {getStatus(resource)}
    +
    + {resource.health ? ( +
    + {resource.health?.status} + {resource.health.message && } +
    + ) : ( + <>{'-'} + )} +
    {resource.hookType}
    diff --git a/ui/src/app/applications/components/application-parameters/application-parameters-source.tsx b/ui/src/app/applications/components/application-parameters/application-parameters-source.tsx index 4acbcdd82fcf6..2d494af941d3d 100644 --- a/ui/src/app/applications/components/application-parameters/application-parameters-source.tsx +++ b/ui/src/app/applications/components/application-parameters/application-parameters-source.tsx @@ -24,8 +24,10 @@ export interface ApplicationParametersPanelProps { viewBottom?: string | React.ReactNode; editTop?: (formApi: FormApi) => React.ReactNode; editBottom?: (formApi: FormApi) => React.ReactNode; + numberOfSources?: number; noReadonlyMode?: boolean; collapsible?: boolean; + deleteSource: () => void; } interface ApplicationParametersPanelState { @@ -64,9 +66,11 @@ export class ApplicationParametersSource extends React.Component { this.setState({editBottom: editClicked}); }} + deleteSource={this.props.deleteSource} /> {this.props.itemsTop && ( diff --git a/ui/src/app/applications/components/application-parameters/application-parameters.scss b/ui/src/app/applications/components/application-parameters/application-parameters.scss index e49945dc85324..d40c88ac05340 100644 --- a/ui/src/app/applications/components/application-parameters/application-parameters.scss +++ b/ui/src/app/applications/components/application-parameters/application-parameters.scss @@ -42,6 +42,10 @@ right: 1em; } + .source-panel-buttons { + margin-bottom: 10px; + } + .argo-field { line-height: 1.15; } @@ -64,6 +68,10 @@ .select { padding-bottom: 0; + + .select__value{ + min-height: 28px; + } } .row.application-retry-options { 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 3961b61d26656..ec6d67dae46a1 100644 --- a/ui/src/app/applications/components/application-parameters/application-parameters.tsx +++ b/ui/src/app/applications/components/application-parameters/application-parameters.tsx @@ -1,4 +1,4 @@ -import {AutocompleteField, DataLoader, FormField, FormSelect, getNestedField} from 'argo-ui'; +import {AutocompleteField, DataLoader, ErrorNotification, FormField, FormSelect, getNestedField, NotificationType, SlidingPanel} from 'argo-ui'; import * as React from 'react'; import {FieldApi, FormApi, FormField as ReactFormField, Text, TextArea} from 'react-form'; import {cloneDeep} from 'lodash-es'; @@ -18,7 +18,8 @@ import { Revision, Repo, EditablePanel, - EditablePanelItem + EditablePanelItem, + Spinner } from '../../../shared/components'; import * as models from '../../../shared/models'; import {ApplicationSourceDirectory, Plugin} from '../../../shared/models'; @@ -27,13 +28,15 @@ import {ImageTagFieldEditor} from './kustomize'; import * as kustomize from './kustomize-image'; import {VarsInputField} from './vars-input-field'; import {concatMaps} from '../../../shared/utils'; -import {getAppDefaultSource} from '../utils'; +import {deleteSourceAction, getAppDefaultSource, helpTip} from '../utils'; import * as jsYaml from 'js-yaml'; import {RevisionFormField} from '../revision-form-field/revision-form-field'; import classNames from 'classnames'; import {ApplicationParametersSource} from './application-parameters-source'; import './application-parameters.scss'; +import {AppContext} from '../../../shared/context'; +import {SourcePanel} from './source-panel'; const TextWithMetadataField = ReactFormField((props: {metadata: {value: string}; fieldApi: FieldApi; className: string}) => { const { @@ -148,17 +151,30 @@ export const ApplicationParameters = (props: { setPageNumber?: (x: number) => any; collapsedSources?: boolean[]; handleCollapse?: (i: number, isCollapsed: boolean) => void; + appContext?: AppContext; + tempSource?: models.ApplicationSource; }) => { const app = cloneDeep(props.application); const source = getAppDefaultSource(app); // For source field const appSources = app?.spec.sources; const [removedOverrides, setRemovedOverrides] = React.useState(new Array()); const collapsible = props.collapsedSources !== undefined && props.handleCollapse !== undefined; + const [createApi, setCreateApi] = React.useState(null); + const [isAddingSource, setIsAddingSource] = React.useState(false); + const [isSavingSource, setIsSavingSource] = React.useState(false); const [appParamsDeletedState, setAppParamsDeletedState] = React.useState([]); if (app.spec.sources?.length > 0 && !props.details) { + // For multi-source case only return (
    +
    + +
    + setIsAddingSource(false)} + header={ +
    + {' '} + +
    + }> + { + setCreateApi(api); + }} + onSubmitFailure={errors => { + props.appContext.apis.notifications.show({ + content: 'Cannot add source: ' + errors.toString(), + type: NotificationType.Warning + }); + }} + updateApp={async updatedAppSource => { + setIsSavingSource(true); + props.application.spec.sources.push(updatedAppSource.spec.source); + try { + await services.applications.update(props.application); + setIsAddingSource(false); + } catch (e) { + props.application.spec.sources.pop(); + props.appContext.apis.notifications.show({ + content: , + type: NotificationType.Error + }); + } finally { + setIsSavingSource(false); + } + }} + /> +
    ); } else { - // For the other old/existings references of ApplicationParameters that have details already loaded. They are single source + // For the three other references of ApplicationParameters. They are single source. + // Create App, Add source, Rollback and History let attributes: EditablePanelItem[] = []; if (props.details) { return getEditablePanel( - gatherDetails(0, props.details, attributes, source, app, setRemovedOverrides, removedOverrides, appParamsDeletedState, setAppParamsDeletedState, false), + gatherDetails( + 0, + props.details, + attributes, + props.tempSource ? props.tempSource : source, + app, + setRemovedOverrides, + removedOverrides, + appParamsDeletedState, + setAppParamsDeletedState, + false + ), props.details ); } else { - // For single source field, for resource details where we have to do the load. + // For single source field, details page where we have to do the load to retrieve repo details return ( getSingleSource(application)}> {(details: models.RepoAppDetails) => { @@ -247,8 +328,11 @@ export const ApplicationParameters = (props: {
    )} - getSourceFromSources(application, index)}> - {(details: models.RepoAppDetails) => getEditablePanelForOneSource(details, index, source)} + getSourceFromAppSources(src, app.metadata.name, app.spec.project, index, 0)}> + {(details: models.RepoAppDetails) => getEditablePanelForOneSource(details, index, app.spec.sources[index])}
    @@ -270,10 +354,10 @@ export const ApplicationParameters = (props: { function isDefinedWithVersion(item: any) { return item !== null && item !== undefined && item.match(/:/); } - if (updatedSrc.helm && updatedSrc.helm.parameters) { + if (updatedSrc && updatedSrc.helm?.parameters) { updatedSrc.helm.parameters = updatedSrc.helm.parameters.filter(isDefined); } - if (updatedSrc.kustomize && updatedSrc.kustomize.images) { + if (updatedSrc && updatedSrc.kustomize?.images) { updatedSrc.kustomize.images = updatedSrc.kustomize.images.filter(isDefinedWithVersion); } @@ -295,7 +379,7 @@ export const ApplicationParameters = (props: { params = params.filter(param => !appParamsDeletedState.includes(param.name)); input.spec.source.plugin.parameters = params; } - if (input.spec.source.helm && input.spec.source.helm.valuesObject) { + if (input.spec.source && input.spec.source.helm?.valuesObject) { input.spec.source.helm.valuesObject = jsYaml.load(input.spec.source.helm.values); // Deserialize json input.spec.source.helm.values = ''; } @@ -303,7 +387,7 @@ export const ApplicationParameters = (props: { setRemovedOverrides(new Array()); }) } - values={((repoAppDetails.plugin || app?.spec?.source?.plugin) && cloneDeep(app)) || app} + values={((repoAppDetails?.plugin || app?.spec?.source?.plugin) && cloneDeep(app)) || app} validate={updatedApp => { const errors = {} as any; @@ -312,7 +396,7 @@ export const ApplicationParameters = (props: { errors[fieldPath] = invalid.length > 0 ? 'All fields must have name' : null; } - if (updatedApp.spec.source.helm && updatedApp.spec.source.helm.values) { + if (updatedApp.spec.source && updatedApp.spec.source.helm?.values) { const parsedValues = jsYaml.load(updatedApp.spec.source.helm.values); errors['spec.source.helm.values'] = typeof parsedValues === 'object' ? null : 'Values must be a map'; } @@ -320,12 +404,12 @@ export const ApplicationParameters = (props: { return errors; }} onModeSwitch={ - repoAppDetails.plugin && + repoAppDetails?.plugin && (() => { setAppParamsDeletedState([]); }) } - title={repoAppDetails.type.toLocaleUpperCase()} + title={repoAppDetails?.type?.toLocaleUpperCase()} items={items as EditablePanelItem[]} noReadonlyMode={props.noReadonlyMode} hasMultipleSources={false} @@ -402,7 +486,7 @@ export const ApplicationParameters = (props: { saveBottom={ props.save && (async (input: models.Application) => { - const updatedSrc = input.spec.sources[ind]; + const appSrc = input.spec.sources[ind]; function isDefined(item: any) { return item !== null && item !== undefined; @@ -411,11 +495,11 @@ export const ApplicationParameters = (props: { return item !== null && item !== undefined && item.match(/:/); } - if (updatedSrc.helm && updatedSrc.helm.parameters) { - updatedSrc.helm.parameters = updatedSrc.helm.parameters.filter(isDefined); + if (appSrc.helm && appSrc.helm.parameters) { + appSrc.helm.parameters = appSrc.helm.parameters.filter(isDefined); } - if (updatedSrc.kustomize && updatedSrc.kustomize.images) { - updatedSrc.kustomize.images = updatedSrc.kustomize.images.filter(isDefinedWithVersion); + if (appSrc.kustomize && appSrc.kustomize.images) { + appSrc.kustomize.images = appSrc.kustomize.images.filter(isDefinedWithVersion); } let params = input.spec?.sources[ind]?.plugin?.parameters; @@ -435,11 +519,11 @@ export const ApplicationParameters = (props: { } params = params.filter(param => !appParamsDeletedState.includes(param.name)); - updatedSrc.plugin.parameters = params; + appSrc.plugin.parameters = params; } - if (updatedSrc.helm && updatedSrc.helm.valuesObject) { - updatedSrc.helm.valuesObject = jsYaml.load(updatedSrc.helm.values); // Deserialize json - updatedSrc.helm.values = ''; + if (appSrc.helm && appSrc.helm.valuesObject) { + appSrc.helm.valuesObject = jsYaml.load(appSrc.helm.values); // Deserialize json + appSrc.helm.values = ''; } await props.save(input, {}); @@ -486,6 +570,10 @@ export const ApplicationParameters = (props: { itemsTop={upperPanel as EditablePanelItem[]} noReadonlyMode={props.noReadonlyMode} collapsible={collapsible} + numberOfSources={app?.spec?.sources.length} + deleteSource={() => { + deleteSourceAction(app, app.spec.sources.at(ind), props.appContext); + }} /> ); } @@ -986,17 +1074,12 @@ function gatherDetails( } // For Sources field. Get one source with index i from the list -async function getSourceFromSources(app: models.Application, i: number) { - const sources: models.ApplicationSource[] = app.spec.sources; - if (sources && i < sources.length) { - const aSource = sources[i]; - const repoDetail = await services.repos.appDetails(aSource, app.metadata.name, app.spec.project, i, 0).catch(() => ({ - type: 'Directory' as models.AppSourceType, - path: aSource.path - })); - return repoDetail; - } - return null; +async function getSourceFromAppSources(aSource: models.ApplicationSource, name: string, project: string, index: number, version: number) { + const repoDetail = await services.repos.appDetails(aSource, name, project, index, version).catch(() => ({ + type: 'Directory' as models.AppSourceType, + path: aSource.path + })); + return repoDetail; } // Delete when source field is removed diff --git a/ui/src/app/applications/components/application-parameters/source-panel.scss b/ui/src/app/applications/components/application-parameters/source-panel.scss new file mode 100644 index 0000000000000..9ee0b7c0aa785 --- /dev/null +++ b/ui/src/app/applications/components/application-parameters/source-panel.scss @@ -0,0 +1,18 @@ +@import 'node_modules/argo-ui/src/styles/config'; + +.new-source-panel { + + .checkbox-container { + margin: 0.5em ; + } + + pre { + font-family: monospace; + line-height: normal; + white-space: pre; + } + + .row.argo-form-row .columns { + padding-left: 0; + } +} diff --git a/ui/src/app/applications/components/application-parameters/source-panel.tsx b/ui/src/app/applications/components/application-parameters/source-panel.tsx new file mode 100644 index 0000000000000..8e750b6e4a9b9 --- /dev/null +++ b/ui/src/app/applications/components/application-parameters/source-panel.tsx @@ -0,0 +1,375 @@ +import {AutocompleteField, DataLoader, DropDownMenu, FormField} from 'argo-ui'; +import * as deepMerge from 'deepmerge'; +import * as React from 'react'; +import {Form, FormApi, FormErrors, Text} from 'react-form'; +import {ApplicationParameters} from '../../../applications/components/application-parameters/application-parameters'; +import {RevisionFormField} from '../../../applications/components/revision-form-field/revision-form-field'; +import {RevisionHelpIcon} from '../../../shared/components'; +import * as models from '../../../shared/models'; +import {services} from '../../../shared/services'; +import './source-panel.scss'; + +// This is similar to what is in application-create-panel.tsx. If the create panel +// is modified to support multi-source apps, then we should refactor and common these up +const appTypes = new Array<{field: string; type: models.AppSourceType}>( + {type: 'Helm', field: 'helm'}, + {type: 'Kustomize', field: 'kustomize'}, + {type: 'Directory', field: 'directory'}, + {type: 'Plugin', field: 'plugin'} +); + +// This is similar to the same function in application-create-panel.tsx. If the create panel +// is modified to support multi-source apps, then we should refactor and common these up +function normalizeAppSource(app: models.Application, type: string): boolean { + const source = app.spec.source; + // eslint-disable-next-line no-prototype-builtins + const repoType = (source.hasOwnProperty('chart') && 'helm') || 'git'; + if (repoType !== type) { + if (type === 'git') { + source.path = source.chart; + delete source.chart; + source.targetRevision = 'HEAD'; + } else { + source.chart = source.path; + delete source.path; + source.targetRevision = ''; + } + return true; + } + return false; +} + +// Use a single source app to represent the 'new source'. This panel will make use of the source field only. +// However, we need to use a template based on an Application so that we can reuse the application-parameters code +const DEFAULT_APP: Partial = { + apiVersion: 'argoproj.io/v1alpha1', + kind: 'Application', + metadata: { + name: '' + }, + spec: { + destination: { + name: '', + namespace: '', + server: '' + }, + source: { + path: '', + repoURL: '', + ref: '', + targetRevision: 'HEAD' + }, + sources: [], + project: '' + } +}; + +export const SourcePanel = (props: { + appCurrent: models.Application; + onSubmitFailure: (error: string) => any; + updateApp: (app: models.Application) => any; + getFormApi: (api: FormApi) => any; +}) => { + const [explicitPathType, setExplicitPathType] = React.useState<{path: string; type: models.AppSourceType}>(null); + const appInEdit = deepMerge(DEFAULT_APP, {}); + + function normalizeTypeFields(formApi: FormApi, type: models.AppSourceType) { + const appToNormalize = formApi.getFormState().values; + for (const item of appTypes) { + if (item.type !== type) { + delete appToNormalize.spec.source[item.field]; + } + } + formApi.setAllValues(appToNormalize); + } + + return ( + + Promise.all([services.repos.list()]).then(([reposInfo]) => ({reposInfo}))}> + {({reposInfo}) => { + const repos = reposInfo.map(info => info.repo).sort(); + return ( +
    +
    { + let samePath = false; + let sameChartVersion = false; + let pathError = null; + let chartError = null; + if (a.spec.source.repoURL && a.spec.source.path) { + props.appCurrent.spec.sources.forEach(source => { + if (source.repoURL === a.spec.source.repoURL && source.path === a.spec.source.path) { + samePath = true; + pathError = 'Provided path in the selected repository URL was already added to this multi-source application'; + } + }); + } + if (a.spec.source.repoURL && a.spec.source.chart) { + props.appCurrent.spec.sources.forEach(source => { + if ( + source.repoURL === a.spec.source.repoURL && + source.chart === a.spec.source.chart && + source.targetRevision === a.spec.source.targetRevision + ) { + sameChartVersion = true; + chartError = + 'Version ' + + source.targetRevision + + ' of chart ' + + source.chart + + ' from the selected repository was already added to this multi-source application'; + } + }); + } + if (!samePath) { + if (!a.spec.source.path && !a.spec.source.chart && !a.spec.source.ref) { + pathError = 'Path or Ref is required'; + } + } + if (!sameChartVersion) { + if (!a.spec.source.chart && !a.spec.source.path && !a.spec.source.ref) { + chartError = 'Chart is required'; + } + } + return { + 'spec.source.repoURL': !a.spec.source.repoURL && 'Repository URL is required', + // eslint-disable-next-line no-prototype-builtins + 'spec.source.targetRevision': !a.spec.source.targetRevision && a.spec.source.hasOwnProperty('chart') && 'Version is required', + 'spec.source.path': pathError, + 'spec.source.chart': chartError + }; + }} + defaultValues={appInEdit} + onSubmitFailure={(errors: FormErrors) => { + let errorString: string = ''; + let i = 0; + for (const key in errors) { + if (errors[key]) { + i++; + errorString = errorString.concat(i + '. ' + errors[key] + ' '); + } + } + props.onSubmitFailure(errorString); + }} + onSubmit={values => { + props.updateApp(values as models.Application); + }} + getApi={props.getFormApi}> + {api => { + // eslint-disable-next-line no-prototype-builtins + const repoType = (api.getFormState().values.spec.source.hasOwnProperty('chart') && 'helm') || 'git'; + const repoInfo = reposInfo.find(info => info.repo === api.getFormState().values.spec.source.repoURL); + if (repoInfo) { + normalizeAppSource(appInEdit, repoInfo.type || 'git'); + } + const sourcePanel = () => ( +
    +

    SOURCE

    +
    +
    + +
    +
    +
    + {(repoInfo && ( + + {(repoInfo.type || 'git').toUpperCase()} + + )) || ( + ( +

    + {repoType.toUpperCase()} +

    + )} + items={['git', 'helm'].map((type: 'git' | 'helm') => ({ + title: type.toUpperCase(), + action: () => { + if (repoType !== type) { + const updatedApp = api.getFormState().values as models.Application; + if (normalizeAppSource(updatedApp, type)) { + api.setAllValues(updatedApp); + } + } + } + }))} + /> + )} +
    +
    +
    + {(repoType === 'git' && ( + + +
    + + (src.repoURL && + (await services.repos + .apps(src.repoURL, src.revision, appInEdit.metadata.name, props.appCurrent.spec.project) + .then(apps => Array.from(new Set(apps.map(item => item.path))).sort()) + .catch(() => new Array()))) || + new Array() + }> + {(apps: string[]) => ( + + )} + +
    +
    + +
    +
    + )) || ( + + (src.repoURL && services.repos.charts(src.repoURL).catch(() => new Array())) || + new Array() + }> + {(charts: models.HelmChart[]) => { + const selectedChart = charts.find(chart => chart.name === api.getFormState().values.spec.source.chart); + return ( +
    +
    + chart.name), + filterSuggestions: true + }} + /> +
    +
    + + +
    +
    + ); + }} +
    + )} +
    + ); + + const typePanel = () => ( + { + if (src.repoURL && src.targetRevision && (src.path || src.chart)) { + return services.repos.appDetails(src, src.appName, props.appCurrent.spec.project, 0, 0).catch(() => ({ + type: 'Directory', + details: {} + })); + } else { + return { + type: 'Directory', + details: {} + }; + } + }}> + {(details: models.RepoAppDetails) => { + const type = (explicitPathType && explicitPathType.path === appInEdit.spec.source.path && explicitPathType.type) || details.type; + if (details.type !== type) { + switch (type) { + case 'Helm': + details = { + type, + path: details.path, + helm: {name: '', valueFiles: [], path: '', parameters: [], fileParameters: []} + }; + break; + case 'Kustomize': + details = {type, path: details.path, kustomize: {path: ''}}; + break; + case 'Plugin': + details = {type, path: details.path, plugin: {name: '', env: []}}; + break; + // Directory + default: + details = {type, path: details.path, directory: {}}; + break; + } + } + return ( + + ( +

    + {type} +

    + )} + items={appTypes.map(item => ({ + title: item.type, + action: () => { + setExplicitPathType({type: item.type, path: appInEdit.spec.source.path}); + normalizeTypeFields(api, item.type); + } + }))} + /> + { + api.setAllValues(updatedApp); + }} + /> +
    + ); + }} +
    + ); + + return ( + + {sourcePanel()} + + {typePanel()} + + ); + }} + +
    + ); + }} +
    +
    + ); +}; diff --git a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx index 0e1cfb9a00783..0e0dfb9ac12a4 100644 --- a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx +++ b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx @@ -1191,6 +1191,58 @@ export const ApplicationResourceTree = (props: ApplicationResourceTreeProps) => }); const graphNodes = graph.nodes(); const size = getGraphSize(graphNodes.map(id => graph.node(id))); + + const resourceTreeRef = React.useRef(); + + const graphMoving = React.useRef({ + enable: false, + x: 0, + y: 0 + }); + + const onGraphDragStart: React.PointerEventHandler = e => { + if (e.target !== resourceTreeRef.current) { + return; + } + + if (!resourceTreeRef.current?.parentElement) { + return; + } + + graphMoving.current.enable = true; + graphMoving.current.x = e.clientX; + graphMoving.current.y = e.clientY; + }; + + const onGraphDragMoving: React.PointerEventHandler = e => { + if (!graphMoving.current.enable) { + return; + } + + if (!resourceTreeRef.current?.parentElement) { + return; + } + + const graphContainer = resourceTreeRef.current?.parentElement; + + const currentPositionX = graphContainer.scrollLeft; + const currentPositionY = graphContainer.scrollTop; + + const scrollLeft = currentPositionX + graphMoving.current.x - e.clientX; + const scrollTop = currentPositionY + graphMoving.current.y - e.clientY; + + graphContainer.scrollTo(scrollLeft, scrollTop); + + graphMoving.current.x = e.clientX; + graphMoving.current.y = e.clientY; + }; + + const onGraphDragEnd: React.PointerEventHandler = e => { + if (graphMoving.current.enable) { + graphMoving.current.enable = false; + e.preventDefault(); + } + }; return ( (graphNodes.length === 0 && ( @@ -1199,6 +1251,11 @@ export const ApplicationResourceTree = (props: ApplicationResourceTreeProps) => )) || (
    {graphNodes.map(key => { diff --git a/ui/src/app/applications/components/application-resources-diff/individual-diff-section.tsx b/ui/src/app/applications/components/application-resources-diff/individual-diff-section.tsx index 7d82659cbfdc7..8104e7e232b23 100644 --- a/ui/src/app/applications/components/application-resources-diff/individual-diff-section.tsx +++ b/ui/src/app/applications/components/application-resources-diff/individual-diff-section.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import {useState} from 'react'; -import {Diff, Hunk} from 'react-diff-view'; +import {Diff, Hunk, tokenize, markEdits} from 'react-diff-view'; import 'react-diff-view/style/index.css'; import './application-resources-diff.scss'; @@ -15,6 +15,12 @@ export interface IndividualDiffSectionProps { export const IndividualDiffSection = (props: IndividualDiffSectionProps) => { const {file, showPath, whiteBox, viewType} = props; const [collapsed, setCollapsed] = useState(false); + const options = { + highlight: false, + enhancers: [markEdits(file.hunks, {type: 'block'})] + }; + const token = tokenize(file.hunks, options); + return (
    {showPath && ( @@ -24,7 +30,7 @@ export const IndividualDiffSection = (props: IndividualDiffSectionProps) => {

    )} {!collapsed && ( - + {(hunks: any) => hunks.map((hunk: any) => )} )} diff --git a/ui/src/app/applications/components/application-summary/application-summary.scss b/ui/src/app/applications/components/application-summary/application-summary.scss index 408feb30da01c..ee0ae6cacd171 100644 --- a/ui/src/app/applications/components/application-summary/application-summary.scss +++ b/ui/src/app/applications/components/application-summary/application-summary.scss @@ -42,8 +42,23 @@ right: 1em; } + &__links-rows { + margin: 10px 0; + } + + &__links-row { + display: flex; + align-items: center; + height: 35px; + } + .argo-field { line-height: 1.15; + button { + @include themify($themes) { + color: themed('text-1'); + } + } } .white-box__details p { 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 1747e943af69f..174c66c5dc196 100644 --- a/ui/src/app/applications/components/application-summary/application-summary.tsx +++ b/ui/src/app/applications/components/application-summary/application-summary.tsx @@ -263,7 +263,12 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { view: app.spec.revisionHistoryLimit, edit: (formApi: FormApi) => (
    - +
    - {urls - .map(item => item.split('|')) - .map((parts, i) => ( - 1 ? parts[1] : parts[0]} target='__blank'> - {parts[0]}   - - ))} +
    + {urls + .map(item => item.split('|')) + .map((parts, i) => ( + + ))} +
    ) }); diff --git a/ui/src/app/applications/components/application-summary/edit-notification-subscriptions.tsx b/ui/src/app/applications/components/application-summary/edit-notification-subscriptions.tsx index d1b2d597079a1..771204edc05f5 100644 --- a/ui/src/app/applications/components/application-summary/edit-notification-subscriptions.tsx +++ b/ui/src/app/applications/components/application-summary/edit-notification-subscriptions.tsx @@ -10,8 +10,7 @@ import './edit-notification-subscriptions.scss'; export const NOTIFICATION_SUBSCRIPTION_ANNOTATION_PREFIX = 'notifications.argoproj.io/subscribe'; -// eslint-disable-next-line no-useless-escape -export const NOTIFICATION_SUBSCRIPTION_ANNOTATION_REGEX = new RegExp(`^notifications\.argoproj\.io\/subscribe\.[a-zA-Z-]{1,100}\.[a-zA-Z-]{1,100}$`); +export const NOTIFICATION_SUBSCRIPTION_ANNOTATION_REGEX = new RegExp(`^notifications\\.argoproj\\.io/subscribe\\.[a-zA-Z-]{1,100}\\.[a-zA-Z-]{1,100}$`); export type TNotificationSubscription = { trigger: string; diff --git a/ui/src/app/applications/components/application-summary/edit-notification-subscriptsions.test.ts b/ui/src/app/applications/components/application-summary/edit-notification-subscriptsions.test.ts new file mode 100644 index 0000000000000..8cfc93bb29a06 --- /dev/null +++ b/ui/src/app/applications/components/application-summary/edit-notification-subscriptsions.test.ts @@ -0,0 +1,6 @@ +import {NOTIFICATION_SUBSCRIPTION_ANNOTATION_REGEX} from "./edit-notification-subscriptions"; + +test('rejects incorrect annotations', () => { + expect(NOTIFICATION_SUBSCRIPTION_ANNOTATION_REGEX.test('notifications_argoproj_io/subscribe_a_b')).toEqual(false) + expect(NOTIFICATION_SUBSCRIPTION_ANNOTATION_REGEX.test('notifications.argoproj.io/subscribe.a.b')).toEqual(true) +}) diff --git a/ui/src/app/applications/components/applications-list/applications-table.tsx b/ui/src/app/applications/components/applications-list/applications-table.tsx index a024059e16e5b..4952a0f08fb9a 100644 --- a/ui/src/app/applications/components/applications-list/applications-table.tsx +++ b/ui/src/app/applications/components/applications-list/applications-table.tsx @@ -59,7 +59,7 @@ export const ApplicationsTable = (props: { applications-list__entry applications-list__entry--health-${app.status.health.status} ${selectedApp === i ? 'applications-tiles__selected' : ''}`}>
    ctx.navigation.goto(`/applications/${app.metadata.namespace}/${app.metadata.name}`, {}, {event: e})}> + onClick={e => ctx.navigation.goto(`applications/${app.metadata.namespace}/${app.metadata.name}`, {}, {event: e})}>
    diff --git a/ui/src/app/applications/components/applications-list/applications-tiles.tsx b/ui/src/app/applications/components/applications-list/applications-tiles.tsx index 3467d3b952a87..ce27238b87d60 100644 --- a/ui/src/app/applications/components/applications-list/applications-tiles.tsx +++ b/ui/src/app/applications/components/applications-list/applications-tiles.tsx @@ -118,7 +118,7 @@ export const ApplicationTiles = ({applications, syncApplication, refreshApplicat
    - ctx.navigation.goto(`/applications/${app.metadata.namespace}/${app.metadata.name}`, {view: pref.appDetails.view}, {event: e}) + ctx.navigation.goto(`applications/${app.metadata.namespace}/${app.metadata.name}`, {view: pref.appDetails.view}, {event: e}) }>
    { setValues(update); }} style={{width: '100%'}} - inputStyle={{marginBottom: '0.5em', backgroundColor: 'black', border: 'none'}} + inputStyle={{marginBottom: '0.5em', backgroundColor: 'black', border: 'none', color: '#fff'}} /> )} {((props.field ? tags : options) || []).map((opt, i) => ( diff --git a/ui/src/app/applications/components/pod-logs-viewer/container-selector.tsx b/ui/src/app/applications/components/pod-logs-viewer/container-selector.tsx index 5dca12dd6af6c..bcd67ead7e9ab 100644 --- a/ui/src/app/applications/components/pod-logs-viewer/container-selector.tsx +++ b/ui/src/app/applications/components/pod-logs-viewer/container-selector.tsx @@ -27,7 +27,7 @@ export const ContainerSelector = ({ }; if (containerNames.length <= 1) return <>; return ( - +