mirror of
https://github.com/argoproj/argo-cd
synced 2026-04-21 17:07:16 +00:00
Merge branch 'master' into 26271-fix-manifests-version
This commit is contained in:
commit
2874752301
362 changed files with 21783 additions and 33358 deletions
1
.github/configs/renovate-config.js
vendored
1
.github/configs/renovate-config.js
vendored
|
|
@ -4,6 +4,7 @@ module.exports = {
|
|||
autodiscover: false,
|
||||
allowPostUpgradeCommandTemplating: true,
|
||||
allowedPostUpgradeCommands: ["make mockgen"],
|
||||
binarySource: 'install',
|
||||
extends: [
|
||||
"github>argoproj/argo-cd//renovate-presets/commons.json5",
|
||||
"github>argoproj/argo-cd//renovate-presets/custom-managers/shell.json5",
|
||||
|
|
|
|||
26
.github/pr-title-checker-config.json
vendored
26
.github/pr-title-checker-config.json
vendored
|
|
@ -1,15 +1,15 @@
|
|||
{
|
||||
"LABEL": {
|
||||
"name": "title needs formatting",
|
||||
"color": "EEEEEE"
|
||||
},
|
||||
"CHECKS": {
|
||||
"prefixes": ["[Bot] docs: "],
|
||||
"regexp": "^(feat|fix|docs|test|ci|chore)!?(\\(.*\\))?!?:.*"
|
||||
},
|
||||
"MESSAGES": {
|
||||
"success": "PR title is valid",
|
||||
"failure": "PR title is invalid",
|
||||
"notice": "PR Title needs to pass regex '^(feat|fix|docs|test|ci|chore)!?(\\(.*\\))?!?:.*"
|
||||
}
|
||||
"LABEL": {
|
||||
"name": "title needs formatting",
|
||||
"color": "EEEEEE"
|
||||
},
|
||||
"CHECKS": {
|
||||
"prefixes": ["[Bot] docs: "],
|
||||
"regexp": "^(refactor|feat|fix|docs|test|ci|chore)!?(\\(.*\\))?!?:.*"
|
||||
},
|
||||
"MESSAGES": {
|
||||
"success": "PR title is valid",
|
||||
"failure": "PR title is invalid",
|
||||
"notice": "PR Title needs to pass regex '^(refactor|feat|fix|docs|test|ci|chore)!?(\\(.*\\))?!?:.*"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
.github/workflows/README.md
vendored
1
.github/workflows/README.md
vendored
|
|
@ -11,6 +11,7 @@
|
|||
| release.yaml | Build images, cli-binaries, provenances, and post actions |
|
||||
| scorecard.yaml | Generate scorecard for supply-chain security |
|
||||
| update-snyk.yaml | Scheduled snyk reports |
|
||||
| stale.yaml | Labels stale issues and PRs |
|
||||
|
||||
# Reusable workflows
|
||||
|
||||
|
|
|
|||
2
.github/workflows/cherry-pick-single.yml
vendored
2
.github/workflows/cherry-pick-single.yml
vendored
|
|
@ -32,7 +32,7 @@ jobs:
|
|||
steps:
|
||||
- name: Generate a token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
|
||||
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
with:
|
||||
app-id: ${{ secrets.CHERRYPICK_APP_ID }}
|
||||
private-key: ${{ secrets.CHERRYPICK_APP_PRIVATE_KEY }}
|
||||
|
|
|
|||
15
.github/workflows/ci-build.yaml
vendored
15
.github/workflows/ci-build.yaml
vendored
|
|
@ -14,7 +14,7 @@ on:
|
|||
env:
|
||||
# Golang version to use across CI steps
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
GOLANG_VERSION: '1.25.6'
|
||||
GOLANG_VERSION: '1.26.0'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
|
@ -32,7 +32,7 @@ jobs:
|
|||
docs: ${{ steps.filter.outputs.docs_any_changed }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: tj-actions/changed-files@8cba46e29c11878d930bca7870bb54394d3e8b21 # v47.0.2
|
||||
- uses: tj-actions/changed-files@7dee1b0c1557f278e5c7dc244927139d78c0e22a # v47.0.4
|
||||
id: filter
|
||||
with:
|
||||
# Any file which is not under docs/, ui/ or is not a markdown file is counted as a backend file
|
||||
|
|
@ -111,7 +111,7 @@ jobs:
|
|||
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
|
||||
with:
|
||||
# renovate: datasource=go packageName=github.com/golangci/golangci-lint/v2 versioning=regex:^v(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)?$
|
||||
version: v2.8.0
|
||||
version: v2.9.0
|
||||
args: --verbose
|
||||
|
||||
test-go:
|
||||
|
|
@ -390,16 +390,17 @@ jobs:
|
|||
run: |
|
||||
go tool covdata percent -i=test-results,e2e-code-coverage/applicationset-controller,e2e-code-coverage/repo-server,e2e-code-coverage/app-controller,e2e-code-coverage/commit-server -o test-results/full-coverage.out
|
||||
- name: Upload code coverage information to codecov.io
|
||||
# Only run when the workflow is for upstream (PR target or push is in argoproj/argo-cd).
|
||||
if: github.repository == 'argoproj/argo-cd'
|
||||
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
|
||||
with:
|
||||
files: test-results/full-coverage.out
|
||||
fail_ci_if_error: true
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
if: env.codecov_secret != ''
|
||||
- name: Upload test results to Codecov
|
||||
# Codecov uploads test results to Codecov.io on upstream master branch and on fork master branch if the token is configured.
|
||||
if: env.codecov_secret != '' && github.ref == 'refs/heads/master' && github.event_name == 'push'
|
||||
# Codecov uploads test results to Codecov.io on upstream master branch.
|
||||
if: github.repository == 'argoproj/argo-cd' && github.ref == 'refs/heads/master' && github.event_name == 'push'
|
||||
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
|
||||
with:
|
||||
files: test-results/junit.xml
|
||||
|
|
@ -501,7 +502,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.43.0
|
||||
docker pull ghcr.io/dexidp/dex:v2.44.0
|
||||
docker pull argoproj/argo-cd-ci-builder:v1.0.0
|
||||
docker pull redis:8.2.3-alpine
|
||||
- name: Create target directory for binaries in the build-process
|
||||
|
|
|
|||
2
.github/workflows/image-reuse.yaml
vendored
2
.github/workflows/image-reuse.yaml
vendored
|
|
@ -142,7 +142,7 @@ jobs:
|
|||
|
||||
- name: Build and push container image
|
||||
id: image
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0
|
||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 #v6.19.2
|
||||
with:
|
||||
context: .
|
||||
platforms: ${{ inputs.platforms }}
|
||||
|
|
|
|||
4
.github/workflows/image.yaml
vendored
4
.github/workflows/image.yaml
vendored
|
|
@ -86,7 +86,7 @@ jobs:
|
|||
with:
|
||||
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
go-version: 1.25.6
|
||||
go-version: 1.26.0
|
||||
platforms: ${{ needs.set-vars.outputs.platforms }}
|
||||
push: false
|
||||
|
||||
|
|
@ -103,7 +103,7 @@ jobs:
|
|||
ghcr_image_name: ${{ needs.set-vars.outputs.ghcr_image_name }}
|
||||
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
go-version: 1.25.6
|
||||
go-version: 1.26.0
|
||||
platforms: ${{ needs.set-vars.outputs.platforms }}
|
||||
push: true
|
||||
secrets:
|
||||
|
|
|
|||
6
.github/workflows/release.yaml
vendored
6
.github/workflows/release.yaml
vendored
|
|
@ -11,7 +11,7 @@ permissions: {}
|
|||
|
||||
env:
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
GOLANG_VERSION: '1.25.6' # Note: go-version must also be set in job argocd-image.with.go-version
|
||||
GOLANG_VERSION: '1.26.0' # Note: go-version must also be set in job argocd-image.with.go-version
|
||||
|
||||
jobs:
|
||||
argocd-image:
|
||||
|
|
@ -26,7 +26,7 @@ jobs:
|
|||
quay_image_name: ${{ needs.setup-variables.outputs.quay_image_name }}
|
||||
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
go-version: 1.25.6
|
||||
go-version: 1.26.0
|
||||
platforms: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le
|
||||
push: true
|
||||
secrets:
|
||||
|
|
@ -159,7 +159,7 @@ jobs:
|
|||
tool-cache: false
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
|
||||
uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7.0.0
|
||||
id: run-goreleaser
|
||||
with:
|
||||
version: latest
|
||||
|
|
|
|||
9
.github/workflows/renovate.yaml
vendored
9
.github/workflows/renovate.yaml
vendored
|
|
@ -22,15 +22,8 @@ jobs:
|
|||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
|
||||
|
||||
# Some codegen commands require Go to be setup
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||
with:
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
go-version: 1.25.6
|
||||
|
||||
- name: Self-hosted Renovate
|
||||
uses: renovatebot/github-action@e23f4d9675532445118c886434f5a34292b630b4 #46.0.2
|
||||
uses: renovatebot/github-action@8d75b92f43899d483728e9a8a7fd44238020f6e6 #46.1.2
|
||||
with:
|
||||
configurationFile: .github/configs/renovate-config.js
|
||||
token: '${{ steps.get_token.outputs.token }}'
|
||||
|
|
|
|||
33
.github/workflows/stale.yaml
vendored
Normal file
33
.github/workflows/stale.yaml
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
name: "Label stale issues and PRs"
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" #Runs midnight 12AM UTC
|
||||
|
||||
#Added Recommended permissions
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
stale-issue-message: >
|
||||
This issue has been marked as stale because it has had no activity for 90 days. Please comment if this is still relevant.
|
||||
|
||||
stale-pr-message: >
|
||||
This pull request has been marked as stale because it has had no activity for 90 days. Please comment if this is still relevant.
|
||||
|
||||
days-before-stale: 90
|
||||
days-before-close: -1 # Auto-close diabled
|
||||
|
||||
exempt-issue-labels: >
|
||||
bug, security, breaking/high, breaking/medium, breaking/low
|
||||
|
||||
# General configuration
|
||||
operations-per-run: 200
|
||||
remove-stale-when-updated: true #Remove stale label when issue/pr is updated
|
||||
|
|
@ -22,6 +22,7 @@ linters:
|
|||
- govet
|
||||
- importas
|
||||
- misspell
|
||||
- modernize
|
||||
- noctx
|
||||
- perfsprint
|
||||
- revive
|
||||
|
|
@ -121,6 +122,13 @@ linters:
|
|||
- pkg: github.com/argoproj/argo-cd/v3/util/io
|
||||
alias: utilio
|
||||
|
||||
modernize:
|
||||
disable:
|
||||
# Suggest replacing omitempty with omitzero for struct fields.
|
||||
- omitzero
|
||||
# Simplify code by using go1.26's new(expr). - generates lots of false positives.
|
||||
- newexpr
|
||||
|
||||
nolintlint:
|
||||
require-specific: true
|
||||
|
||||
|
|
|
|||
|
|
@ -79,10 +79,10 @@ packages:
|
|||
github.com/argoproj/argo-cd/v3/util/workloadidentity:
|
||||
interfaces:
|
||||
TokenProvider: {}
|
||||
github.com/argoproj/gitops-engine/pkg/cache:
|
||||
github.com/argoproj/argo-cd/gitops-engine/pkg/cache:
|
||||
interfaces:
|
||||
ClusterCache: {}
|
||||
github.com/argoproj/gitops-engine/pkg/diff:
|
||||
github.com/argoproj/argo-cd/gitops-engine/pkg/diff:
|
||||
interfaces:
|
||||
ServerSideDryRunner: {}
|
||||
github.com/microsoft/azure-devops-go-api/azuredevops/v7/git:
|
||||
|
|
|
|||
11
Dockerfile
11
Dockerfile
|
|
@ -4,7 +4,7 @@ ARG BASE_IMAGE=docker.io/library/ubuntu:25.10@sha256:4a9232cc47bf99defcc8860ef62
|
|||
# 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.25.6@sha256:06d1251c59a75761ce4ebc8b299030576233d7437c886a68b43464bad62d4bb1 AS builder
|
||||
FROM docker.io/library/golang:1.26.0@sha256:c83e68f3ebb6943a2904fa66348867d108119890a2c6a2e6f07b38d0eb6c25c5 AS builder
|
||||
|
||||
WORKDIR /tmp
|
||||
|
||||
|
|
@ -16,7 +16,6 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
|
|||
unzip \
|
||||
fcgiwrap \
|
||||
git \
|
||||
git-lfs \
|
||||
make \
|
||||
wget \
|
||||
gcc \
|
||||
|
|
@ -29,7 +28,8 @@ COPY hack/install.sh hack/tool-versions.sh ./
|
|||
COPY hack/installers installers
|
||||
|
||||
RUN ./install.sh helm && \
|
||||
INSTALL_PATH=/usr/local/bin ./install.sh kustomize
|
||||
INSTALL_PATH=/usr/local/bin ./install.sh kustomize && \
|
||||
./install.sh git-lfs
|
||||
|
||||
####################################################################################################
|
||||
# Argo CD Base - used as the base for both the release and dev argocd images
|
||||
|
|
@ -51,7 +51,7 @@ RUN groupadd -g $ARGOCD_USER_ID argocd && \
|
|||
apt-get update && \
|
||||
apt-get dist-upgrade -y && \
|
||||
apt-get install --no-install-recommends -y \
|
||||
git git-lfs tini ca-certificates gpg gpg-agent tzdata connect-proxy openssh-client && \
|
||||
git tini ca-certificates gpg gpg-agent tzdata connect-proxy openssh-client && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
|
||||
|
||||
|
|
@ -61,6 +61,7 @@ COPY hack/gpg-wrapper.sh \
|
|||
/usr/local/bin/
|
||||
COPY --from=builder /usr/local/bin/helm /usr/local/bin/helm
|
||||
COPY --from=builder /usr/local/bin/kustomize /usr/local/bin/kustomize
|
||||
COPY --from=builder /usr/local/bin/git-lfs /usr/local/bin/git-lfs
|
||||
|
||||
# keep uid_entrypoint.sh for backward compatibility
|
||||
RUN ln -s /usr/local/bin/entrypoint.sh /usr/local/bin/uid_entrypoint.sh
|
||||
|
|
@ -109,7 +110,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.25.6@sha256:06d1251c59a75761ce4ebc8b299030576233d7437c886a68b43464bad62d4bb1 AS argocd-build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26.0@sha256:c83e68f3ebb6943a2904fa66348867d108119890a2c6a2e6f07b38d0eb6c25c5 AS argocd-build
|
||||
|
||||
WORKDIR /go/src/github.com/argoproj/argo-cd
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM docker.io/library/golang:1.25.6@sha256:06d1251c59a75761ce4ebc8b299030576233d7437c886a68b43464bad62d4bb1
|
||||
FROM docker.io/library/golang:1.26.0@sha256:c83e68f3ebb6943a2904fa66348867d108119890a2c6a2e6f07b38d0eb6c25c5
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
|
|
@ -11,7 +11,6 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
|
|||
unzip \
|
||||
fcgiwrap \
|
||||
git \
|
||||
git-lfs \
|
||||
make \
|
||||
wget \
|
||||
gcc \
|
||||
|
|
@ -28,7 +27,8 @@ COPY hack/install.sh hack/tool-versions.sh ./
|
|||
COPY hack/installers installers
|
||||
|
||||
RUN ./install.sh helm && \
|
||||
INSTALL_PATH=/usr/local/bin ./install.sh kustomize
|
||||
INSTALL_PATH=/usr/local/bin ./install.sh kustomize && \
|
||||
./install.sh git-lfs
|
||||
|
||||
COPY hack/gpg-wrapper.sh \
|
||||
hack/git-verify-wrapper.sh \
|
||||
|
|
|
|||
|
|
@ -18,14 +18,14 @@ This document lists the maintainers of the Argo CD project.
|
|||
| Dan Garfield | [todaywasawesome](https://github.com/todaywasawesome) | Approver(docs) | [Octopus Deploy](https://octopus.com/) |
|
||||
| Alexandre Gaudreault | [agaudreault](https://github.com/agaudreault) | Approver | [Intuit](https://www.github.com/intuit/) |
|
||||
| Christian Hernandez | [christianh814](https://github.com/christianh814) | Reviewer(docs) | [Akuity](https://akuity.io/) |
|
||||
| Peter Jiang | [pjiang](https://github.com/pjiang) | Reviewer | [Intuit](https://www.intuit.com/) |
|
||||
| Peter Jiang | [pjiang-dev](https://github.com/pjiang-dev) | Approver(docs) | [Intuit](https://www.intuit.com/) |
|
||||
| Andrii Korotkov | [andrii-korotkov](https://github.com/andrii-korotkov) | Reviewer | [Verkada](https://www.verkada.com/) |
|
||||
| Pasha Kostohrys | [pasha-codefresh](https://github.com/pasha-codefresh) | Approver | [Codefresh](https://www.github.com/codefresh/) |
|
||||
| Nitish Kumar | [nitishfy](https://github.com/nitishfy) | Approver(cli,docs) | [Akuity](https://akuity.io/) |
|
||||
| Justin Marquis | [34fathombelow](https://github.com/34fathombelow) | Approver(docs/ci) | [Akuity](https://akuity.io/) |
|
||||
| Alexander Matyushentsev | [alexmt](https://github.com/alexmt) | Lead | [Akuity](https://akuity.io/) |
|
||||
| Nicholas Morey | [morey-tech](https://github.com/morey-tech) | Reviewer(docs) | [Akuity](https://akuity.io/) |
|
||||
| Papapetrou Patroklos | [ppapapetrou76](https://github.com/ppapapetrou76) | Reviewer | [Octopus Deploy](https://octopus.com/) |
|
||||
| Papapetrou Patroklos | [ppapapetrou76](https://github.com/ppapapetrou76) | Approver(docs,cli) | [Octopus Deploy](https://octopus.com/) |
|
||||
| Blake Pettersson | [blakepettersson](https://github.com/blakepettersson) | Approver | [Akuity](https://akuity.io/) |
|
||||
| Ishita Sequeira | [ishitasequeira](https://github.com/ishitasequeira) | Approver | [Red Hat](https://redhat.com/) |
|
||||
| Ashutosh Singh | [ashutosh16](https://github.com/ashutosh16) | Approver(docs) | [Intuit](https://www.github.com/intuit/) |
|
||||
|
|
@ -37,3 +37,7 @@ This document lists the maintainers of the Argo CD project.
|
|||
| Regina Voloshin | [reggie-k](https://github.com/reggie-k) | Approver | [Octopus Deploy](https://octopus.com/) |
|
||||
| Hong Wang | [wanghong230](https://github.com/wanghong230) | Reviewer | [Akuity](https://akuity.io/) |
|
||||
| Jonathan West | [jgwest](https://github.com/jgwest) | Approver | [Red Hat](https://redhat.com/) |
|
||||
| Jaewoo Choi | [choejwoo](https://github.com/choejwoo) | Reviewer | [Hyundai-Autoever](https://www.hyundai-autoever.com/eng/) |
|
||||
| Alexy Mantha | [alexymantha](https://github.com/alexymantha) | Reviewer | GoTo |
|
||||
| Kanika Rana | [ranakan19](https://github.com/ranakan19) | Reviewer | [Red Hat](https://redhat.com/) |
|
||||
| Jonathan Winters | [jwinters01](https://github.com/jwinters01) | Reviewer | [Intuit](https://www.github.com/intuit/) |
|
||||
|
|
|
|||
4
Makefile
4
Makefile
|
|
@ -445,7 +445,7 @@ test: test-tools-image
|
|||
.PHONY: test-local
|
||||
test-local: test-gitops-engine
|
||||
# run if TEST_MODULE is empty or does not point to gitops-engine tests
|
||||
ifneq ($(if $(TEST_MODULE),,ALL)$(filter-out github.com/argoproj/gitops-engine% ./gitops-engine%,$(TEST_MODULE)),)
|
||||
ifneq ($(if $(TEST_MODULE),,ALL)$(filter-out github.com/argoproj/argo-cd/gitops-engine% ./gitops-engine%,$(TEST_MODULE)),)
|
||||
if test "$(TEST_MODULE)" = ""; then \
|
||||
DIST_DIR=${DIST_DIR} RERUN_FAILS=0 PACKAGES=`go list ./... | grep -v 'test/e2e'` ./hack/test.sh -args -test.gocoverdir="$(PWD)/test-results"; \
|
||||
else \
|
||||
|
|
@ -457,7 +457,7 @@ endif
|
|||
.PHONY: test-gitops-engine
|
||||
test-gitops-engine:
|
||||
# run if TEST_MODULE is empty or points to gitops-engine tests
|
||||
ifneq ($(if $(TEST_MODULE),,ALL)$(filter github.com/argoproj/gitops-engine% ./gitops-engine%,$(TEST_MODULE)),)
|
||||
ifneq ($(if $(TEST_MODULE),,ALL)$(filter github.com/argoproj/argo-cd/gitops-engine% ./gitops-engine%,$(TEST_MODULE)),)
|
||||
mkdir -p $(PWD)/test-results
|
||||
cd gitops-engine && go test -race -cover ./... -args -test.gocoverdir="$(PWD)/test-results"
|
||||
endif
|
||||
|
|
|
|||
26
USERS.md
26
USERS.md
|
|
@ -7,7 +7,7 @@ Currently, the following organizations are **officially** using Argo CD:
|
|||
|
||||
1. [100ms](https://www.100ms.ai/)
|
||||
1. [127Labs](https://127labs.com/)
|
||||
1. [3Rein](https://www.3rein.com/)
|
||||
1. [3Rein](https://3reinmedia.com/)
|
||||
1. [42 School](https://42.fr/)
|
||||
1. [4data](https://4data.ch/)
|
||||
1. [7shifts](https://www.7shifts.com/)
|
||||
|
|
@ -31,8 +31,8 @@ Currently, the following organizations are **officially** using Argo CD:
|
|||
1. [ANSTO - Australian Synchrotron](https://www.synchrotron.org.au/)
|
||||
1. [Ant Group](https://www.antgroup.com/)
|
||||
1. [AppDirect](https://www.appdirect.com)
|
||||
1. [Arcadia](https://www.arcadia.io)
|
||||
1. [Arctiq Inc.](https://www.arctiq.ca)
|
||||
1. [Arcadia](https://arcadia.io/)
|
||||
1. [Arctiq Inc.](https://arctiq.com/)
|
||||
1. [Artemis Health by Nomi Health](https://www.artemishealth.com/)
|
||||
1. [Arturia](https://www.arturia.com)
|
||||
1. [ARZ Allgemeines Rechenzentrum GmbH](https://www.arz.at/)
|
||||
|
|
@ -147,14 +147,14 @@ Currently, the following organizations are **officially** using Argo CD:
|
|||
1. [Getir](https://getir.com)
|
||||
1. [GetYourGuide](https://www.getyourguide.com/)
|
||||
1. [Gitpod](https://www.gitpod.io)
|
||||
1. [Gllue](https://gllue.com)
|
||||
1. [Gllue](https://www.gllue.com/)
|
||||
1. [gloat](https://gloat.com/)
|
||||
1. [GLOBIS](https://globis.com)
|
||||
1. [Glovo](https://www.glovoapp.com)
|
||||
1. [GlueOps](https://glueops.dev)
|
||||
1. [GMETRI](https://gmetri.com/)
|
||||
1. [Gojek](https://www.gojek.io/)
|
||||
1. [GoTo Financial](https://gotofinancial.com/)
|
||||
1. [GoTo Financial](https://www.gotocompany.com/en/products/goto-financial)
|
||||
1. [GoTo](https://www.goto.com/)
|
||||
1. [Greenpass](https://www.greenpass.com.br/)
|
||||
1. [Gridfuse](https://gridfuse.com/)
|
||||
|
|
@ -165,7 +165,7 @@ Currently, the following organizations are **officially** using Argo CD:
|
|||
1. [Healy](https://www.healyworld.net)
|
||||
1. [Helio](https://helio.exchange)
|
||||
1. [hetao101](https://www.hetao101.com/)
|
||||
1. [Hetki](https://hetki.ai)
|
||||
1. [Hetki](https://hetki.io/)
|
||||
1. [hipages](https://hipages.com.au/)
|
||||
1. [Hiya](https://hiya.com)
|
||||
1. [Honestbank](https://honestbank.com)
|
||||
|
|
@ -177,7 +177,7 @@ Currently, the following organizations are **officially** using Argo CD:
|
|||
1. [Icelandair](https://www.icelandair.com)
|
||||
1. [IFS](https://www.ifs.com)
|
||||
1. [IITS-Consulting](https://iits-consulting.de)
|
||||
1. [IllumiDesk](https://www.illumidesk.com)
|
||||
1. [IllumiDesk](https://illumichat.com/)
|
||||
1. [Imagine Learning](https://www.imaginelearning.com/)
|
||||
1. [imaware](https://imaware.health)
|
||||
1. [Indeed](https://indeed.com)
|
||||
|
|
@ -213,7 +213,7 @@ Currently, the following organizations are **officially** using Argo CD:
|
|||
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. [Lian Chu Securities](https://www.lczq.com/)
|
||||
1. [Liatrio](https://www.liatrio.com)
|
||||
1. [Lightricks](https://www.lightricks.com/)
|
||||
1. [Loom](https://www.loom.com/)
|
||||
|
|
@ -246,7 +246,7 @@ Currently, the following organizations are **officially** using Argo CD:
|
|||
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. [Natura &Co](https://ri.natura.com.br/)
|
||||
1. [Netease Cloud Music](https://music.163.com/)
|
||||
1. [Nethopper](https://nethopper.io)
|
||||
1. [New Relic](https://newrelic.com/)
|
||||
|
|
@ -277,7 +277,7 @@ Currently, the following organizations are **officially** using Argo CD:
|
|||
1. [Orbital Insight](https://orbitalinsight.com/)
|
||||
1. [Oscar Health Insurance](https://hioscar.com/)
|
||||
1. [Outpost24](https://outpost24.com/)
|
||||
1. [p3r](https://www.p3r.one/)
|
||||
1. [p3r](https://persona.atlus.com/p3r/)
|
||||
1. [Packlink](https://www.packlink.com/)
|
||||
1. [PagerDuty](https://www.pagerduty.com/)
|
||||
1. [Pandosearch](https://www.pandosearch.com/en/home)
|
||||
|
|
@ -419,18 +419,18 @@ Currently, the following organizations are **officially** using Argo CD:
|
|||
1. [VSHN - The DevOps Company](https://vshn.ch/)
|
||||
1. [Wakacje.pl](https://www.wakacje.pl/)
|
||||
1. [Walkbase](https://www.walkbase.com/)
|
||||
1. [Webstores](https://www.webstores.nl)
|
||||
1. [Webstores](https://www.friday.nl/)
|
||||
1. [Wehkamp](https://www.wehkamp.nl/)
|
||||
1. [WeMaintain](https://www.wemaintain.com/)
|
||||
1. [WeMo Scooter](https://www.wemoscooter.com/)
|
||||
1. [Whitehat Berlin](https://whitehat.berlin) by Guido Maria Serra +Fenaroli
|
||||
1. [Witick](https://witick.io/)
|
||||
1. [Witick](https://www.witik.io/en/)
|
||||
1. [Wolffun Game](https://www.wolffungame.com/)
|
||||
1. [WooliesX](https://wooliesx.com.au/)
|
||||
1. [Woolworths Group](https://www.woolworthsgroup.com.au/)
|
||||
1. [WSpot](https://www.wspot.com.br/)
|
||||
1. [X3M ads](https://x3mads.com)
|
||||
1. [Yieldlab](https://www.yieldlab.de/)
|
||||
1. [Yieldlab](https://virtualminds.com/)
|
||||
1. [Youverify](https://youverify.co/)
|
||||
1. [Yubo](https://www.yubo.live/)
|
||||
1. [Yuno](https://y.uno/)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ import (
|
|||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/controllers/template"
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/generators"
|
||||
|
|
@ -244,11 +244,6 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
|
|||
return ctrl.Result{}, fmt.Errorf("failed to get current applications for application set: %w", err)
|
||||
}
|
||||
|
||||
err = r.updateResourcesStatus(ctx, logCtx, &applicationSetInfo, currentApplications)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("failed to get update resources status for application set: %w", err)
|
||||
}
|
||||
|
||||
// appSyncMap tracks which apps will be synced during this reconciliation.
|
||||
appSyncMap := map[string]bool{}
|
||||
|
||||
|
|
@ -372,6 +367,16 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
|
|||
}
|
||||
}
|
||||
|
||||
// Update resources status after create/update/delete so it reflects the actual cluster state.
|
||||
currentApplications, err = r.getCurrentApplications(ctx, applicationSetInfo)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("failed to get current applications for application set: %w", err)
|
||||
}
|
||||
err = r.updateResourcesStatus(ctx, logCtx, &applicationSetInfo, currentApplications)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("failed to update resources status for application set: %w", err)
|
||||
}
|
||||
|
||||
if applicationSetInfo.RefreshRequired() {
|
||||
delete(applicationSetInfo.Annotations, common.AnnotationApplicationSetRefresh)
|
||||
err := r.Update(ctx, &applicationSetInfo)
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ import (
|
|||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/generators"
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/generators/mocks"
|
||||
|
|
@ -2950,6 +2950,112 @@ func TestUpdatePerformedWithSyncPolicySync(t *testing.T) {
|
|||
assert.Equal(t, map[string]string{"label-key": "label-value"}, app.Labels)
|
||||
}
|
||||
|
||||
// TestReconcilePopulatesResourcesStatusOnFirstRun verifies that status.resources and status.resourcesCount
|
||||
// are populated after the first reconcile, when applications are created.
|
||||
func TestReconcilePopulatesResourcesStatusOnFirstRun(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
err := v1alpha1.AddToScheme(scheme)
|
||||
require.NoError(t, err)
|
||||
err = corev1.AddToScheme(scheme)
|
||||
require.NoError(t, err)
|
||||
|
||||
defaultProject := v1alpha1.AppProject{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: "argocd"},
|
||||
Spec: v1alpha1.AppProjectSpec{SourceRepos: []string{"*"}, Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "https://good-cluster"}}},
|
||||
}
|
||||
applicationsSyncPolicy := v1alpha1.ApplicationsSyncPolicySync
|
||||
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": "good-cluster","url": "https://good-cluster"}`),
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
SyncPolicy: &v1alpha1.ApplicationSetSyncPolicy{
|
||||
ApplicationsSync: &applicationsSyncPolicy,
|
||||
},
|
||||
Template: v1alpha1.ApplicationSetTemplate{
|
||||
ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{
|
||||
Name: "{{cluster}}",
|
||||
Namespace: "argocd",
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSpec{
|
||||
Source: &v1alpha1.ApplicationSource{RepoURL: "https://github.com/argoproj/argocd-example-apps", Path: "guestbook"},
|
||||
Project: "default",
|
||||
Destination: v1alpha1.ApplicationDestination{Server: "{{url}}"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
secret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-cluster",
|
||||
Namespace: "argocd",
|
||||
Labels: map[string]string{
|
||||
argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster,
|
||||
},
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"name": []byte("good-cluster"),
|
||||
"server": []byte("https://good-cluster"),
|
||||
"config": []byte("{\"username\":\"foo\",\"password\":\"foo\"}"),
|
||||
},
|
||||
}
|
||||
|
||||
kubeclientset := getDefaultTestClientSet(secret)
|
||||
client := fake.NewClientBuilder().
|
||||
WithScheme(scheme).
|
||||
WithObjects(&appSet, &defaultProject, secret).
|
||||
WithStatusSubresource(&appSet).
|
||||
WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).
|
||||
Build()
|
||||
metrics := appsetmetrics.NewFakeAppsetMetrics()
|
||||
|
||||
argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset)
|
||||
clusterInformer, err := settings.NewClusterInformer(kubeclientset, "argocd")
|
||||
require.NoError(t, err)
|
||||
|
||||
defer startAndSyncInformer(t, clusterInformer)()
|
||||
|
||||
r := ApplicationSetReconciler{
|
||||
Client: client,
|
||||
Scheme: scheme,
|
||||
Renderer: &utils.Render{},
|
||||
Recorder: record.NewFakeRecorder(1),
|
||||
Generators: map[string]generators.Generator{"List": generators.NewListGenerator()},
|
||||
ArgoDB: argodb,
|
||||
ArgoCDNamespace: "argocd",
|
||||
KubeClientset: kubeclientset,
|
||||
Policy: v1alpha1.ApplicationsSyncPolicySync,
|
||||
Metrics: metrics,
|
||||
ClusterInformer: clusterInformer,
|
||||
}
|
||||
|
||||
req := ctrl.Request{
|
||||
NamespacedName: types.NamespacedName{Namespace: "argocd", Name: "name"},
|
||||
}
|
||||
|
||||
_, err = r.Reconcile(t.Context(), req)
|
||||
require.NoError(t, err)
|
||||
|
||||
var retrievedAppSet v1alpha1.ApplicationSet
|
||||
err = r.Get(t.Context(), crtclient.ObjectKey{Namespace: "argocd", Name: "name"}, &retrievedAppSet)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, retrievedAppSet.Status.Resources, 1, "status.resources should have 1 item after first reconcile")
|
||||
assert.Equal(t, int64(1), retrievedAppSet.Status.ResourcesCount, "status.resourcesCount should be 1 after first reconcile")
|
||||
assert.Equal(t, "good-cluster", retrievedAppSet.Status.Resources[0].Name)
|
||||
}
|
||||
|
||||
func TestUpdatePerformedWithSyncPolicyCreateOnlyAndAllowPolicyOverrideFalse(t *testing.T) {
|
||||
applicationsSyncPolicy := v1alpha1.ApplicationsSyncPolicyCreateOnly
|
||||
|
||||
|
|
|
|||
|
|
@ -388,8 +388,7 @@ func invalidGenerators(applicationSetInfo *argoappsv1.ApplicationSet) (bool, map
|
|||
for index, generator := range applicationSetInfo.Spec.Generators {
|
||||
v := reflect.Indirect(reflect.ValueOf(generator))
|
||||
found := false
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
field := v.Field(i)
|
||||
for _, field := range v.Fields() {
|
||||
if !field.CanInterface() {
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
6
assets/swagger.json
generated
6
assets/swagger.json
generated
|
|
@ -7695,11 +7695,11 @@
|
|||
},
|
||||
"namePrefix": {
|
||||
"type": "string",
|
||||
"title": "NamePrefix is a prefix appended to resources for Kustomize apps"
|
||||
"title": "NamePrefix overrides the namePrefix in the kustomization.yaml for Kustomize apps"
|
||||
},
|
||||
"nameSuffix": {
|
||||
"type": "string",
|
||||
"title": "NameSuffix is a suffix appended to resources for Kustomize apps"
|
||||
"title": "NameSuffix overrides the nameSuffix in the kustomization.yaml for Kustomize apps"
|
||||
},
|
||||
"namespace": {
|
||||
"type": "string",
|
||||
|
|
@ -9756,7 +9756,7 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"diff": {
|
||||
"description": "Diff contains the JSON patch representing the difference between the live and target resource.\nDeprecated: Use NormalizedLiveState and PredictedLiveState instead to compute differences.",
|
||||
"description": "Diff contains the JSON patch representing the difference between the live and target resource.\n\nDeprecated: Use NormalizedLiveState and PredictedLiveState instead to compute differences.",
|
||||
"type": "string"
|
||||
},
|
||||
"group": {
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// CLIName is the name of the CLI
|
||||
cliName = common.ApplicationController
|
||||
// Default time in seconds for application resync period
|
||||
defaultAppResyncPeriod = 120
|
||||
// Default time in seconds for application resync period jitter
|
||||
|
|
@ -99,7 +97,7 @@ func NewCommand() *cobra.Command {
|
|||
hydratorEnabled bool
|
||||
)
|
||||
command := cobra.Command{
|
||||
Use: cliName,
|
||||
Use: common.CommandApplicationController,
|
||||
Short: "Run ArgoCD Application Controller",
|
||||
Long: "ArgoCD application controller is a Kubernetes controller that continuously monitors running applications and compares the current, live state against the desired target state (as specified in the repo). This command runs Application Controller in the foreground. It can be configured by following options.",
|
||||
DisableAutoGenTag: true,
|
||||
|
|
|
|||
|
|
@ -49,10 +49,6 @@ import (
|
|||
|
||||
var gitSubmoduleEnabled = env.ParseBoolFromEnv(common.EnvGitSubmoduleEnabled, true)
|
||||
|
||||
const (
|
||||
cliName = common.ApplicationSetController
|
||||
)
|
||||
|
||||
func NewCommand() *cobra.Command {
|
||||
var (
|
||||
clientConfig clientcmd.ClientConfig
|
||||
|
|
@ -87,7 +83,7 @@ func NewCommand() *cobra.Command {
|
|||
_ = clientgoscheme.AddToScheme(scheme)
|
||||
_ = appv1alpha1.AddToScheme(scheme)
|
||||
command := cobra.Command{
|
||||
Use: cliName,
|
||||
Use: common.CommandApplicationSetController,
|
||||
Short: "Starts Argo CD ApplicationSet controller",
|
||||
DisableAutoGenTag: true,
|
||||
RunE: func(c *cobra.Command, _ []string) error {
|
||||
|
|
|
|||
|
|
@ -18,11 +18,6 @@ import (
|
|||
traceutil "github.com/argoproj/argo-cd/v3/util/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
// CLIName is the name of the CLI
|
||||
cliName = "argocd-cmp-server"
|
||||
)
|
||||
|
||||
func NewCommand() *cobra.Command {
|
||||
var (
|
||||
configFilePath string
|
||||
|
|
@ -32,7 +27,7 @@ func NewCommand() *cobra.Command {
|
|||
otlpAttrs []string
|
||||
)
|
||||
command := cobra.Command{
|
||||
Use: cliName,
|
||||
Use: common.CommandCMPServer,
|
||||
Short: "Run ArgoCD ConfigManagementPlugin Server",
|
||||
Long: "ArgoCD ConfigManagementPlugin Server is an internal service which runs as sidecar container in reposerver deployment. The following configuration options are available:",
|
||||
DisableAutoGenTag: true,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ func NewCommand() *cobra.Command {
|
|||
metricsHost string
|
||||
)
|
||||
command := &cobra.Command{
|
||||
Use: "argocd-commit-server",
|
||||
Use: common.CommandCommitServer,
|
||||
Short: "Run Argo CD Commit Server",
|
||||
Long: "Argo CD Commit Server is an internal service which commits and pushes hydrated manifests to git. This command runs Commit Server in the foreground.",
|
||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||
|
|
|
|||
|
|
@ -25,13 +25,9 @@ import (
|
|||
"github.com/argoproj/argo-cd/v3/util/tls"
|
||||
)
|
||||
|
||||
const (
|
||||
cliName = "argocd-dex"
|
||||
)
|
||||
|
||||
func NewCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: cliName,
|
||||
Use: common.CommandDex,
|
||||
Short: "argocd-dex tools used by Argo CD",
|
||||
Long: "argocd-dex has internal utility tools used by Argo CD",
|
||||
DisableAutoGenTag: true,
|
||||
|
|
|
|||
|
|
@ -9,20 +9,16 @@ import (
|
|||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
"github.com/argoproj/argo-cd/v3/util/askpass"
|
||||
"github.com/argoproj/argo-cd/v3/util/errors"
|
||||
grpc_util "github.com/argoproj/argo-cd/v3/util/grpc"
|
||||
utilio "github.com/argoproj/argo-cd/v3/util/io"
|
||||
)
|
||||
|
||||
const (
|
||||
// cliName is the name of the CLI
|
||||
cliName = "argocd-git-ask-pass"
|
||||
)
|
||||
|
||||
func NewCommand() *cobra.Command {
|
||||
command := cobra.Command{
|
||||
Use: cliName,
|
||||
Use: common.CommandGitAskPass,
|
||||
Short: "Argo CD git credential helper",
|
||||
DisableAutoGenTag: true,
|
||||
Run: func(c *cobra.Command, _ []string) {
|
||||
|
|
|
|||
|
|
@ -2,15 +2,13 @@ package commands
|
|||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
cliName = "argocd-k8s-auth"
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
)
|
||||
|
||||
func NewCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: cliName,
|
||||
Use: common.CommandK8sAuth,
|
||||
Short: "argocd-k8s-auth a set of commands to generate k8s auth token",
|
||||
DisableAutoGenTag: true,
|
||||
Run: func(c *cobra.Command, args []string) {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func NewCommand() *cobra.Command {
|
|||
selfServiceNotificationEnabled bool
|
||||
)
|
||||
command := cobra.Command{
|
||||
Use: "controller",
|
||||
Use: common.CommandNotifications,
|
||||
Short: "Starts Argo CD Notifications controller",
|
||||
RunE: func(_ *cobra.Command, _ []string) error {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
|
@ -34,15 +34,11 @@ import (
|
|||
"github.com/argoproj/argo-cd/v3/util/gpg"
|
||||
"github.com/argoproj/argo-cd/v3/util/healthz"
|
||||
utilio "github.com/argoproj/argo-cd/v3/util/io"
|
||||
"github.com/argoproj/argo-cd/v3/util/profile"
|
||||
"github.com/argoproj/argo-cd/v3/util/tls"
|
||||
traceutil "github.com/argoproj/argo-cd/v3/util/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
// CLIName is the name of the CLI
|
||||
cliName = "argocd-repo-server"
|
||||
)
|
||||
|
||||
var (
|
||||
gnuPGSourcePath = env.StringFromEnv(common.EnvGPGDataPath, "/app/config/gpg/source")
|
||||
pauseGenerationAfterFailedGenerationAttempts = env.ParseNumFromEnv(common.EnvPauseGenerationAfterFailedAttempts, 3, 0, math.MaxInt32)
|
||||
|
|
@ -84,7 +80,7 @@ func NewCommand() *cobra.Command {
|
|||
enableBuiltinGitConfig bool
|
||||
)
|
||||
command := cobra.Command{
|
||||
Use: cliName,
|
||||
Use: common.CommandRepoServer,
|
||||
Short: "Run ArgoCD Repository Server",
|
||||
Long: "ArgoCD Repository Server is an internal service which maintains a local cache of the Git repository holding the application manifests, and is responsible for generating and returning the Kubernetes manifests. This command runs Repository Server in the foreground. It can be configured by following options.",
|
||||
DisableAutoGenTag: true,
|
||||
|
|
@ -177,7 +173,8 @@ func NewCommand() *cobra.Command {
|
|||
listener, err := lc.Listen(ctx, "tcp", fmt.Sprintf("%s:%d", listenHost, listenPort))
|
||||
errors.CheckError(err)
|
||||
|
||||
healthz.ServeHealthCheck(http.DefaultServeMux, func(r *http.Request) error {
|
||||
mux := http.NewServeMux()
|
||||
healthz.ServeHealthCheck(mux, func(r *http.Request) error {
|
||||
if val, ok := r.URL.Query()["full"]; ok && len(val) > 0 && val[0] == "true" {
|
||||
// connect to itself to make sure repo server is able to serve connection
|
||||
// used by liveness probe to auto restart repo server
|
||||
|
|
@ -199,8 +196,9 @@ func NewCommand() *cobra.Command {
|
|||
}
|
||||
return nil
|
||||
})
|
||||
http.Handle("/metrics", metricsServer.GetHandler())
|
||||
go func() { errors.CheckError(http.ListenAndServe(fmt.Sprintf("%s:%d", metricsHost, metricsPort), nil)) }()
|
||||
mux.Handle("/metrics", metricsServer.GetHandler())
|
||||
profile.RegisterProfiler(mux)
|
||||
go func() { errors.CheckError(http.ListenAndServe(fmt.Sprintf("%s:%d", metricsHost, metricsPort), mux)) }()
|
||||
go func() { errors.CheckError(askPassServer.Run()) }()
|
||||
|
||||
if gpg.IsGPGEnabled() {
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ func NewCommand() *cobra.Command {
|
|||
enableK8sEvent []string
|
||||
)
|
||||
command := &cobra.Command{
|
||||
Use: cliName,
|
||||
Use: common.CommandServer,
|
||||
Short: "Run the ArgoCD API server",
|
||||
Long: "The API server is a gRPC/REST server which exposes the API consumed by the Web UI, CLI, and CI/CD systems. This command runs API server in the foreground. It can be configured by following options.",
|
||||
DisableAutoGenTag: true,
|
||||
|
|
@ -307,7 +307,7 @@ func NewCommand() *cobra.Command {
|
|||
command.Flags().BoolVar(&disableAuth, "disable-auth", env.ParseBoolFromEnv("ARGOCD_SERVER_DISABLE_AUTH", false), "Disable client authentication")
|
||||
command.Flags().StringVar(&contentTypes, "api-content-types", env.StringFromEnv("ARGOCD_API_CONTENT_TYPES", "application/json", env.StringFromEnvOpts{AllowEmpty: true}), "Semicolon separated list of allowed content types for non GET api requests. Any content type is allowed if empty.")
|
||||
command.Flags().BoolVar(&enableGZip, "enable-gzip", env.ParseBoolFromEnv("ARGOCD_SERVER_ENABLE_GZIP", true), "Enable GZIP compression")
|
||||
command.AddCommand(cli.NewVersionCmd(cliName))
|
||||
command.AddCommand(cli.NewVersionCmd(common.CommandServer))
|
||||
command.Flags().StringVar(&listenHost, "address", env.StringFromEnv("ARGOCD_SERVER_LISTEN_ADDRESS", common.DefaultAddressAPIServer), "Listen on given address")
|
||||
command.Flags().IntVar(&listenPort, "port", common.DefaultPortAPIServer, "Listen on given port")
|
||||
command.Flags().StringVar(&metricsHost, env.StringFromEnv("ARGOCD_SERVER_METRICS_LISTEN_ADDRESS", "metrics-address"), common.DefaultAddressAPIServerMetrics, "Listen for metrics on given address")
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
package commands
|
||||
|
||||
const (
|
||||
// cliName is the name of the CLI
|
||||
cliName = "argocd-server"
|
||||
)
|
||||
|
|
@ -10,8 +10,8 @@ import (
|
|||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
"github.com/spf13/cobra"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ package admin
|
|||
import (
|
||||
"testing"
|
||||
|
||||
clustermocks "github.com/argoproj/gitops-engine/pkg/cache/mocks"
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
clustermocks "github.com/argoproj/argo-cd/gitops-engine/pkg/cache/mocks"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/util/security"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
"github.com/stretchr/testify/assert"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
"github.com/redis/go-redis/v9"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import (
|
|||
utilio "github.com/argoproj/argo-cd/v3/util/io"
|
||||
"github.com/argoproj/argo-cd/v3/util/templates"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
"github.com/spf13/cobra"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import (
|
|||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
healthutil "github.com/argoproj/gitops-engine/pkg/health"
|
||||
healthutil "github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ func getPolicy(ctx context.Context, policyFile string, kubeClient kubernetes.Int
|
|||
}
|
||||
|
||||
// getPolicyFromFile loads a RBAC policy from given path
|
||||
// nolint:unparam // complains about the error being always nil which is false-positive
|
||||
func getPolicyFromFile(policyFile string) (string, string, string, error) {
|
||||
var (
|
||||
userPolicy string
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@ import (
|
|||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/hook"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/ignore"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/hook"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/ignore"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/retry"
|
||||
"github.com/mattn/go-isatty"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
|
@ -46,7 +46,7 @@ import (
|
|||
argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient"
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apiclient/application"
|
||||
|
||||
resourceutil "github.com/argoproj/gitops-engine/pkg/sync/resource"
|
||||
resourceutil "github.com/argoproj/argo-cd/gitops-engine/pkg/sync/resource"
|
||||
|
||||
clusterpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster"
|
||||
projectpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/project"
|
||||
|
|
@ -3326,7 +3326,6 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob
|
|||
default:
|
||||
log.Fatalf("Unknown source type '%s'", source)
|
||||
}
|
||||
|
||||
for _, obj := range unstructureds {
|
||||
fmt.Println("---")
|
||||
yamlBytes, err := yaml.Marshal(obj)
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
"github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie
|
|||
)
|
||||
command := &cobra.Command{
|
||||
Use: "add CONTEXT",
|
||||
Short: cliName + " cluster add CONTEXT",
|
||||
Short: common.CommandCLI + " cluster add CONTEXT",
|
||||
Run: func(c *cobra.Command, args []string) {
|
||||
ctx := c.Context()
|
||||
|
||||
|
|
@ -549,7 +549,7 @@ argocd cluster list -o server <ARGOCD_SERVER_ADDRESS>
|
|||
func NewClusterRotateAuthCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: "rotate-auth SERVER/NAME",
|
||||
Short: cliName + " cluster rotate-auth SERVER/NAME",
|
||||
Short: common.CommandCLI + " cluster rotate-auth SERVER/NAME",
|
||||
Example: `argocd cluster rotate-auth https://12.34.567.89
|
||||
argocd cluster rotate-auth cluster-name`,
|
||||
Run: func(c *cobra.Command, args []string) {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
cliName = "argocd"
|
||||
|
||||
// DefaultSSOLocalPort is the localhost port to listen on for the temporary web server performing
|
||||
// the OAuth2 login flow.
|
||||
DefaultSSOLocalPort = 8085
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ func NewCommand() *cobra.Command {
|
|||
)
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: cliName,
|
||||
Use: common.CommandCLI,
|
||||
Short: "argocd controls a Argo CD server",
|
||||
Run: func(c *cobra.Command, args []string) {
|
||||
c.HelpFunc()(c, args)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import (
|
|||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
"k8s.io/apimachinery/pkg/util/duration"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ func NewVersionCmd(clientOpts *argocdclient.ClientOptions, serverVersion *versio
|
|||
v := make(map[string]any)
|
||||
|
||||
if short {
|
||||
v["client"] = map[string]string{cliName: cv.Version}
|
||||
v["client"] = map[string]string{common.CommandCLI: cv.Version}
|
||||
} else {
|
||||
v["client"] = cv
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ func getServerVersion(ctx context.Context, options *argocdclient.ClientOptions,
|
|||
}
|
||||
|
||||
func printClientVersion(version *common.Version, short bool) string {
|
||||
output := fmt.Sprintf("%s: %s\n", cliName, version)
|
||||
output := fmt.Sprintf("%s: %s\n", common.CommandCLI, version)
|
||||
if short {
|
||||
return output
|
||||
}
|
||||
|
|
|
|||
24
cmd/main.go
24
cmd/main.go
|
|
@ -20,6 +20,7 @@ import (
|
|||
reposerver "github.com/argoproj/argo-cd/v3/cmd/argocd-repo-server/commands"
|
||||
apiserver "github.com/argoproj/argo-cd/v3/cmd/argocd-server/commands"
|
||||
cli "github.com/argoproj/argo-cd/v3/cmd/argocd/commands"
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
"github.com/argoproj/argo-cd/v3/util/log"
|
||||
)
|
||||
|
||||
|
|
@ -43,33 +44,34 @@ func main() {
|
|||
isArgocdCLI := false
|
||||
|
||||
switch binaryName {
|
||||
case "argocd", "argocd-linux-amd64", "argocd-darwin-amd64", "argocd-windows-amd64.exe":
|
||||
case common.CommandCLI:
|
||||
command = cli.NewCommand()
|
||||
isArgocdCLI = true
|
||||
case "argocd-server":
|
||||
case common.CommandServer:
|
||||
command = apiserver.NewCommand()
|
||||
case "argocd-application-controller":
|
||||
case common.CommandApplicationController:
|
||||
command = appcontroller.NewCommand()
|
||||
case "argocd-repo-server":
|
||||
case common.CommandRepoServer:
|
||||
command = reposerver.NewCommand()
|
||||
case "argocd-cmp-server":
|
||||
case common.CommandCMPServer:
|
||||
command = cmpserver.NewCommand()
|
||||
isArgocdCLI = true
|
||||
case "argocd-commit-server":
|
||||
case common.CommandCommitServer:
|
||||
command = commitserver.NewCommand()
|
||||
case "argocd-dex":
|
||||
case common.CommandDex:
|
||||
command = dex.NewCommand()
|
||||
case "argocd-notifications":
|
||||
case common.CommandNotifications:
|
||||
command = notification.NewCommand()
|
||||
case "argocd-git-ask-pass":
|
||||
case common.CommandGitAskPass:
|
||||
command = gitaskpass.NewCommand()
|
||||
isArgocdCLI = true
|
||||
case "argocd-applicationset-controller":
|
||||
case common.CommandApplicationSetController:
|
||||
command = applicationset.NewCommand()
|
||||
case "argocd-k8s-auth":
|
||||
case common.CommandK8sAuth:
|
||||
command = k8sauth.NewCommand()
|
||||
isArgocdCLI = true
|
||||
default:
|
||||
// "argocd-linux-amd64", "argocd-darwin-amd64", "argocd-windows-amd64.exe" are also valid binary names
|
||||
command = cli.NewCommand()
|
||||
isArgocdCLI = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
|
||||
argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/util/config"
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import (
|
|||
argoexec "github.com/argoproj/argo-cd/v3/util/exec"
|
||||
"github.com/argoproj/argo-cd/v3/util/io/files"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
securejoin "github.com/cyphar/filepath-securejoin"
|
||||
"github.com/mattn/go-zglob"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
|
|
|||
|
|
@ -17,10 +17,19 @@ import (
|
|||
"k8s.io/client-go/kubernetes"
|
||||
)
|
||||
|
||||
// Component names
|
||||
// Argo CD component names
|
||||
const (
|
||||
ApplicationController = "argocd-application-controller"
|
||||
ApplicationSetController = "argocd-applicationset-controller"
|
||||
CommandCLI = "argocd"
|
||||
CommandApplicationController = "argocd-application-controller"
|
||||
CommandApplicationSetController = "argocd-applicationset-controller"
|
||||
CommandServer = "argocd-server"
|
||||
CommandCMPServer = "argocd-cmp-server"
|
||||
CommandCommitServer = "argocd-commit-server"
|
||||
CommandGitAskPass = "argocd-git-ask-pass"
|
||||
CommandNotifications = "argocd-notifications"
|
||||
CommandK8sAuth = "argocd-k8s-auth"
|
||||
CommandDex = "argocd-dex"
|
||||
CommandRepoServer = "argocd-repo-server"
|
||||
)
|
||||
|
||||
// Default service addresses and URLS of Argo CD internal services
|
||||
|
|
@ -108,7 +117,6 @@ const (
|
|||
|
||||
// Argo CD application related constants
|
||||
const (
|
||||
|
||||
// ArgoCDAdminUsername is the username of the 'admin' user
|
||||
ArgoCDAdminUsername = "admin"
|
||||
// ArgoCDUserAgentName is the default user-agent name used by the gRPC API client library and grpc-gateway
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
clustercache "github.com/argoproj/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/gitops-engine/pkg/diff"
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
resourceutil "github.com/argoproj/gitops-engine/pkg/sync/resource"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
clustercache "github.com/argoproj/argo-cd/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/diff"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
synccommon "github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
|
||||
resourceutil "github.com/argoproj/argo-cd/gitops-engine/pkg/sync/resource"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/sync/semaphore"
|
||||
|
|
@ -206,7 +206,7 @@ func NewApplicationController(
|
|||
statusRefreshJitter: appResyncJitter,
|
||||
refreshRequestedApps: make(map[string]CompareWith),
|
||||
refreshRequestedAppsMutex: &sync.Mutex{},
|
||||
auditLogger: argo.NewAuditLogger(kubeClientset, common.ApplicationController, enableK8sEvent),
|
||||
auditLogger: argo.NewAuditLogger(kubeClientset, common.CommandApplicationController, enableK8sEvent),
|
||||
settingsMgr: settingsMgr,
|
||||
selfHealTimeout: selfHealTimeout,
|
||||
selfHealBackoff: selfHealBackoff,
|
||||
|
|
@ -1138,13 +1138,13 @@ func (ctrl *ApplicationController) processProjectQueueItem() (processNext bool)
|
|||
}
|
||||
|
||||
func (ctrl *ApplicationController) finalizeProjectDeletion(proj *appv1.AppProject) error {
|
||||
apps, err := ctrl.appLister.Applications(ctrl.namespace).List(labels.Everything())
|
||||
apps, err := ctrl.appLister.List(labels.Everything())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error listing applications: %w", err)
|
||||
}
|
||||
appsCount := 0
|
||||
for i := range apps {
|
||||
if apps[i].Spec.GetProject() == proj.Name {
|
||||
if apps[i].Spec.GetProject() == proj.Name && ctrl.isAppNamespaceAllowed(apps[i]) && proj.IsAppNamespacePermitted(apps[i], ctrl.namespace) {
|
||||
appsCount++
|
||||
}
|
||||
}
|
||||
|
|
@ -1560,8 +1560,18 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli
|
|||
// if we just completed an operation, force a refresh so that UI will report up-to-date
|
||||
// sync/health information
|
||||
if _, err := cache.MetaNamespaceKeyFunc(app); err == nil {
|
||||
// force app refresh with using CompareWithLatest comparison type and trigger app reconciliation loop
|
||||
ctrl.requestAppRefresh(app.QualifiedName(), CompareWithLatestForceResolve.Pointer(), nil)
|
||||
var compareWith CompareWith
|
||||
if state.Operation.InitiatedBy.Automated {
|
||||
// Do not force revision resolution on automated operations because
|
||||
// this would cause excessive Ls-Remote requests on monorepo commits
|
||||
compareWith = CompareWithLatest
|
||||
} else {
|
||||
// Force app refresh with using most recent resolved revision after sync,
|
||||
// so UI won't show a just synced application being out of sync if it was
|
||||
// synced after commit but before app. refresh (see #18153)
|
||||
compareWith = CompareWithLatestForceResolve
|
||||
}
|
||||
ctrl.requestAppRefresh(app.QualifiedName(), compareWith.Pointer(), nil)
|
||||
} else {
|
||||
logCtx.WithError(err).Warn("Fails to requeue application")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
clustercache "github.com/argoproj/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube/kubetest"
|
||||
clustercache "github.com/argoproj/argo-cd/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube/kubetest"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
|
|
@ -24,9 +24,9 @@ import (
|
|||
statecache "github.com/argoproj/argo-cd/v3/controller/cache"
|
||||
"github.com/argoproj/argo-cd/v3/controller/sharding"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/cache/mocks"
|
||||
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/cache/mocks"
|
||||
synccommon "github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
|
|
@ -2313,6 +2313,93 @@ func TestFinalizeProjectDeletion_DoesNotHaveApplications(t *testing.T) {
|
|||
}, receivedPatch)
|
||||
}
|
||||
|
||||
func TestFinalizeProjectDeletion_HasApplicationInOtherNamespace(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
app.Namespace = "team-a"
|
||||
proj := &v1alpha1.AppProject{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: test.FakeArgoCDNamespace},
|
||||
Spec: v1alpha1.AppProjectSpec{
|
||||
SourceNamespaces: []string{"team-a"},
|
||||
},
|
||||
}
|
||||
ctrl := newFakeController(t.Context(), &fakeData{
|
||||
apps: []runtime.Object{app, proj},
|
||||
applicationNamespaces: []string{"team-a"},
|
||||
}, nil)
|
||||
|
||||
fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset)
|
||||
patched := false
|
||||
fakeAppCs.PrependReactor("patch", "*", func(_ kubetesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
patched = true
|
||||
return true, &v1alpha1.AppProject{}, nil
|
||||
})
|
||||
|
||||
err := ctrl.finalizeProjectDeletion(proj)
|
||||
require.NoError(t, err)
|
||||
assert.False(t, patched)
|
||||
}
|
||||
|
||||
func TestFinalizeProjectDeletion_IgnoresAppsInUnmonitoredNamespace(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
app.Namespace = "team-b"
|
||||
proj := &v1alpha1.AppProject{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: test.FakeArgoCDNamespace},
|
||||
}
|
||||
ctrl := newFakeController(t.Context(), &fakeData{
|
||||
apps: []runtime.Object{app, proj},
|
||||
applicationNamespaces: []string{"team-a"},
|
||||
}, nil)
|
||||
|
||||
fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset)
|
||||
receivedPatch := map[string]any{}
|
||||
fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
if patchAction, ok := action.(kubetesting.PatchAction); ok {
|
||||
require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch))
|
||||
}
|
||||
return true, &v1alpha1.AppProject{}, nil
|
||||
})
|
||||
|
||||
err := ctrl.finalizeProjectDeletion(proj)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, map[string]any{
|
||||
"metadata": map[string]any{
|
||||
"finalizers": nil,
|
||||
},
|
||||
}, receivedPatch)
|
||||
}
|
||||
|
||||
func TestFinalizeProjectDeletion_IgnoresAppsNotPermittedByProject(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
app.Namespace = "team-b"
|
||||
proj := &v1alpha1.AppProject{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: test.FakeArgoCDNamespace},
|
||||
Spec: v1alpha1.AppProjectSpec{
|
||||
SourceNamespaces: []string{"team-a"},
|
||||
},
|
||||
}
|
||||
ctrl := newFakeController(t.Context(), &fakeData{
|
||||
apps: []runtime.Object{app, proj},
|
||||
applicationNamespaces: []string{"team-a", "team-b"},
|
||||
}, nil)
|
||||
|
||||
fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset)
|
||||
receivedPatch := map[string]any{}
|
||||
fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
if patchAction, ok := action.(kubetesting.PatchAction); ok {
|
||||
require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch))
|
||||
}
|
||||
return true, &v1alpha1.AppProject{}, nil
|
||||
})
|
||||
|
||||
err := ctrl.finalizeProjectDeletion(proj)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, map[string]any{
|
||||
"metadata": map[string]any{
|
||||
"finalizers": nil,
|
||||
},
|
||||
}, receivedPatch)
|
||||
}
|
||||
|
||||
func TestProcessRequestedAppOperation_FailedNoRetries(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
app.Spec.Project = "default"
|
||||
|
|
@ -2557,6 +2644,41 @@ func TestProcessRequestedAppOperation_Successful(t *testing.T) {
|
|||
assert.Equal(t, CompareWithLatestForceResolve, level)
|
||||
}
|
||||
|
||||
func TestProcessRequestedAppAutomatedOperation_Successful(t *testing.T) {
|
||||
app := newFakeApp()
|
||||
app.Spec.Project = "default"
|
||||
app.Operation = &v1alpha1.Operation{
|
||||
Sync: &v1alpha1.SyncOperation{},
|
||||
InitiatedBy: v1alpha1.OperationInitiator{
|
||||
Automated: true,
|
||||
},
|
||||
}
|
||||
ctrl := newFakeController(t.Context(), &fakeData{
|
||||
apps: []runtime.Object{app, &defaultProj},
|
||||
manifestResponses: []*apiclient.ManifestResponse{{
|
||||
Manifests: []string{},
|
||||
}},
|
||||
}, nil)
|
||||
fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset)
|
||||
receivedPatch := map[string]any{}
|
||||
fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
if patchAction, ok := action.(kubetesting.PatchAction); ok {
|
||||
require.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch))
|
||||
}
|
||||
return true, &v1alpha1.Application{}, nil
|
||||
})
|
||||
|
||||
ctrl.processRequestedAppOperation(app)
|
||||
|
||||
phase, _, _ := unstructured.NestedString(receivedPatch, "status", "operationState", "phase")
|
||||
message, _, _ := unstructured.NestedString(receivedPatch, "status", "operationState", "message")
|
||||
assert.Equal(t, string(synccommon.OperationSucceeded), phase)
|
||||
assert.Equal(t, "successfully synced (no more tasks)", message)
|
||||
ok, level := ctrl.isRefreshRequested(ctrl.toAppKey(app.Name))
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, CompareWithLatest, level)
|
||||
}
|
||||
|
||||
func TestProcessRequestedAppOperation_SyncTimeout(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
|
|
|||
6
controller/cache/cache.go
vendored
6
controller/cache/cache.go
vendored
|
|
@ -16,9 +16,9 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
clustercache "github.com/argoproj/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
clustercache "github.com/argoproj/argo-cd/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/sync/semaphore"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
|
|
|||
8
controller/cache/cache_test.go
vendored
8
controller/cache/cache_test.go
vendored
|
|
@ -18,10 +18,10 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/gitops-engine/pkg/cache/mocks"
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/cache/mocks"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
|
|
|
|||
4
controller/cache/info.go
vendored
4
controller/cache/info.go
vendored
|
|
@ -9,8 +9,8 @@ import (
|
|||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/text"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/text"
|
||||
"github.com/cespare/xxhash/v2"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
|
|
|||
2
controller/cache/info_test.go
vendored
2
controller/cache/info_test.go
vendored
|
|
@ -4,7 +4,7 @@ import (
|
|||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
|
|
|||
4
controller/cache/mocks/LiveStateCache.go
generated
vendored
4
controller/cache/mocks/LiveStateCache.go
generated
vendored
|
|
@ -7,10 +7,10 @@ package mocks
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
cache0 "github.com/argoproj/argo-cd/v3/controller/cache"
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import (
|
|||
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
log "github.com/sirupsen/logrus"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import (
|
|||
"github.com/argoproj/argo-cd/v3/util/db"
|
||||
"github.com/argoproj/argo-cd/v3/util/settings"
|
||||
|
||||
clustercache "github.com/argoproj/gitops-engine/pkg/cache"
|
||||
clustercache "github.com/argoproj/argo-cd/gitops-engine/pkg/cache"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ package controller
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
hookutil "github.com/argoproj/gitops-engine/pkg/sync/hook"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/ignore"
|
||||
kubeutil "github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
hookutil "github.com/argoproj/argo-cd/gitops-engine/pkg/sync/hook"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/ignore"
|
||||
kubeutil "github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
synccommon "github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
|
|||
|
|
@ -3,12 +3,13 @@ package controller
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/hook"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/hook"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
log "github.com/sirupsen/logrus"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
|
@ -43,8 +44,12 @@ func isHookOfType(obj *unstructured.Unstructured, hookType HookType) bool {
|
|||
}
|
||||
|
||||
for k, v := range hookTypeAnnotations[hookType] {
|
||||
if val, ok := obj.GetAnnotations()[k]; ok && val == v {
|
||||
return true
|
||||
if val, ok := obj.GetAnnotations()[k]; ok {
|
||||
if slices.ContainsFunc(strings.Split(val, ","), func(item string) bool {
|
||||
return strings.TrimSpace(item) == v
|
||||
}) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -127,6 +127,16 @@ func TestIsPreDeleteHook(t *testing.T) {
|
|||
annot: map[string]string{"argocd.argoproj.io/hook": "PostDelete"},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "Helm PreDelete & PreDelete hook",
|
||||
annot: map[string]string{"helm.sh/hook": "pre-delete,post-delete"},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "ArgoCD PostDelete & PreDelete hook",
|
||||
annot: map[string]string{"argocd.argoproj.io/hook": "PostDelete,PreDelete"},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
@ -160,6 +170,16 @@ func TestIsPostDeleteHook(t *testing.T) {
|
|||
annot: map[string]string{"argocd.argoproj.io/hook": "PreDelete"},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "ArgoCD PostDelete & PreDelete hook",
|
||||
annot: map[string]string{"argocd.argoproj.io/hook": "PostDelete,PreDelete"},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "Helm PostDelete & PreDelete hook",
|
||||
annot: map[string]string{"helm.sh/hook": "post-delete,pre-delete"},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
@ -171,3 +191,38 @@ func TestIsPostDeleteHook(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiHookOfType(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
hookType []HookType
|
||||
annot map[string]string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "helm PreDelete & PostDelete hook",
|
||||
hookType: []HookType{PreDeleteHookType, PostDeleteHookType},
|
||||
annot: map[string]string{"helm.sh/hook": "pre-delete,post-delete"},
|
||||
expected: true,
|
||||
},
|
||||
|
||||
{
|
||||
name: "ArgoCD PreDelete & PostDelete hook",
|
||||
hookType: []HookType{PreDeleteHookType, PostDeleteHookType},
|
||||
annot: map[string]string{"argocd.argoproj.io/hook": "PreDelete,PostDelete"},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
obj := &unstructured.Unstructured{}
|
||||
obj.SetAnnotations(tt.annot)
|
||||
|
||||
for _, hookType := range tt.hookType {
|
||||
result := isHookOfType(obj, hookType)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
|
||||
commitclient "github.com/argoproj/argo-cd/v3/commitserver/apiclient"
|
||||
commitservermocks "github.com/argoproj/argo-cd/v3/commitserver/apiclient/mocks"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/cache"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"errors"
|
||||
"testing"
|
||||
|
||||
gitopsCache "github.com/argoproj/gitops-engine/pkg/cache"
|
||||
gitopsCache "github.com/argoproj/argo-cd/gitops-engine/pkg/cache"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
dbmocks "github.com/argoproj/argo-cd/v3/util/db/mocks"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/robfig/cron/v3"
|
||||
|
|
@ -300,12 +300,12 @@ func (m *MetricsServer) IncKubernetesRequest(app *argoappv1.Application, server,
|
|||
}
|
||||
|
||||
func (m *MetricsServer) IncRedisRequest(failed bool) {
|
||||
m.redisRequestCounter.WithLabelValues(m.hostname, common.ApplicationController, strconv.FormatBool(failed)).Inc()
|
||||
m.redisRequestCounter.WithLabelValues(m.hostname, common.CommandApplicationController, strconv.FormatBool(failed)).Inc()
|
||||
}
|
||||
|
||||
// ObserveRedisRequestDuration observes redis request duration
|
||||
func (m *MetricsServer) ObserveRedisRequestDuration(duration time.Duration) {
|
||||
m.redisRequestHistogram.WithLabelValues(m.hostname, common.ApplicationController).Observe(duration.Seconds())
|
||||
m.redisRequestHistogram.WithLabelValues(m.hostname, common.CommandApplicationController).Observe(duration.Seconds())
|
||||
}
|
||||
|
||||
// ObserveResourceEventsProcessingDuration observes resource events processing duration
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ import (
|
|||
|
||||
"github.com/argoproj/argo-cd/v3/util/db/mocks"
|
||||
|
||||
gitopsCache "github.com/argoproj/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
gitopsCache "github.com/argoproj/argo-cd/gitops-engine/pkg/cache"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ package sharding
|
|||
|
||||
import (
|
||||
"maps"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/util/db"
|
||||
)
|
||||
|
|
@ -61,6 +63,10 @@ func (sharding *ClusterSharding) IsManagedCluster(c *v1alpha1.Cluster) bool {
|
|||
if c == nil { // nil cluster (in-cluster) is always managed by current clusterShard
|
||||
return true
|
||||
}
|
||||
if skipReconcile, err := strconv.ParseBool(c.Annotations[common.AnnotationKeyAppSkipReconcile]); err == nil && skipReconcile {
|
||||
log.Debugf("Cluster %s has %s annotation set, skipping", c.Server, common.AnnotationKeyAppSkipReconcile)
|
||||
return false
|
||||
}
|
||||
clusterShard := 0
|
||||
if shard, ok := sharding.Shards[c.Server]; ok {
|
||||
clusterShard = shard
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
dbmocks "github.com/argoproj/argo-cd/v3/util/db/mocks"
|
||||
)
|
||||
|
|
@ -322,6 +323,28 @@ func TestClusterSharding_IsManagedCluster(t *testing.T) {
|
|||
}))
|
||||
}
|
||||
|
||||
func TestIsManagedCluster_SkipReconcileAnnotation(t *testing.T) {
|
||||
sharding := setupTestSharding(0, 1)
|
||||
sharding.Init(
|
||||
&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{{ID: "1", Server: "https://cluster1"}}},
|
||||
&v1alpha1.ApplicationList{},
|
||||
)
|
||||
|
||||
assert.True(t, sharding.IsManagedCluster(&v1alpha1.Cluster{Server: "https://cluster1"}))
|
||||
|
||||
assert.False(t, sharding.IsManagedCluster(&v1alpha1.Cluster{
|
||||
Server: "https://cluster1",
|
||||
Annotations: map[string]string{common.AnnotationKeyAppSkipReconcile: "true"},
|
||||
}))
|
||||
|
||||
assert.True(t, sharding.IsManagedCluster(&v1alpha1.Cluster{
|
||||
Server: "https://cluster1",
|
||||
Annotations: map[string]string{common.AnnotationKeyAppSkipReconcile: "false"},
|
||||
}))
|
||||
|
||||
assert.True(t, sharding.IsManagedCluster(nil))
|
||||
}
|
||||
|
||||
func TestClusterSharding_ClusterShardOfResourceShouldNotBeChanged(t *testing.T) {
|
||||
shard := 1
|
||||
replicas := 2
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package controller
|
|||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/syncwaves"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/syncwaves"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
. "github.com/argoproj/gitops-engine/pkg/utils/testing"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
|
||||
. "github.com/argoproj/argo-cd/gitops-engine/pkg/utils/testing"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,17 +11,17 @@ import (
|
|||
goSync "sync"
|
||||
"time"
|
||||
|
||||
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
synccommon "github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/diff"
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync"
|
||||
hookutil "github.com/argoproj/gitops-engine/pkg/sync/hook"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/ignore"
|
||||
resourceutil "github.com/argoproj/gitops-engine/pkg/sync/resource"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/syncwaves"
|
||||
kubeutil "github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/diff"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync"
|
||||
hookutil "github.com/argoproj/argo-cd/gitops-engine/pkg/sync/hook"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/ignore"
|
||||
resourceutil "github.com/argoproj/argo-cd/gitops-engine/pkg/sync/resource"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/syncwaves"
|
||||
kubeutil "github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
log "github.com/sirupsen/logrus"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ import (
|
|||
"time"
|
||||
|
||||
"dario.cat/mergo"
|
||||
cachemocks "github.com/argoproj/gitops-engine/pkg/cache/mocks"
|
||||
"github.com/argoproj/gitops-engine/pkg/health"
|
||||
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
. "github.com/argoproj/gitops-engine/pkg/utils/testing"
|
||||
cachemocks "github.com/argoproj/argo-cd/gitops-engine/pkg/cache/mocks"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/health"
|
||||
synccommon "github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
. "github.com/argoproj/argo-cd/gitops-engine/pkg/utils/testing"
|
||||
"github.com/sirupsen/logrus"
|
||||
logrustest "github.com/sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ import (
|
|||
|
||||
cdcommon "github.com/argoproj/argo-cd/v3/common"
|
||||
|
||||
gitopsDiff "github.com/argoproj/gitops-engine/pkg/diff"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
gitopsDiff "github.com/argoproj/argo-cd/gitops-engine/pkg/diff"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
log "github.com/sirupsen/logrus"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package controller
|
|||
import (
|
||||
"maps"
|
||||
|
||||
gitopscommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
gitopscommon "github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ import (
|
|||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/sync"
|
||||
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/sync"
|
||||
synccommon "github.com/argoproj/argo-cd/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/argo-cd/gitops-engine/pkg/utils/kube"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ If the build is failing at the `Build & cache Go code`, you need to make sure `m
|
|||
|
||||
### Why does the codegen step fail?
|
||||
|
||||
If the codegen step fails with "Check nothing has changed...", chances are high that you did not run `make codegen`, or did not commit the changes it made. You should double-check by running `make codegen` followed by `git status` in the local working copy of your branch. Commit any changes and push them to your GH branch to have the CI check it again.
|
||||
If the codegen step fails with "Check nothing has changed...", chances are high that you did not run `make codegen-local`, or did not commit the changes it made. You should double-check by running `make codegen-local` followed by `git status` in the local working copy of your branch. Commit any changes and push them to your GH branch to have the CI check it again.
|
||||
|
||||
A second common case for this is, when you modified any of the auto generated assets, as these will be overwritten upon `make codegen`.
|
||||
A second common case for this is, when you modified any of the auto generated assets, as these will be overwritten upon `make codegen-local`.
|
||||
|
||||
Generally, this step runs `codegen` and compares the outcome against the Git branch it has checked out. If there are differences, the step will fail.
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ After your Notifications Engine PR has been merged, ArgoCD needs to be updated t
|
|||
|
||||
- If your notifications engine PR included docs changes, run `make codegen` or `make codegen-local`.
|
||||
|
||||
- Create an ArgoCD PR with a `refactor:` type in its title for the above file changes.
|
||||
- Create an ArgoCD PR with a `chore:` type in its title for the above file changes.
|
||||
|
||||
## Argo UI Components (`github.com/argoproj/argo-ui`)
|
||||
### Contributing to Argo CD UI
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ These are the upcoming releases dates:
|
|||
| v3.1 | Monday, Jun. 16, 2025 | Monday, Aug. 4, 2025 | [Christian Hernandez](https://github.com/christianh814) | [Alexandre Gaudreault](https://github.com/agaudreault) | [checklist](https://github.com/argoproj/argo-cd/issues/23347) |
|
||||
| v3.2 | Monday, Sep. 15, 2025 | Monday, Nov. 3, 2025 | [Nitish Kumar](https://github.com/nitishfy) | [Michael Crenshaw](https://github.com/crenshaw-dev) | [checklist](https://github.com/argoproj/argo-cd/issues/24539) |
|
||||
| v3.3 | Monday, Dec. 15, 2025 | Monday, Feb. 2, 2026 | [Peter Jiang](https://github.com/pjiang-dev) | [Regina Voloshin](https://github.com/reggie-k) | [checklist](https://github.com/argoproj/argo-cd/issues/25211) |
|
||||
| v3.4 | Monday, Mar. 16, 2026 | Monday, May. 4, 2026 | [Codey Jenkins](https://github.com/FourFifthsCode) | |
|
||||
| v3.4 | Monday, Mar. 16, 2026 | Monday, May. 4, 2026 | [Codey Jenkins](https://github.com/FourFifthsCode) | [Regina Voloshin](https://github.com/reggie-k) | [checklist](https://github.com/argoproj/argo-cd/issues/26527)
|
||||
| v3.5 | Monday, Jun. 15, 2026 | Monday, Aug. 3, 2026 | | |
|
||||
|
||||
Actual release dates might differ from the plan by a few days.
|
||||
|
|
|
|||
|
|
@ -49,10 +49,13 @@ Please use a meaningful and concise title for your PR. This will help us to pick
|
|||
|
||||
We use [PR title checker](https://github.com/marketplace/actions/pr-title-checker) to categorize your PR into one of the following categories:
|
||||
|
||||
* `ci` - Your PR updates or improves Continuous Integration workflows
|
||||
* `fix` - Your PR contains one or more code bug fixes
|
||||
* `feat` - Your PR contains a new feature
|
||||
* `test` - Your PR adds tests to the code base, or improves existing tests
|
||||
* `docs` - Your PR improves the documentation
|
||||
* `chore` - Your PR improves any internals of Argo CD, such as the build process, unit tests, etc
|
||||
* `refactor` - Your PR refactors the code base, without adding new features or fixing bugs
|
||||
|
||||
Please prefix the title of your PR with one of the valid categories. For example, if you chose the title your PR `Add documentation for GitHub SSO integration`, please use `docs: Add documentation for GitHub SSO integration` instead.
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ kubectl get svc argocd-server -n argocd -o=jsonpath='{.status.loadBalancer.ingre
|
|||
Follow the [ingress documentation](operator-manual/ingress.md) on how to configure Argo CD with ingress.
|
||||
|
||||
### Port Forwarding
|
||||
Kubectl port-forwarding can also be used to connect to the API server without exposing the service.
|
||||
`kubectl port-forward` can also be used to connect to the API server without exposing the service.
|
||||
|
||||
```bash
|
||||
kubectl port-forward svc/argocd-server -n argocd 8080:443
|
||||
|
|
@ -93,7 +93,7 @@ kubectl port-forward svc/argocd-server -n argocd 8080:443
|
|||
The API server can then be accessed using https://localhost:8080
|
||||
|
||||
|
||||
## 4. Login Using The CLI
|
||||
## 4. Log in Using The CLI
|
||||
|
||||
The initial password for the `admin` account is auto-generated and stored as
|
||||
clear text in the field `password` in a secret named `argocd-initial-admin-secret`
|
||||
|
|
@ -111,7 +111,7 @@ argocd admin initial-password -n argocd
|
|||
> safely be deleted at any time. It will be re-created on demand by Argo CD
|
||||
> if a new admin password must be re-generated.
|
||||
|
||||
Using the username `admin` and the password from above, login to Argo CD's IP or hostname:
|
||||
Using the username `admin` and the password from above, log in to Argo CD's IP or hostname:
|
||||
|
||||
```bash
|
||||
argocd login <ARGOCD_SERVER>
|
||||
|
|
@ -126,7 +126,7 @@ Change the password using the command:
|
|||
argocd account update-password
|
||||
```
|
||||
|
||||
## 5. Register A Cluster To Deploy Apps To (Optional)
|
||||
## 5. Register a Cluster to Deploy Apps To (Optional)
|
||||
|
||||
This step registers a cluster's credentials to Argo CD, and is only necessary when deploying to
|
||||
an external cluster. When deploying internally (to the same cluster that Argo CD is running in),
|
||||
|
|
@ -161,7 +161,7 @@ An example repository containing a guestbook application is available at
|
|||
|
||||
### Creating Apps Via CLI
|
||||
|
||||
First we need to set the current namespace to argocd running the following command:
|
||||
First, set the current namespace to argocd by running the following command:
|
||||
|
||||
```bash
|
||||
kubectl config set-context --current --namespace=argocd
|
||||
|
|
|
|||
|
|
@ -279,6 +279,8 @@ data:
|
|||
# _grpc_config.<hostname> are disabled to prevent excessive DNS queries that can cause timeouts in dual-stack environments.
|
||||
# See https://github.com/argoproj/argo-cd/issues/24991
|
||||
reposerver.grpc.enable.txt.service.config: "false"
|
||||
# Enables profile endpoint on the internal metrics port
|
||||
reposerver.profile.enabled: "false"
|
||||
|
||||
## Commit-server properties
|
||||
# Listen on given address for incoming connections (default "0.0.0.0")
|
||||
|
|
|
|||
|
|
@ -13,6 +13,23 @@ If you're unsure about the context names, run `kubectl config get-contexts` to g
|
|||
This will connect to the cluster and install the necessary resources for ArgoCD to connect to it.
|
||||
Note that you will need privileged access to the cluster.
|
||||
|
||||
## Skipping cluster reconciliation
|
||||
|
||||
You can stop the controller from reconciling a cluster without removing it by annotating its secret:
|
||||
|
||||
```bash
|
||||
kubectl -n argocd annotate secret <cluster-secret-name> argocd.argoproj.io/skip-reconcile=true
|
||||
```
|
||||
|
||||
The cluster will still appear in `argocd cluster list` but the controller will skip reconciliation
|
||||
for all apps targeting it. To resume, remove the annotation:
|
||||
|
||||
```bash
|
||||
kubectl -n argocd annotate secret <cluster-secret-name> argocd.argoproj.io/skip-reconcile-
|
||||
```
|
||||
|
||||
See [Declarative Setup - Skipping Cluster Reconciliation](./declarative-setup.md#skipping-cluster-reconciliation) for details.
|
||||
|
||||
## Removing a cluster
|
||||
|
||||
Run `argocd cluster rm context-name`.
|
||||
|
|
|
|||
|
|
@ -595,6 +595,49 @@ stringData:
|
|||
}
|
||||
```
|
||||
|
||||
### Skipping Cluster Reconciliation
|
||||
|
||||
You can prevent the application controller from reconciling all apps targeting a cluster by annotating its
|
||||
secret with `argocd.argoproj.io/skip-reconcile: "true"`. This uses the same annotation as
|
||||
[Skip Application Reconcile](../user-guide/skip_reconcile.md), but applied at the cluster level.
|
||||
|
||||
The cluster remains visible in API responses (`argocd cluster list`), but the controller treats it as unmanaged.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: mycluster-secret
|
||||
labels:
|
||||
argocd.argoproj.io/secret-type: cluster
|
||||
annotations:
|
||||
argocd.argoproj.io/skip-reconcile: "true"
|
||||
type: Opaque
|
||||
stringData:
|
||||
name: mycluster.example.com
|
||||
server: https://mycluster.example.com
|
||||
config: |
|
||||
{
|
||||
"bearerToken": "<authentication token>",
|
||||
"tlsClientConfig": {
|
||||
"insecure": false,
|
||||
"caData": "<base64 encoded certificate>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To skip an existing cluster:
|
||||
|
||||
```bash
|
||||
kubectl -n argocd annotate secret mycluster-secret argocd.argoproj.io/skip-reconcile=true
|
||||
```
|
||||
|
||||
To resume reconciliation:
|
||||
|
||||
```bash
|
||||
kubectl -n argocd annotate secret mycluster-secret argocd.argoproj.io/skip-reconcile-
|
||||
```
|
||||
|
||||
### EKS
|
||||
|
||||
EKS cluster secret example using argocd-k8s-auth and [IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) and [Pod Identity](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html):
|
||||
|
|
|
|||
|
|
@ -44,9 +44,9 @@ to indicate their stability and maturity. These are the statuses of non-stable f
|
|||
### ApplicationSet CRD
|
||||
|
||||
| Feature | Property | Status |
|
||||
| ----------------------------- | ---------------------------- | ------ |
|
||||
| [AppSet Progressive Syncs][2] | `spec.strategy.*` | Alpha |
|
||||
| [AppSet Progressive Syncs][2] | `status.applicationStatus.*` | Alpha |
|
||||
| ----------------------------- | ---------------------------- |--------|
|
||||
| [AppSet Progressive Syncs][2] | `spec.strategy.*` | Beta |
|
||||
| [AppSet Progressive Syncs][2] | `status.applicationStatus.*` | Beta |
|
||||
|
||||
### Configuration
|
||||
|
||||
|
|
@ -58,11 +58,11 @@ to indicate their stability and maturity. These are the statuses of non-stable f
|
|||
| [AppSets in any Namespace][5] | `Deployment/argocd-applicationset-controller` | `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_SCM_PROVIDERS` | Beta |
|
||||
| [AppSets in any Namespace][5] | `Deployment/argocd-applicationset-controller` | `ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES` | Beta |
|
||||
| [AppSets in any Namespace][5] | `ConfigMap/argocd-cmd-params-cm` | `applicationsetcontroller.namespaces` | Beta |
|
||||
| [AppSet Progressive Syncs][2] | `ConfigMap/argocd-cmd-params-cm` | `applicationsetcontroller.enable.progressive.syncs` | Alpha |
|
||||
| [AppSet Progressive Syncs][2] | `Deployment/argocd-applicationset-controller` | `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCS` | Alpha |
|
||||
| [Proxy Extensions][3] | `ConfigMap/argocd-cmd-params-cm` | `server.enable.proxy.extension` | Alpha |
|
||||
| [Proxy Extensions][3] | `Deployment/argocd-server` | `ARGOCD_SERVER_ENABLE_PROXY_EXTENSION` | Alpha |
|
||||
| [Proxy Extensions][3] | `ConfigMap/argocd-cm` | `extension.config` | Alpha |
|
||||
| [AppSet Progressive Syncs][2] | `ConfigMap/argocd-cmd-params-cm` | `applicationsetcontroller.enable.progressive.syncs` | Beta |
|
||||
| [AppSet Progressive Syncs][2] | `Deployment/argocd-applicationset-controller` | `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCS` | Beta |
|
||||
| [Proxy Extensions][3] | `ConfigMap/argocd-cmd-params-cm` | `server.enable.proxy.extension` | Beta |
|
||||
| [Proxy Extensions][3] | `Deployment/argocd-server` | `ARGOCD_SERVER_ENABLE_PROXY_EXTENSION` | Beta |
|
||||
| [Proxy Extensions][3] | `ConfigMap/argocd-cm` | `extension.config` | Beta |
|
||||
| [Dynamic Cluster Distribution][7] | `Deployment/argocd-application-controller` | `ARGOCD_ENABLE_DYNAMIC_CLUSTER_DISTRIBUTION` | Alpha |
|
||||
| [Dynamic Cluster Distribution][7] | `Deployment/argocd-application-controller` | `ARGOCD_CONTROLLER_HEARTBEAT_TIME` | Alpha |
|
||||
| [Cluster Sharding: round-robin][6] | `ConfigMap/argocd-cmd-params-cm` | `controller.sharding.algorithm: round-robin` | Alpha |
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
# High Availability
|
||||
|
||||
Argo CD is largely stateless. All data is persisted as Kubernetes objects, which in turn is stored in Kubernetes' etcd.
|
||||
Redis is only used as a throw-away cache and can be lost. When lost, it will be rebuilt without loss of service.
|
||||
Redis is only used as a disposable cache and can be safely rebuilt without service disruption.
|
||||
|
||||
A set of [HA manifests](https://github.com/argoproj/argo-cd/tree/stable/manifests/ha) are provided for users who wish to
|
||||
run Argo CD in a highly available manner. This runs more containers, and runs Redis in HA mode.
|
||||
|
||||
> [!NOTE]
|
||||
> The HA installation will require at least three different nodes due to pod anti-affinity roles in the
|
||||
> The HA installation will require at least three different nodes due to pod anti-affinity rule in the
|
||||
> specs. Additionally, IPv6 only clusters are not supported.
|
||||
|
||||
## Scaling Up
|
||||
|
|
@ -19,17 +19,17 @@ run Argo CD in a highly available manner. This runs more containers, and runs Re
|
|||
The `argocd-repo-server` is responsible for cloning Git repository, keeping it up to date and generating manifests using
|
||||
the appropriate tool.
|
||||
|
||||
* `argocd-repo-server` fork/exec config management tool to generate manifests. The fork can fail due to lack of memory
|
||||
* `argocd-repo-server` fork/exec config management tools to generate manifests. The fork can fail due to lack of memory
|
||||
or limit on the number of OS threads.
|
||||
The `--parallelismlimit` flag controls how many manifests generations are running concurrently and helps avoid OOM
|
||||
kills.
|
||||
|
||||
* the `argocd-repo-server` ensures that repository is in the clean state during the manifest generation using config
|
||||
* The `argocd-repo-server` ensures that repository is in the clean state during the manifest generation using config
|
||||
management tools such as Kustomize, Helm
|
||||
or custom plugin. As a result Git repositories with multiple applications might affect repository server performance.
|
||||
Read [Monorepo Scaling Considerations](#monorepo-scaling-considerations) for more information.
|
||||
|
||||
* `argocd-repo-server` clones the repository into `/tmp` (or the path specified in the `TMPDIR` env variable). The Pod
|
||||
* `argocd-repo-server` clones the repository into `/tmp` (or the path specified in the `TMPDIR` env variable). The pod
|
||||
might run out of disk space if it has too many repositories
|
||||
or if the repositories have a lot of files. To avoid this problem mount a persistent volume.
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ get the actual cluster state.
|
|||
syncing (seconds). The number of queue processors for each queue is controlled by
|
||||
`--status-processors` (20 by default) and `--operation-processors` (10 by default) flags. Increase the number of
|
||||
processors if your Argo CD instance manages too many applications.
|
||||
For 1000 application we use 50 for `--status-processors` and 25 for `--operation-processors`
|
||||
For 1000 applications, we use 50 for `--status-processors` and 25 for `--operation-processors`
|
||||
|
||||
* The manifest generation typically takes the most time during reconciliation. The duration of manifest generation is
|
||||
limited to make sure the controller refresh queue does not overflow.
|
||||
|
|
@ -139,7 +139,7 @@ spec:
|
|||
and also reduces cluster or application reshuffling in case of additions or removals of shards or clusters.
|
||||
|
||||
The `--sharding-method` parameter can also be overridden by setting the key `controller.sharding.algorithm` in the
|
||||
`argocd-cmd-params-cm` `configMap` (preferably) or by setting the `ARGOCD_CONTROLLER_SHARDING_ALGORITHM` environment
|
||||
`argocd-cmd-params-cm` `ConfigMap` (preferably) or by setting the `ARGOCD_CONTROLLER_SHARDING_ALGORITHM` environment
|
||||
variable and by specifying the same possible values.
|
||||
|
||||
> [!WARNING]
|
||||
|
|
@ -148,7 +148,7 @@ variable and by specifying the same possible values.
|
|||
> The `round-robin` shard distribution algorithm is an experimental feature. Reshuffling is known to occur in certain
|
||||
> scenarios with cluster removal. If the cluster at rank-0 is removed, reshuffling all clusters across shards will occur
|
||||
> and may temporarily have negative performance impacts.
|
||||
> The `consistent-hashing` shard distribution algorithm is an experimental feature. Extensive benchmark have been
|
||||
> The `consistent-hashing` shard distribution algorithm is an experimental feature. Extensive benchmarks have been
|
||||
> documented on the [CNOE blog](https://cnoe.io/blog/argo-cd-application-scalability) with encouraging results.
|
||||
> Community
|
||||
> feedback is highly appreciated before moving this feature to a production ready state.
|
||||
|
|
@ -182,7 +182,7 @@ stringData:
|
|||
if you need to troubleshoot performance issues. Note: This metric is expensive to both query and store!
|
||||
|
||||
* `ARGOCD_CLUSTER_CACHE_LIST_PAGE_BUFFER_SIZE` - environment variable controlling the number of pages the controller
|
||||
buffers in memory when performing a list operation against the K8s api server while syncing the cluster cache. This
|
||||
buffers in memory when performing a list operation against the K8s Api server while syncing the cluster cache. This
|
||||
is useful when the cluster contains a large number of resources and cluster sync times exceed the default etcd
|
||||
compaction interval timeout. In this scenario, when attempting to sync the cluster cache, the application controller
|
||||
may throw an error that the `continue parameter is too old to display a consistent list result`. Setting a higher
|
||||
|
|
@ -255,14 +255,14 @@ spec:
|
|||
|
||||
### argocd-dex-server, argocd-redis
|
||||
|
||||
The `argocd-dex-server` uses an in-memory database, and two or more instances would have inconsistent data.
|
||||
The `argocd-dex-server` uses an in-memory database, and two or more instances may have inconsistent data.
|
||||
`argocd-redis` is pre-configured with the understanding of only three total redis servers/sentinels.
|
||||
|
||||
## Monorepo Scaling Considerations
|
||||
|
||||
Argo CD repo server maintains one repository clone locally and uses it for application manifest generation. If the
|
||||
manifest generation requires to change a file in the local repository clone then only one concurrent manifest generation
|
||||
per server instance is allowed. This limitation might significantly slowdown Argo CD if you have a mono repository with
|
||||
per server instance is allowed. This limitation might significantly slow down Argo CD if you have a monorepo with
|
||||
multiple applications (50+).
|
||||
|
||||
### Enable Concurrent Processing
|
||||
|
|
@ -280,8 +280,8 @@ The following are known cases that might cause slowness and their workarounds:
|
|||
`.argocd-allow-concurrency` file in the app directory, or use the sidecar plugin option, which processes each
|
||||
application using a temporary copy of the repository.
|
||||
|
||||
* **Multiple Kustomize applications in same repository with [parameter overrides](../user-guide/parameters.md):** sorry,
|
||||
no workaround for now.
|
||||
* **Multiple Kustomize applications in same repository with [parameter overrides](../user-guide/parameters.md):** Currently,
|
||||
there is no workaround for this limitation.
|
||||
|
||||
### Manifest Paths Annotation
|
||||
|
||||
|
|
@ -522,12 +522,12 @@ Not all HTTP responses are eligible for retries. The following conditions will n
|
|||
|
||||
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
|
||||
The profiling endpoint is available on the 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`, `applicationsetcontroller.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:
|
||||
`server.profile.enabled`, `applicationsetcontroller.profile.enabled`, `reposerver.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 the go profile tool to collect the CPU and memory profiles. Example:
|
||||
|
||||
```bash
|
||||
$ kubectl port-forward svc/argocd-metrics 8082:8082
|
||||
|
|
|
|||
|
|
@ -1,19 +1,21 @@
|
|||
# Ingress Configuration
|
||||
|
||||
Argo CD API server runs both a gRPC server (used by the CLI), as well as a HTTP/HTTPS server (used by the UI).
|
||||
Argo CD API server runs both a gRPC server (used by the CLI), as well as an HTTP/HTTPS server (used by the UI).
|
||||
Both protocols are exposed by the argocd-server service object on the following ports:
|
||||
|
||||
* 443 - gRPC/HTTPS
|
||||
* 80 - HTTP (redirects to HTTPS)
|
||||
|
||||
There are several ways how Ingress can be configured.
|
||||
There are several ways to configure Ingress.
|
||||
|
||||
## [Ambassador](https://www.getambassador.io/)
|
||||
|
||||
The Ambassador Edge Stack can be used as a Kubernetes ingress controller with [automatic TLS termination](https://www.getambassador.io/docs/latest/topics/running/tls/#host) and routing capabilities for both the CLI and the UI.
|
||||
|
||||
The API server should be run with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md). Given the `argocd` CLI includes the port number in the request `host` header, 2 Mappings are required.
|
||||
Note: Disabling TLS in not required if you are using grpc-web
|
||||
The API server should be run with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md). Given the `argocd` CLI includes the port number in the request `host` header, two Mappings are required.
|
||||
|
||||
> [!NOTE]
|
||||
> Disabling TLS is not required if you are using gRPC-Web.
|
||||
|
||||
### Option 1: Mapping CRD for Host-based Routing
|
||||
```yaml
|
||||
|
|
@ -375,7 +377,7 @@ Traefik can be used as an edge router and provide [TLS](https://docs.traefik.io/
|
|||
|
||||
It currently has an advantage over NGINX in that it can terminate both TCP and HTTP connections _on the same port_ meaning you do not require multiple hosts or paths.
|
||||
|
||||
The API server should be run with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command or set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md).
|
||||
Run the API server with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command or set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md).
|
||||
|
||||
### IngressRoute CRD
|
||||
```yaml
|
||||
|
|
@ -476,7 +478,7 @@ Also note that we can configure the health check to return the gRPC health statu
|
|||
```
|
||||
|
||||
## [Istio](https://www.istio.io)
|
||||
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
|
||||
You can put Argo CD behind Istio using the following configuration. This example serves Argo CD behind Istio and uses a subpath (for example, `/argocd`).
|
||||
|
||||
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
|
||||
|
||||
|
|
@ -484,7 +486,7 @@ First we need to make sure that we can run Argo CD with subpath (ie /argocd). Fo
|
|||
curl -kLs -o install.yaml https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
|
||||
```
|
||||
|
||||
save following file as kustomization.yml
|
||||
Save the following file as `kustomization.yaml`:
|
||||
|
||||
```yaml
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
|
|
@ -528,7 +530,7 @@ spec:
|
|||
value: "0"
|
||||
```
|
||||
|
||||
After that install Argo CD (there should be only 3 yml file defined above in current directory )
|
||||
Install Argo CD (there should be only the three YAML files defined above in the current directory):
|
||||
|
||||
```bash
|
||||
kubectl apply -k ./ -n argocd --wait=true
|
||||
|
|
@ -598,7 +600,7 @@ spec:
|
|||
number: 80
|
||||
```
|
||||
|
||||
And now we can browse http://{{ IP }}/argocd (it will be rewritten to https://{{ IP }}/argocd
|
||||
You can now browse to `http://<IP>/argocd` (it will be redirected to HTTPS).
|
||||
|
||||
|
||||
## Google Cloud load balancers with Kubernetes Ingress
|
||||
|
|
@ -648,7 +650,7 @@ spec:
|
|||
|
||||
### Creating a BackendConfig
|
||||
|
||||
See that previous service referencing a backend config called `argocd-backend-config`? So lets deploy it using this yaml:
|
||||
See that previous service referencing a backend config called `argocd-backend-config`? So let's deploy it using this YAML:
|
||||
|
||||
```yaml
|
||||
apiVersion: cloud.google.com/v1
|
||||
|
|
@ -777,7 +779,7 @@ Argo CD endpoints may be protected by one or more reverse proxies layers, in tha
|
|||
$ argocd login <host>:<port> --header 'x-token1:foo' --header 'x-token2:bar' # can be repeated multiple times
|
||||
$ argocd login <host>:<port> --header 'x-token1:foo,x-token2:bar' # headers can also be comma separated
|
||||
```
|
||||
## ArgoCD Server and UI Root Path (v1.5.3)
|
||||
## Argo CD server and UI root path (v1.5.3)
|
||||
|
||||
Argo CD server and UI can be configured to be available under a non-root path (e.g. `/argo-cd`).
|
||||
To do this, add the `--rootpath` flag into the `argocd-server` deployment command:
|
||||
|
|
@ -823,7 +825,7 @@ http {
|
|||
}
|
||||
}
|
||||
```
|
||||
Flag ```--grpc-web-root-path ``` is used to provide a non-root path (e.g. /argo-cd)
|
||||
The `--grpc-web-root-path` flag is used to provide a non-root path (e.g. /argo-cd)
|
||||
|
||||
```shell
|
||||
$ argocd login <host>:<port> --grpc-web-root-path /argo-cd
|
||||
|
|
@ -881,12 +883,12 @@ http {
|
|||
## Gateway API Example
|
||||
|
||||
This section discusses using Gateway API to expose the Argo CD server in various TLS configurations,
|
||||
accomodating both HTTP and gRPC traffic, possibly using HTTP/2.
|
||||
accommodating both HTTP and gRPC traffic, possibly using HTTP/2.
|
||||
|
||||
### TLS termination at the Gateway
|
||||
|
||||
Assume the following cluster-wide `Gateway` resource,
|
||||
that terminates the TLS conection with a certificate stored in a `Secret` in the same namespace:
|
||||
that terminates the TLS connection with a certificate stored in a `Secret` in the same namespace:
|
||||
|
||||
```yaml
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
|
|
@ -1000,7 +1002,7 @@ server:
|
|||
servicePortHttpsAppProtocol: kubernetes.io/h2c
|
||||
```
|
||||
|
||||
##### Routing gRPC and HTTP on through the same domain
|
||||
##### Routing gRPC and HTTP through the same domain
|
||||
|
||||
Although officially [discouraged](https://gateway-api.sigs.k8s.io/api-types/grpcroute/#cross-serving),
|
||||
attaching the `HTTPRoute` and `GRPCRoute` to the same domain may be supported by some implementations.
|
||||
|
|
@ -1033,7 +1035,7 @@ spec:
|
|||
|
||||
TLS can also be configured to terminate at the Argo CD API server.
|
||||
|
||||
This require attaching a `TLSRoute` to the gateway,
|
||||
This requires attaching a `TLSRoute` to the gateway,
|
||||
which is part of the [Experimental](https://gateway-api.sigs.k8s.io/reference/1.4/specx/) Gateway API CRDs.
|
||||
|
||||
```yaml
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Installation
|
||||
|
||||
Argo CD has two type of installations: multi-tenant and core.
|
||||
Argo CD has two types of installations: multi-tenant and core.
|
||||
|
||||
## Multi-Tenant
|
||||
|
||||
|
|
@ -11,9 +11,9 @@ The end-users can access Argo CD via the API server using the Web UI or `argocd`
|
|||
|
||||
Two types of installation manifests are provided:
|
||||
|
||||
### Non High Availability:
|
||||
### Non-High Availability:
|
||||
|
||||
Not recommended for production use. This type of installation is typically used during evaluation period for demonstrations and testing.
|
||||
Not recommended for production use. This type of installation is typically used during an evaluation period for demonstrations and testing.
|
||||
|
||||
* [install.yaml](https://github.com/argoproj/argo-cd/blob/stable/manifests/install.yaml) - Standard Argo CD installation with cluster-admin access. Use this
|
||||
manifest set if you plan to use Argo CD to deploy applications in the same cluster that Argo CD runs
|
||||
|
|
@ -30,7 +30,7 @@ Not recommended for production use. This type of installation is typically used
|
|||
on inputted cluster credentials. An example of using this set of manifests is if you run several
|
||||
Argo CD instances for different teams, where each instance will be deploying applications to
|
||||
external clusters. It will still be possible to deploy to the same cluster (kubernetes.svc.default)
|
||||
with inputted credentials (i.e. `argocd cluster add <CONTEXT> --in-cluster --namespace <YOUR NAMESPACE>`).
|
||||
with provided credentials (i.e. `argocd cluster add <CONTEXT> --in-cluster --namespace <YOUR NAMESPACE>`).
|
||||
With the default roles included, you will only be able to deploy Argo CD resources (Applications, ApplicationSets
|
||||
and AppProjects) in the same cluster, as it's only supporting the GitOps mode with real deployments being
|
||||
done to external clusters.
|
||||
|
|
@ -60,13 +60,13 @@ The Argo CD Core installation is primarily used to deploy Argo CD in
|
|||
headless mode. This type of installation is most suitable for cluster
|
||||
administrators who independently use Argo CD and don't need
|
||||
multi-tenancy features. This installation includes fewer components
|
||||
and is easier to setup. The bundle does not include the API server or
|
||||
and is easier to set up. The bundle does not include the API server or
|
||||
UI, and installs the lightweight (non-HA) version of each component.
|
||||
|
||||
Installation manifest is available at [core-install.yaml](https://github.com/argoproj/argo-cd/blob/stable/manifests/core-install.yaml).
|
||||
|
||||
For more details about Argo CD Core please refer to the [official
|
||||
documentation](./core.md)
|
||||
documentation](./core.md).
|
||||
|
||||
## Kustomize
|
||||
|
||||
|
|
|
|||
|
|
@ -115,3 +115,6 @@ template.app-deployed: |
|
|||
- The `github.pullRequestComment.commentTag` parameter is used to identify the comment. If a comment with the specified tag is found, it will be updated (upserted). If no comment with the tag is found, a new comment will be created.
|
||||
- Reference is optional. When set, it will be used as the ref to deploy. If not set, the revision will be used as the ref to deploy.
|
||||
|
||||
## Commit Statuses
|
||||
|
||||
The [method for generating commit statuses](https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#create-a-commit-status) allows a maximum of 1000 attempts using the same commit SHA and context. Once this limit is reached, the API returns validation errors (HTTP 422). The notification engine ignores these errors and marks the notification attempts as completed.
|
||||
|
|
|
|||
49
docs/operator-manual/notifications/services/nats.md
Executable file
49
docs/operator-manual/notifications/services/nats.md
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
# Nats
|
||||
|
||||
## Parameters
|
||||
|
||||
This notification service is capable of sending simple messages via Nats.
|
||||
|
||||
* Url - Nats server URL, e.g. `nats://nats:4222`
|
||||
* Headers - optional, additional headers to be sent with the message
|
||||
* User - optional, Nats user for authentication used in combination with password
|
||||
* Password - optional, Nats password for authentication used in combination with user
|
||||
* Nkey - optional, Nats key for authentication
|
||||
|
||||
## Example
|
||||
|
||||
Resource Annotation:
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
annotations:
|
||||
notifications.argoproj.io/subscribe.on-deployment-ready.nats: "mytopic"
|
||||
```
|
||||
|
||||
* ConfigMap
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: argocd-notifications-cm
|
||||
data:
|
||||
service.nats: |
|
||||
url: "nats://nats:4222"
|
||||
headers:
|
||||
my-header: "my-value"
|
||||
|
||||
template.deployment-ready: |
|
||||
message: |
|
||||
Deployment {{.obj.metadata.name}} is ready!
|
||||
|
||||
trigger.on-deployment-ready: |
|
||||
- when: any(obj.status.conditions, {.type == 'Available' && .status == 'True'})
|
||||
send: [deployment-ready]
|
||||
- oncePer: obj.metadata.annotations["generation"]
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
@ -47,12 +47,14 @@ metadata:
|
|||
|
||||
## Templates
|
||||
|
||||
* `description` - __optional__, high-level description of this deployment, visible in the [Summary](https://docs.newrelic.com/docs/apm/applications-menu/monitoring/apm-overview-page) page and on the [Deployments](https://docs.newrelic.com/docs/apm/applications-menu/events/deployments-page) page when you select an individual deployment.
|
||||
* Defaults to `message`
|
||||
* `changelog` - __optional__, A summary of what changed in this deployment, visible in the [Deployments](https://docs.newrelic.com/docs/apm/applications-menu/events/deployments-page) page when you select (selected deployment) > Change log.
|
||||
* Defaults to `{{(call .repo.GetCommitMetadata .app.status.sync.revision).Message}}`
|
||||
* `user` - __optional__, A username to associate with the deployment, visible in the [Summary](https://docs.newrelic.com/docs/apm/applications-menu/events/deployments-page) and on the [Deployments](https://docs.newrelic.com/docs/apm/applications-menu/events/deployments-page).
|
||||
* Defaults to `{{(call .repo.GetCommitMetadata .app.status.sync.revision).Author}}`
|
||||
- `revision` - **optional**, The revision being deployed. Can contain a custom template to extract the revision from your specific application status structure.
|
||||
- Defaults to `{{.app.status.operationState.syncResult.revision}}`
|
||||
- `description` - **optional**, high-level description of this deployment, visible in the [Summary](https://docs.newrelic.com/docs/apm/applications-menu/monitoring/apm-overview-page) page and on the [Deployments](https://docs.newrelic.com/docs/apm/applications-menu/events/deployments-page) page when you select an individual deployment.
|
||||
- Defaults to `message`
|
||||
- `changelog` - **optional**, A summary of what changed in this deployment, visible in the [Deployments](https://docs.newrelic.com/docs/apm/applications-menu/events/deployments-page) page when you select (selected deployment) > Change log.
|
||||
- Defaults to `{{(call .repo.GetCommitMetadata .app.status.sync.revision).Message}}`
|
||||
- `user` - **optional**, A username to associate with the deployment, visible in the [Summary](https://docs.newrelic.com/docs/apm/applications-menu/events/deployments-page) and on the [Deployments](https://docs.newrelic.com/docs/apm/applications-menu/events/deployments-page).
|
||||
- Defaults to `{{(call .repo.GetCommitMetadata .app.status.sync.revision).Author}}`
|
||||
|
||||
```yaml
|
||||
context: |
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ When Argo CD is upgraded manually using plain manifests or Kustomize overlays, i
|
|||
|
||||
Users upgrading Argo CD manually using `helm upgrade` are not impacted by this change, since Helm does not use client-side apply and does not result in creation of the `last-applied` annotation.
|
||||
|
||||
#### Users who previously upgraded to 3.3.0 or 3.3.1
|
||||
In some cases, after upgrading to one of those versions and applying Server-Side Apply, the following error occured:
|
||||
`one or more synchronization tasks completed unsuccessfully, reason: Failed to perform client-side apply migration: failed to perform client-side apply migration on manager kubectl-client-side-apply: error when patching "/dev/shm/2047509016": CustomResourceDefinition.apiextensions.k8s.io "applicationsets.argoproj.io" is invalid: metadata.annotations: Too long: may not be more than 262144 bytes`.
|
||||
|
||||
Users that have configured the sync option `ClientSideApplyMigration=false` as a temporary remediation for the above error, should remove it after upgrading to `3.3.2`. Disabling `ClientSideApplyMigration` imposes a risk to encounter conflicts between K8s field managers in the future.
|
||||
|
||||
### Source Hydrator Now Tracks Hydration State Using Git Notes
|
||||
|
||||
Previously, Argo CD's Source Hydrator pushed a new hydrated commit for every DRY (source) commit, regardless of whether any manifest files (`manifest.yaml`) actually changed. This was necessary for the hydrator to track which DRY commit had last been hydrated: it embedded this information in the `hydrator.metadata` file's `drySha` field in each hydrated commit.
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ Go through the same steps as in [OpenID Connect using Dex](#openid-connect-using
|
|||
### Set up Directory API access
|
||||
|
||||
1. Follow [Google instructions to create a service account with Domain-Wide Delegation](https://developers.google.com/admin-sdk/directory/v1/guides/delegation)
|
||||
- When assigning API scopes to the service account, the scope must **strictly include** `https://www.googleapis.com/auth/admin.directory.group.readonly`. If you assign only the [broader scope] (https://www.googleapis.com/auth/admin.directory.group), you will not be able to retrieve data from the API
|
||||
- When assigning API scopes to the service account, the scope must **strictly include** `https://www.googleapis.com/auth/admin.directory.group.readonly`. If you assign only the [broader scope](https://www.googleapis.com/auth/admin.directory.group), you will not be able to retrieve data from the API
|
||||
- Create the credentials in JSON format and store them in a safe place, we'll need them later
|
||||
2. Enable the [Admin SDK](https://console.developers.google.com/apis/library/admin.googleapis.com/)
|
||||
|
||||
|
|
|
|||
370
docs/proposals/source-verification-policies.md
Normal file
370
docs/proposals/source-verification-policies.md
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
---
|
||||
title: Source Verification Policies
|
||||
authors:
|
||||
- "@olivergondza"
|
||||
sponsors:
|
||||
- "@jannfis"
|
||||
- "@pasha-codefresh"
|
||||
- "@blakepettersson"
|
||||
reviewers:
|
||||
- "@jannfis"
|
||||
- "@pasha-codefresh"
|
||||
- "@blakepettersson"
|
||||
approvers:
|
||||
- "@jannfis"
|
||||
- "@pasha-codefresh"
|
||||
|
||||
creation-date: 2023-08-08
|
||||
---
|
||||
|
||||
# Source Verification Policies
|
||||
|
||||
This proposal introduces an evolution to the existing GnuPG commit verification feature.
|
||||
|
||||
## Summary
|
||||
|
||||
Argo CD has had a feature to verify OpenPGP signatures on Git commits using GnuPG for a while.
|
||||
However, this feature is limited and in some ways may behave unexpectedly.
|
||||
Argo CD would ever only verify the signature on the commit that's pointed to by the `HEAD` of the `Application`'s resolved `targetRevision`.
|
||||
|
||||
Source verification policies are an evolution of the legacy signature verification in Argo CD.
|
||||
It brings new verification modes, the possibility of treating multiple sources in an Application with different strictness.
|
||||
It also sets the foundation to implement more verification methods in the future that are not gpg, nor git specific.
|
||||
|
||||
## Motivation
|
||||
|
||||
As a deployment tool, Argo CD sits in a prominent spot to enforce secure supply chain requirements.
|
||||
The cryptographic verification of sources and artifacts becomes more and more important to organizations and is heavily regulated in some fields.
|
||||
|
||||
Verifying the `HEAD` commit before syncing is not a sufficient level of verification for many organizations and individuals anymore.
|
||||
|
||||
Also, the current approach is an "all-or-nothing" for any given AppProject.
|
||||
Different repositories might have different trust levels, different sets of contributors or contribution/signing guidelines.
|
||||
Especially with the advent of multi-source applications, the current approach of defining the trusted signers for all project repositories/Applications is not flexible enough.
|
||||
|
||||
### Goals
|
||||
|
||||
* Increase confidence in Git commit verification
|
||||
* Manage signer trust based on source repositories (more fine-grained compared to application projects)
|
||||
* Be flexible enough to support other verification providers in the future (e.g. Helm provenance, Git signed using sigstore, etc.)
|
||||
* Make it easy for users to migrate to a more secure verification policy
|
||||
* Fully backwards compatibility to existing GnuPG commit verification mechanisms
|
||||
|
||||
### Non-Goals
|
||||
|
||||
* Implement other verification methods than GnuPG for Git commits.
|
||||
* This may come in later, and the design of SVPs would allow those to integrate rather easily.
|
||||
|
||||
## Proposal
|
||||
|
||||
### Use cases
|
||||
|
||||
1. As an Argo CD user, I need to **ensure that my applications only sync if every single commit in my source repository has been cryptographically signed** by a trusted contributor.
|
||||
- This effectively prevents unsigned/untrusted commits in the git history.
|
||||
1. As an Argo CD user, I need to apply a **different level of trust to different source repositories**, especially with multi-source applications.
|
||||
- Permitting different source repositories to have a different signing policy, and their flexible evolution in time (gradually introduce signing to multiple repositories, for example).
|
||||
1. As an Argo CD admin, I need to restrict **distinct sets of contributors in different repositories**.
|
||||
- Rather than trusting all the contributors in all project's repositories. This becomes another line of defense in the event of a key compromise.
|
||||
|
||||
## Source verification policy
|
||||
|
||||
### Overview
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: AppProject
|
||||
spec:
|
||||
sourceIntegrity:
|
||||
# Out of scope, demonstrating the declaration structure permits extending to different
|
||||
# source types and whatever integrity verification turns out suitable in the future
|
||||
# helm: {}
|
||||
git:
|
||||
policies:
|
||||
- repos:
|
||||
- url: "https://github.com/foo/*"
|
||||
gpg:
|
||||
mode: "none|head|strict"
|
||||
keys:
|
||||
- "0xDEAD"
|
||||
- "0xBEEF"
|
||||
```
|
||||
|
||||
#### Policy repos
|
||||
|
||||
List of glob-style patterns matched against the URL of the source to verify.
|
||||
When the pattern matches a source, it will be verified, otherwise verification of the source will be skipped.
|
||||
|
||||
#### GPG verification policy
|
||||
|
||||
Right now, this is the only supported verification method.
|
||||
It will use GnuPG to verify PGP signatures on commits in Git.
|
||||
|
||||
Using this method, the list of allowed signers is a list of PGP key IDs.
|
||||
Commits signed by keys other than those specified in the list of allowed signers will not verify successfully.
|
||||
In addition to the key IDs to be listed as allowed signers, the keys themselves need to be imported into Argo CD as well using existing mechanisms.
|
||||
|
||||
The `mode` defines how thorough the GPG verification is:
|
||||
|
||||
* `none`: No gpg verification performed.
|
||||
* `head`: Verify the commit pointed to by the HEAD of the target revision.
|
||||
* `strict`: Verify all ancestor commits from target revisions to init. This makes sure there is no unsigned change whatsoever.
|
||||
|
||||
`keys` lists the set of key IDs to trust for signed commits
|
||||
If a commit in the repository is signed by an ID not specified in the list of trusted signers, the verification will fail.
|
||||
If no trusted keys are configured, all signers from `argocd-gpg-keys-cm` ConfigMap are trusted.
|
||||
|
||||
### Verification modes explained
|
||||
|
||||
As a simple example, consider the following revision history:
|
||||
|
||||
```
|
||||
HEAD
|
||||
1.0 2.0
|
||||
+ +
|
||||
| |
|
||||
A---B---C---D---E---F
|
||||
- - - + + +
|
||||
```
|
||||
|
||||
In the above diagram, `A` through `F` represent the commits making up the repository's history, and `1.0` and `2.0` are annotated tags pointing to respective commits.
|
||||
In this example, `HEAD` is pointing to `F`, aka `2.0`.
|
||||
The `+`/`-` indicate if the commit or tag are signed by a trusted key - commits `D`, `E` and `F` are signed, and so are the two tags.
|
||||
|
||||
#### Verification mode "none"
|
||||
|
||||
With this mode, an Application can sync to any of the above revisions regardless of whether there are valid signatures on the source.
|
||||
Verification is not performed.
|
||||
|
||||
#### Verification mode "head"
|
||||
|
||||
If the `targetRevision` is set to one of the commits `A`, `B` or `C` it will not be trusted, because the commits are not signed.
|
||||
On commit `D`, `E` or `F`, it will.
|
||||
|
||||
Specifying `HEAD` (tip of the named branch), `1.0` or `2.0` will successfully validate.
|
||||
`HEAD` because the revision it points to is signed.
|
||||
`1.0` and `2.0` because they are signed tags.
|
||||
|
||||
#### Verification mode "strict"
|
||||
|
||||
Strict mode is not going to trust any point of this git history, because it contains unsigned commits `A`, `B` and `C`.
|
||||
|
||||
### Significance of policy order
|
||||
|
||||
Policies are not accumulative.
|
||||
Only one policy is applied per source repository, and therefore the order of definitions is significant.
|
||||
|
||||
Note that a multi-source application can have its source repositories validated based on different SVPs each.
|
||||
|
||||
Argo CD will select the first policy that matches a repository source URL, and will ignore any other policies that follow.
|
||||
Policies are being evaluated top-down, so your more specific policies must come before the more broad ones.
|
||||
|
||||
As an example, consider you want to verify that all commits across all repositories you source from `github.com` have a valid signature from GitHub's web signing key.
|
||||
However, on a specific repository, you want to have a different policy, using `strict` mode and allowing a different signer in addition.
|
||||
You would set up the more specific policy first, and then the broad one:
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: AppProject
|
||||
metadata:
|
||||
name: gpg
|
||||
namespace: argocd
|
||||
spec:
|
||||
sourceIntegrity:
|
||||
git:
|
||||
policies:
|
||||
- repos:
|
||||
- url: 'https://github.com/example/super-secure'
|
||||
gpg:
|
||||
mode: strict
|
||||
keys:
|
||||
- 4AEE18F83AFDEB23
|
||||
- D56C4FCA57A46444
|
||||
- repos:
|
||||
- url: 'https://github.com/*'
|
||||
gpg:
|
||||
mode: head
|
||||
keys:
|
||||
- 4AEE18F83AFDEB23
|
||||
```
|
||||
|
||||
If the policies had been defined in the opposite order, the specific policy for `https://github.com/example/super-secure` would never match, because that repository URL is already matched by the other policy's `https://github.com/*` pattern, thus that policy would be applied.
|
||||
|
||||
There needs to be a visual indicator in Argo CD CLI and UI, pointing out project repositories that do not perform GPG verification.
|
||||
This is to provide an administrator with feedback on the repository matching evaluation.
|
||||
|
||||
### Security Considerations
|
||||
|
||||
Implementing this proposal would significantly increase resilience against breached Git repositories:
|
||||
|
||||
- An unauthorized contributor has commit access.
|
||||
- Signing key was compromised.
|
||||
|
||||
When someone compromises a developer's credentials as well as signature keys, the adversaries can force Argo CD to trust their commits only in those repositories, where the compromised keys had been added, but not elsewhere.
|
||||
|
||||
### Upgrade / Downgrade Strategy
|
||||
|
||||
#### Upgrade
|
||||
|
||||
Upgrade will be seamless.
|
||||
When Argo CD detects the prior configuration for Git commit verification (i.e. `.spec.signatureKeys` is populated in the `AppProject`), the new implementation will behave like the current one.
|
||||
|
||||
Internally, this will create a single verification policy similar to the one illustrated earlier taking the keys from `.spec.signatureKeys`.
|
||||
|
||||
If a user wants to migrate from the current implementation to the new source verification policies, they will first have to remove `.spec.signatureKeys` and can then go ahead and define desired policies in `.spec.sourceIntegrity.git.policies`.
|
||||
|
||||
To achieve the legacy Argo CD verification behavior in a project, use the following config:
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: AppProject
|
||||
spec:
|
||||
sourceIntegrity:
|
||||
git:
|
||||
policies:
|
||||
- repos:
|
||||
# For any repository in the project
|
||||
- url: "*"
|
||||
gpg:
|
||||
mode: "head" # Verify only the HEAD of the targetRevision
|
||||
keys:
|
||||
- "..." # Keys from .spec.signatureKeys
|
||||
```
|
||||
|
||||
#### Downgrade
|
||||
|
||||
At downgrade time, people will have to reconfigure `.spec.signatureKeys` into any AppProject where it has been removed and remove `.spec.sourceIntegrity.git.policies` at the same time.
|
||||
|
||||
Unless the user motivation for the downgrade is a bug in Argo CD implementation, moving the mode to `head` or `none` (depending on what they are downgrading to) is sufficient.
|
||||
|
||||
## Drawbacks
|
||||
|
||||
* Configuring source verification policies adds some complexity to both Argo CD implementation and used configuration.
|
||||
* Configuring or implementing those incorrectly can be a source of security incidents.
|
||||
|
||||
## Alternatives
|
||||
|
||||
### How to handle local manifests?
|
||||
|
||||
The current implementation rejects them when GPG is turned on and projest's signing keys are declared.
|
||||
Can be done selectively based on source integrity criteria applicability (Git/OCI/Helm & repo).
|
||||
|
||||
### Where to configure verification policies?
|
||||
|
||||
* Verification policies could be placed in the `AppProject`'s `sourceRepos`, for example:
|
||||
|
||||
```
|
||||
spec:
|
||||
sourceRepos:
|
||||
# ...
|
||||
```
|
||||
|
||||
However, this would be a breaking change, as currently the type of entry in `sourceRepos` is just `string`, and it would have to become a complex type.
|
||||
|
||||
We might want to consider moving `sourceIntegrity` into either of those places with the next major Argo CD release.
|
||||
|
||||
### Dealing with unsigned commits in the history using `strict` verification mode
|
||||
|
||||
Having all commits in a Git repository cryptographically signed from init is an ideal situation.
|
||||
However, the reality often looks different.
|
||||
There are a number of reasons why unsigned, or signed but untrusted commits can be found in git history, and it is almost impossible to avoid such situations in large and/or long-running repository.
|
||||
|
||||
- User forgot to sign the commit / used other key than intended
|
||||
- Commit was created unsigned by a (misconfigured) tool
|
||||
- Such has merge&squash, automation/IDE created
|
||||
- Key once approved was rotated after it was compromised, expired, cryptographically obsoleted
|
||||
- Former contributor is no longer trusted (ex-employee, etc.)
|
||||
- It is desirable to accept Pull Request from untrusted parties and merge them without resigning by trusted GPG keys.
|
||||
- Repository policy has not required GPG signing in the past.
|
||||
|
||||
Dealing with such commits with the expectation to validate the entire history requires git history rewrites (rebase, force-push) that are problematic on a number of technical and organizational fronts.
|
||||
Force pushing is often prohibited also as a security measure, so asking users to relax security in order to improve security proposes them with a Sophie's choice.
|
||||
|
||||
Some of these can be prevented by requiring gpg signatures on git push, but not all.
|
||||
Also, preventing force pushing is easier to configure in git hosting sites, than restricting only a fixed set of GPG signing keys can push commits.
|
||||
|
||||
While retroactively signing commits without a signature is a somewhat straightforward chore (`git rebase --signoff XXX`),
|
||||
identifying all commits signed by a particular key and re-signing it by a new/valid one is more cumbersome and error-prone.
|
||||
Hence, this proposal is treating git history rewriting as an undesirable and possibly even technically disallowed procedure.
|
||||
|
||||
In fact, it does not harm UX *and* improves security with:
|
||||
|
||||
#### Git history *sealing* for strict verification mode
|
||||
|
||||
A sealing commit is a gpg signed commit that works as a "seal of approval" attesting that all its ancestor commits were either signed by a trusted key, or reviewed and trusted by the commit author.
|
||||
Argo CD verifying gpg signatures would then progres only as far back in the history as the most recent "seal" commits in each individual ancestral branch.
|
||||
|
||||
In practice, a commiter reviews all commits that are not signed or signed with untrusted keys from the previous "seal" and creates a (possibly empty) commit with a custom trailer.
|
||||
Such commits can have the following organization level semantics:
|
||||
|
||||
- "From now on, we are going to gpg sign all commits in this repository. There is no point in verifying the unsigned ones from before."
|
||||
- "I merge these changes from untrusted external contributor, and I approve of them."
|
||||
- "I am removing the GPG key of Bob. All his previous commits are trusted, but no new ones will be. Happy retirement, Bob!"
|
||||
- "I am replacing my old key with a new one. Trust my commit signed with the old one before this commit, trust my new one from now on."
|
||||
|
||||
To make a "seal" commit, run `git commit --signoff --gpg-sign --trailer="Argocd-gpg-seal: <justification>"` and push to branch pulled by Argo CD.
|
||||
The advantage is the exact same procedure deals with all the identified situations of unsigned or untrusted commits in the history, eliminating the room for eventual rebasing mistakes that would jeopardize security or correctness.
|
||||
It is possible to introduce tooling to help identify all previous "seal" commits and all the untrusted commits made since then, so the administrator knows exactly what are they "seal-signing".
|
||||
|
||||
Git history sealing can be part of the `strict` mode, eventually enabled through a flag, or be enabled in a separate "less-strict" mode.
|
||||
Either way, it requires no force-pushing.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
## head mode
|
||||
|
||||
T <- verified
|
||||
| \
|
||||
| o
|
||||
| |
|
||||
o |
|
||||
| |
|
||||
| o
|
||||
| /
|
||||
o
|
||||
|
|
||||
o
|
||||
|
||||
|
||||
## strict mode
|
||||
|
||||
T <- verified
|
||||
| \
|
||||
| o <- verified
|
||||
| |
|
||||
o | <- verified
|
||||
| |
|
||||
| o <- verified
|
||||
| /
|
||||
o <- verified
|
||||
|
|
||||
o <- verified
|
||||
|
||||
|
||||
## strict mode - with seal commits
|
||||
|
||||
T <- verified
|
||||
| \
|
||||
| S <- verified (seal)
|
||||
| |
|
||||
S | <- verified (seal)
|
||||
| |
|
||||
| o
|
||||
| /
|
||||
o
|
||||
|
|
||||
o
|
||||
|
||||
```
|
||||
|
||||
#### Comparison with the original `progressive` mode
|
||||
|
||||
The "seal-signing" is inspired by the original mode that verified commits from `targetRevision` to a commit of last successful Argo CD Application sync.
|
||||
They both verify the history backwards only until a certain point, from which it is considered inherently trusted.
|
||||
|
||||
The non-trivial N:M mapping between repositories and Applications (or even Argo CD instances) was a cause of a number of corner cases identified in the original proposal.
|
||||
|
||||
Seal-signing marks the point(s) from where not to verify commits *inside* the repository itself, and thus is making sure that all Argo CD instances and their applications have a consistent view of what they are, regardless of application removal from Argo CD, Argo CD migration, etc.
|
||||
|
||||
Both approaches, in fact, work as an optimization mechanism by limiting the number of commits to verify.
|
||||
For sealing, a commiter needs to add a seal commit manually even if there are no unsigned changes to speed things up.
|
||||
Additionally, the implementation can cache the last `strict`-verified commit per repository & strategy, to optimize verification speed on a best effort basis.
|
||||
|
|
@ -13,66 +13,52 @@ recent minor releases.
|
|||
|
||||
| | Critical | High | Medium | Low |
|
||||
|---:|:--------:|:----:|:------:|:---:|
|
||||
| [gitops-engine/go.mod](master/argocd-test.html) | 0 | 2 | 0 | 0 |
|
||||
| [go.mod](master/argocd-test.html) | 0 | 1 | 0 | 0 |
|
||||
| [ui/yarn.lock](master/argocd-test.html) | 0 | 1 | 2 | 2 |
|
||||
| [dex:v2.43.0](master/ghcr.io_dexidp_dex_v2.43.0.html) | 0 | 1 | 0 | 14 |
|
||||
| [gitops-engine/go.mod](master/argocd-test.html) | 0 | 0 | 2 | 0 |
|
||||
| [go.mod](master/argocd-test.html) | 0 | 1 | 6 | 0 |
|
||||
| [ui/yarn.lock](master/argocd-test.html) | 0 | 4 | 2 | 2 |
|
||||
| [dex:v2.44.0](master/ghcr.io_dexidp_dex_v2.44.0.html) | 0 | 1 | 0 | 16 |
|
||||
| [haproxy:3.0.8-alpine](master/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html) | 0 | 1 | 0 | 14 |
|
||||
| [redis:8.2.3-alpine](master/public.ecr.aws_docker_library_redis_8.2.3-alpine.html) | 0 | 0 | 0 | 0 |
|
||||
| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 7 | 10 |
|
||||
| [install.yaml](master/argocd-iac-install.html) | - | - | - | - |
|
||||
| [namespace-install.yaml](master/argocd-iac-namespace-install.html) | - | - | - | - |
|
||||
|
||||
### v3.3.0-rc4
|
||||
### v3.3.1
|
||||
|
||||
| | Critical | High | Medium | Low |
|
||||
|---:|:--------:|:----:|:------:|:---:|
|
||||
| [gitops-engine/go.mod](v3.3.0-rc4/argocd-test.html) | 0 | 2 | 0 | 0 |
|
||||
| [go.mod](v3.3.0-rc4/argocd-test.html) | 0 | 1 | 0 | 0 |
|
||||
| [ui/yarn.lock](v3.3.0-rc4/argocd-test.html) | 0 | 2 | 4 | 2 |
|
||||
| [dex:v2.43.0](v3.3.0-rc4/ghcr.io_dexidp_dex_v2.43.0.html) | 0 | 1 | 0 | 14 |
|
||||
| [haproxy:3.0.8-alpine](v3.3.0-rc4/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html) | 0 | 1 | 0 | 14 |
|
||||
| [redis:8.2.3-alpine](v3.3.0-rc4/public.ecr.aws_docker_library_redis_8.2.3-alpine.html) | 0 | 0 | 0 | 0 |
|
||||
| [argocd:v3.3.0-rc4](v3.3.0-rc4/quay.io_argoproj_argocd_v3.3.0-rc4.html) | 0 | 0 | 0 | 1 |
|
||||
| [install.yaml](v3.3.0-rc4/argocd-iac-install.html) | - | - | - | - |
|
||||
| [namespace-install.yaml](v3.3.0-rc4/argocd-iac-namespace-install.html) | - | - | - | - |
|
||||
| [gitops-engine/go.mod](v3.3.1/argocd-test.html) | 0 | 0 | 2 | 0 |
|
||||
| [go.mod](v3.3.1/argocd-test.html) | 0 | 1 | 6 | 0 |
|
||||
| [ui/yarn.lock](v3.3.1/argocd-test.html) | 0 | 5 | 5 | 2 |
|
||||
| [dex:v2.43.0](v3.3.1/ghcr.io_dexidp_dex_v2.43.0.html) | 0 | 1 | 0 | 14 |
|
||||
| [haproxy:3.0.8-alpine](v3.3.1/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html) | 0 | 1 | 0 | 14 |
|
||||
| [redis:8.2.3-alpine](v3.3.1/public.ecr.aws_docker_library_redis_8.2.3-alpine.html) | 0 | 0 | 0 | 0 |
|
||||
| [argocd:v3.3.1](v3.3.1/quay.io_argoproj_argocd_v3.3.1.html) | 0 | 0 | 7 | 12 |
|
||||
| [install.yaml](v3.3.1/argocd-iac-install.html) | - | - | - | - |
|
||||
| [namespace-install.yaml](v3.3.1/argocd-iac-namespace-install.html) | - | - | - | - |
|
||||
|
||||
### v3.2.6
|
||||
### v3.2.7
|
||||
|
||||
| | Critical | High | Medium | Low |
|
||||
|---:|:--------:|:----:|:------:|:---:|
|
||||
| [go.mod](v3.2.6/argocd-test.html) | 0 | 1 | 0 | 0 |
|
||||
| [ui/yarn.lock](v3.2.6/argocd-test.html) | 0 | 2 | 6 | 2 |
|
||||
| [dex:v2.43.0](v3.2.6/ghcr.io_dexidp_dex_v2.43.0.html) | 0 | 1 | 0 | 14 |
|
||||
| [haproxy:3.0.8-alpine](v3.2.6/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html) | 0 | 1 | 0 | 14 |
|
||||
| [redis:8.2.2-alpine](v3.2.6/public.ecr.aws_docker_library_redis_8.2.2-alpine.html) | 0 | 1 | 0 | 13 |
|
||||
| [argocd:v3.2.6](v3.2.6/quay.io_argoproj_argocd_v3.2.6.html) | 0 | 0 | 0 | 1 |
|
||||
| [install.yaml](v3.2.6/argocd-iac-install.html) | - | - | - | - |
|
||||
| [namespace-install.yaml](v3.2.6/argocd-iac-namespace-install.html) | - | - | - | - |
|
||||
| [go.mod](v3.2.7/argocd-test.html) | 0 | 1 | 6 | 0 |
|
||||
| [ui/yarn.lock](v3.2.7/argocd-test.html) | 0 | 5 | 7 | 2 |
|
||||
| [dex:v2.43.0](v3.2.7/ghcr.io_dexidp_dex_v2.43.0.html) | 0 | 1 | 0 | 14 |
|
||||
| [haproxy:3.0.8-alpine](v3.2.7/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html) | 0 | 1 | 0 | 14 |
|
||||
| [redis:8.2.2-alpine](v3.2.7/public.ecr.aws_docker_library_redis_8.2.2-alpine.html) | 0 | 1 | 0 | 13 |
|
||||
| [argocd:v3.2.7](v3.2.7/quay.io_argoproj_argocd_v3.2.7.html) | 0 | 0 | 0 | 1 |
|
||||
| [install.yaml](v3.2.7/argocd-iac-install.html) | - | - | - | - |
|
||||
| [namespace-install.yaml](v3.2.7/argocd-iac-namespace-install.html) | - | - | - | - |
|
||||
|
||||
### v3.1.12
|
||||
|
||||
| | Critical | High | Medium | Low |
|
||||
|---:|:--------:|:----:|:------:|:---:|
|
||||
| [go.mod](v3.1.12/argocd-test.html) | 0 | 1 | 0 | 0 |
|
||||
| [ui/yarn.lock](v3.1.12/argocd-test.html) | 1 | 2 | 6 | 2 |
|
||||
| [go.mod](v3.1.12/argocd-test.html) | 0 | 1 | 6 | 0 |
|
||||
| [ui/yarn.lock](v3.1.12/argocd-test.html) | 1 | 5 | 7 | 2 |
|
||||
| [dex:v2.43.0](v3.1.12/ghcr.io_dexidp_dex_v2.43.0.html) | 0 | 1 | 0 | 14 |
|
||||
| [haproxy:3.0.8-alpine](v3.1.12/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html) | 0 | 1 | 0 | 14 |
|
||||
| [redis:7.2.11-alpine](v3.1.12/public.ecr.aws_docker_library_redis_7.2.11-alpine.html) | 0 | 1 | 0 | 11 |
|
||||
| [argocd:v3.1.12](v3.1.12/quay.io_argoproj_argocd_v3.1.12.html) | 0 | 0 | 11 | 24 |
|
||||
| [install.yaml](v3.1.12/argocd-iac-install.html) | - | - | - | - |
|
||||
| [namespace-install.yaml](v3.1.12/argocd-iac-namespace-install.html) | - | - | - | - |
|
||||
|
||||
### v3.0.23
|
||||
|
||||
| | Critical | High | Medium | Low |
|
||||
|---:|:--------:|:----:|:------:|:---:|
|
||||
| [go.mod](v3.0.23/argocd-test.html) | 0 | 1 | 0 | 0 |
|
||||
| [ui/yarn.lock](v3.0.23/argocd-test.html) | 1 | 2 | 7 | 4 |
|
||||
| [dex:v2.41.1](v3.0.23/ghcr.io_dexidp_dex_v2.41.1.html) | 0 | 3 | 0 | 17 |
|
||||
| [haproxy:3.0.8-alpine](v3.0.23/public.ecr.aws_docker_library_haproxy_3.0.8-alpine.html) | 0 | 1 | 0 | 14 |
|
||||
| [redis:7.2.11-alpine](v3.0.23/public.ecr.aws_docker_library_redis_7.2.11-alpine.html) | 0 | 1 | 0 | 11 |
|
||||
| [argocd:v3.0.23](v3.0.23/quay.io_argoproj_argocd_v3.0.23.html) | 0 | 0 | 11 | 24 |
|
||||
| [redis:7.2.11-alpine](v3.0.23/redis_7.2.11-alpine.html) | 0 | 1 | 0 | 11 |
|
||||
| [install.yaml](v3.0.23/argocd-iac-install.html) | - | - | - | - |
|
||||
| [namespace-install.yaml](v3.0.23/argocd-iac-namespace-install.html) | - | - | - | - |
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@
|
|||
<div class="header-wrap">
|
||||
<h1 class="project__header__title">Snyk test report</h1>
|
||||
|
||||
<p class="timestamp">February 8th 2026, 12:37:35 am (UTC+00:00)</p>
|
||||
<p class="timestamp">February 22nd 2026, 12:30:44 am (UTC+00:00)</p>
|
||||
</div>
|
||||
<div class="source-panel">
|
||||
<span>Scanned the following path:</span>
|
||||
|
|
@ -507,7 +507,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 30946
|
||||
Line number: 30947
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -553,7 +553,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 30631
|
||||
Line number: 30632
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -599,7 +599,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 30719
|
||||
Line number: 30720
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -645,7 +645,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 30754
|
||||
Line number: 30755
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -691,7 +691,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 30784
|
||||
Line number: 30785
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -737,7 +737,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 30802
|
||||
Line number: 30803
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -783,7 +783,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 30820
|
||||
Line number: 30821
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -829,7 +829,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 30842
|
||||
Line number: 30843
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -881,7 +881,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32097
|
||||
Line number: 32098
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -933,7 +933,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32452
|
||||
Line number: 32453
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -991,7 +991,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31529
|
||||
Line number: 31530
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1049,7 +1049,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31893
|
||||
Line number: 31894
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1107,7 +1107,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31841
|
||||
Line number: 31842
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1165,7 +1165,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31955
|
||||
Line number: 31956
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1223,7 +1223,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32068
|
||||
Line number: 32069
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1281,7 +1281,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32092
|
||||
Line number: 32093
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1339,7 +1339,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32452
|
||||
Line number: 32453
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1397,7 +1397,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32151
|
||||
Line number: 32152
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1455,7 +1455,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32540
|
||||
Line number: 32548
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1513,7 +1513,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32998
|
||||
Line number: 33006
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1565,7 +1565,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31873
|
||||
Line number: 31874
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1617,7 +1617,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31529
|
||||
Line number: 31530
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1669,7 +1669,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31841
|
||||
Line number: 31842
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1721,7 +1721,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32068
|
||||
Line number: 32069
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1779,7 +1779,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31529
|
||||
Line number: 31530
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1837,7 +1837,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31841
|
||||
Line number: 31842
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1895,7 +1895,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31893
|
||||
Line number: 31894
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -1953,7 +1953,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31955
|
||||
Line number: 31956
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2011,7 +2011,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32068
|
||||
Line number: 32069
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2069,7 +2069,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32092
|
||||
Line number: 32093
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2127,7 +2127,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32452
|
||||
Line number: 32453
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2185,7 +2185,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32151
|
||||
Line number: 32152
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2243,7 +2243,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32540
|
||||
Line number: 32548
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2301,7 +2301,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32998
|
||||
Line number: 33006
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2357,7 +2357,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31754
|
||||
Line number: 31755
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2413,7 +2413,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31901
|
||||
Line number: 31902
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2469,7 +2469,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 31876
|
||||
Line number: 31877
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2525,7 +2525,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32000
|
||||
Line number: 32001
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2581,7 +2581,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32085
|
||||
Line number: 32086
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2637,7 +2637,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32099
|
||||
Line number: 32100
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2693,7 +2693,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32460
|
||||
Line number: 32461
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2749,7 +2749,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32425
|
||||
Line number: 32426
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2805,7 +2805,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 32897
|
||||
Line number: 32905
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -2861,7 +2861,7 @@
|
|||
</li>
|
||||
|
||||
<li class="card__meta__item">
|
||||
Line number: 33321
|
||||
Line number: 33329
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue