mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-20 17:48:47 +01:00
Compare commits
104 Commits
crenshaw-d
...
v3.1.12
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a46152e850 | ||
|
|
28b618775d | ||
|
|
1b7cfc0c06 | ||
|
|
0262c8ff97 | ||
|
|
cc053b2eeb | ||
|
|
f9adb4e7f4 | ||
|
|
6c3f3eab5d | ||
|
|
f22ccc2192 | ||
|
|
b424210b52 | ||
|
|
955ea1b1df | ||
|
|
836d47f311 | ||
|
|
db2004f2e2 | ||
|
|
b68c964321 | ||
|
|
f4f21b3642 | ||
|
|
38c15ada45 | ||
|
|
11e7758ca9 | ||
|
|
f2f4f4579b | ||
|
|
f9ada0403d | ||
|
|
b6660a2a7a | ||
|
|
787f3ec6a2 | ||
|
|
49ee0040c4 | ||
|
|
7eca62c2d6 | ||
|
|
8665140f96 | ||
|
|
a419e477e6 | ||
|
|
e53196f9fd | ||
|
|
16ba5f9c43 | ||
|
|
1904de5065 | ||
|
|
becb020064 | ||
|
|
c63c2d8909 | ||
|
|
e20828f869 | ||
|
|
761fc27068 | ||
|
|
1a023f1ca7 | ||
|
|
5c466a4e39 | ||
|
|
b2fa7dcde6 | ||
|
|
38808d03cd | ||
|
|
41eac62eac | ||
|
|
54bab39a80 | ||
|
|
511ebd799e | ||
|
|
2e4458b91a | ||
|
|
7f92418a9c | ||
|
|
f3d59b0bb7 | ||
|
|
4081e2983a | ||
|
|
c26cd5502b | ||
|
|
96797ba846 | ||
|
|
b46a57ab82 | ||
|
|
2b3df7f5a8 | ||
|
|
4ef56634b4 | ||
|
|
cb9574597e | ||
|
|
468870f65d | ||
|
|
cfeed49105 | ||
|
|
c21141a51f | ||
|
|
0415c60af9 | ||
|
|
9a3235ef92 | ||
|
|
3320f1ed7a | ||
|
|
20dd73af34 | ||
|
|
206d57b0de | ||
|
|
c1467b81bc | ||
|
|
791b036d98 | ||
|
|
60c62a944b | ||
|
|
fe6efec8f4 | ||
|
|
6de4f7739b | ||
|
|
ed9149beea | ||
|
|
20447f7f57 | ||
|
|
7982a74600 | ||
|
|
b3ad040b2c | ||
|
|
30d8ce66e2 | ||
|
|
fa342d153e | ||
|
|
c140eb27f8 | ||
|
|
70dde2c27b | ||
|
|
eb72a0bd3b | ||
|
|
fdd099181c | ||
|
|
a0f065316b | ||
|
|
b22566d001 | ||
|
|
03c4ad854c | ||
|
|
a9a0c7bf57 | ||
|
|
1c1c17663e | ||
|
|
61d2a05fd0 | ||
|
|
64e94af771 | ||
|
|
269e213889 | ||
|
|
26c63b9283 | ||
|
|
1ad527f094 | ||
|
|
b7d39b57fc | ||
|
|
9f18ff1fcd | ||
|
|
66d06c0b23 | ||
|
|
007a5aea6e | ||
|
|
36cc2d1b86 | ||
|
|
9db5e25e03 | ||
|
|
8eaccb7ea0 | ||
|
|
fed347da29 | ||
|
|
1cbd28cb30 | ||
|
|
6fe5ec794a | ||
|
|
6142c5bf56 | ||
|
|
563d45b8db | ||
|
|
37f2793e95 | ||
|
|
7224a15502 | ||
|
|
dd675feb33 | ||
|
|
c215dbf202 | ||
|
|
75f7016d89 | ||
|
|
4a7e581080 | ||
|
|
320f46f06b | ||
|
|
d69639a073 | ||
|
|
b75f532a91 | ||
|
|
200dc1d499 | ||
|
|
3f1d9bf5a2 |
18
.github/workflows/ci-build.yaml
vendored
18
.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.24.4'
|
||||
GOLANG_VERSION: '1.25.5'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -103,16 +103,16 @@ jobs:
|
||||
- changes
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
- name: Setup Golang
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
||||
with:
|
||||
go-version: ${{ env.GOLANG_VERSION }}
|
||||
- name: Run golangci-lint
|
||||
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
|
||||
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
|
||||
with:
|
||||
# renovate: datasource=go packageName=github.com/golangci/golangci-lint versioning=regex:^v(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)?$
|
||||
version: v2.1.6
|
||||
version: v2.5.0
|
||||
args: --verbose
|
||||
|
||||
test-go:
|
||||
@@ -414,14 +414,14 @@ jobs:
|
||||
# latest: true means that this version mush upload the coverage report to codecov.io
|
||||
# We designate the latest version because we only collect code coverage for that version.
|
||||
k3s:
|
||||
- version: v1.33.1
|
||||
- version: v1.34.2
|
||||
latest: true
|
||||
- version: v1.33.1
|
||||
latest: false
|
||||
- version: v1.32.1
|
||||
latest: false
|
||||
- version: v1.31.0
|
||||
latest: false
|
||||
- version: v1.30.4
|
||||
latest: false
|
||||
needs:
|
||||
- build-go
|
||||
- changes
|
||||
@@ -496,7 +496,7 @@ jobs:
|
||||
run: |
|
||||
docker pull ghcr.io/dexidp/dex:v2.43.0
|
||||
docker pull argoproj/argo-cd-ci-builder:v1.0.0
|
||||
docker pull redis:7.2.7-alpine
|
||||
docker pull redis:7.2.11-alpine
|
||||
- name: Create target directory for binaries in the build-process
|
||||
run: |
|
||||
mkdir -p dist
|
||||
|
||||
4
.github/workflows/image.yaml
vendored
4
.github/workflows/image.yaml
vendored
@@ -53,7 +53,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.24.4
|
||||
go-version: 1.25.5
|
||||
platforms: ${{ needs.set-vars.outputs.platforms }}
|
||||
push: false
|
||||
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
ghcr_image_name: ghcr.io/argoproj/argo-cd/argocd:${{ needs.set-vars.outputs.image-tag }}
|
||||
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
go-version: 1.24.4
|
||||
go-version: 1.25.5
|
||||
platforms: ${{ needs.set-vars.outputs.platforms }}
|
||||
push: true
|
||||
secrets:
|
||||
|
||||
70
.github/workflows/release.yaml
vendored
70
.github/workflows/release.yaml
vendored
@@ -11,7 +11,7 @@ permissions: {}
|
||||
|
||||
env:
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
GOLANG_VERSION: '1.24.4' # Note: go-version must also be set in job argocd-image.with.go-version
|
||||
GOLANG_VERSION: '1.25.5' # Note: go-version must also be set in job argocd-image.with.go-version
|
||||
|
||||
jobs:
|
||||
argocd-image:
|
||||
@@ -25,13 +25,49 @@ jobs:
|
||||
quay_image_name: quay.io/argoproj/argocd:${{ github.ref_name }}
|
||||
# Note: cannot use env variables to set go-version (https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations)
|
||||
# renovate: datasource=golang-version packageName=golang
|
||||
go-version: 1.24.4
|
||||
go-version: 1.25.5
|
||||
platforms: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le
|
||||
push: true
|
||||
secrets:
|
||||
quay_username: ${{ secrets.RELEASE_QUAY_USERNAME }}
|
||||
quay_password: ${{ secrets.RELEASE_QUAY_TOKEN }}
|
||||
|
||||
setup-variables:
|
||||
name: Setup Release Variables
|
||||
if: github.repository == 'argoproj/argo-cd'
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
is_pre_release: ${{ steps.var.outputs.is_pre_release }}
|
||||
is_latest_release: ${{ steps.var.outputs.is_latest_release }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Setup variables
|
||||
id: var
|
||||
run: |
|
||||
set -xue
|
||||
# Fetch all tag information
|
||||
git fetch --prune --tags --force
|
||||
|
||||
LATEST_RELEASE_TAG=$(git -c 'versionsort.suffix=-rc' tag --list --sort=version:refname | grep -v '-' | tail -n1)
|
||||
|
||||
PRE_RELEASE=false
|
||||
# Check if latest tag is a pre-release
|
||||
if echo ${{ github.ref_name }} | grep -E -- '-rc[0-9]+$';then
|
||||
PRE_RELEASE=true
|
||||
fi
|
||||
|
||||
IS_LATEST=false
|
||||
# Ensure latest release tag matches github.ref_name
|
||||
if [[ $LATEST_RELEASE_TAG == ${{ github.ref_name }} ]];then
|
||||
IS_LATEST=true
|
||||
fi
|
||||
echo "is_pre_release=$PRE_RELEASE" >> $GITHUB_OUTPUT
|
||||
echo "is_latest_release=$IS_LATEST" >> $GITHUB_OUTPUT
|
||||
|
||||
argocd-image-provenance:
|
||||
needs: [argocd-image]
|
||||
permissions:
|
||||
@@ -50,15 +86,17 @@ jobs:
|
||||
|
||||
goreleaser:
|
||||
needs:
|
||||
- setup-variables
|
||||
- argocd-image
|
||||
- argocd-image-provenance
|
||||
permissions:
|
||||
contents: write # used for uploading assets
|
||||
if: github.repository == 'argoproj/argo-cd'
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
GORELEASER_MAKE_LATEST: ${{ needs.setup-variables.outputs.is_latest_release }}
|
||||
outputs:
|
||||
hashes: ${{ steps.hash.outputs.hashes }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
|
||||
@@ -142,7 +180,7 @@ jobs:
|
||||
permissions:
|
||||
contents: write # Needed for release uploads
|
||||
outputs:
|
||||
hashes: ${{ steps.sbom-hash.outputs.hashes}}
|
||||
hashes: ${{ steps.sbom-hash.outputs.hashes }}
|
||||
if: github.repository == 'argoproj/argo-cd'
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
@@ -221,6 +259,7 @@ jobs:
|
||||
|
||||
post-release:
|
||||
needs:
|
||||
- setup-variables
|
||||
- argocd-image
|
||||
- goreleaser
|
||||
- generate-sbom
|
||||
@@ -229,6 +268,8 @@ jobs:
|
||||
pull-requests: write # Needed to create PR for VERSION update.
|
||||
if: github.repository == 'argoproj/argo-cd'
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
TAG_STABLE: ${{ needs.setup-variables.outputs.is_latest_release }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@8410ad0602e1e429cee44a835ae9f77f654a6694 # v4.0.0
|
||||
@@ -242,27 +283,6 @@ jobs:
|
||||
git config --global user.email 'ci@argoproj.com'
|
||||
git config --global user.name 'CI'
|
||||
|
||||
- name: Check if tag is the latest version and not a pre-release
|
||||
run: |
|
||||
set -xue
|
||||
# Fetch all tag information
|
||||
git fetch --prune --tags --force
|
||||
|
||||
LATEST_TAG=$(git -c 'versionsort.suffix=-rc' tag --list --sort=version:refname | tail -n1)
|
||||
|
||||
PRE_RELEASE=false
|
||||
# Check if latest tag is a pre-release
|
||||
if echo $LATEST_TAG | grep -E -- '-rc[0-9]+$';then
|
||||
PRE_RELEASE=true
|
||||
fi
|
||||
|
||||
# Ensure latest tag matches github.ref_name & not a pre-release
|
||||
if [[ $LATEST_TAG == ${{ github.ref_name }} ]] && [[ $PRE_RELEASE != 'true' ]];then
|
||||
echo "TAG_STABLE=true" >> $GITHUB_ENV
|
||||
else
|
||||
echo "TAG_STABLE=false" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Update stable tag to latest version
|
||||
run: |
|
||||
git tag -f stable ${{ github.ref_name }}
|
||||
|
||||
@@ -21,7 +21,7 @@ builds:
|
||||
- -X github.com/argoproj/argo-cd/v3/common.gitCommit={{ .FullCommit }}
|
||||
- -X github.com/argoproj/argo-cd/v3/common.gitTreeState={{ .Env.GIT_TREE_STATE }}
|
||||
- -X github.com/argoproj/argo-cd/v3/common.kubectlVersion={{ .Env.KUBECTL_VERSION }}
|
||||
- '{{ if or (eq .Runtime.Goos "linux") (eq .Runtime.Goos "windows") }}-extldflags="-static"{{ end }}'
|
||||
- -extldflags="-static"
|
||||
goos:
|
||||
- linux
|
||||
- windows
|
||||
@@ -42,15 +42,6 @@ builds:
|
||||
goarch: ppc64le
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
overrides:
|
||||
- goos: darwin
|
||||
goarch: amd64
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- goos: darwin
|
||||
goarch: arm64
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
|
||||
archives:
|
||||
- id: argocd-archive
|
||||
@@ -58,13 +49,14 @@ archives:
|
||||
- argocd-cli
|
||||
name_template: |-
|
||||
{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}
|
||||
formats: [ binary ]
|
||||
formats: [binary]
|
||||
|
||||
checksum:
|
||||
name_template: 'cli_checksums.txt'
|
||||
algorithm: sha256
|
||||
|
||||
release:
|
||||
make_latest: '{{ .Env.GORELEASER_MAKE_LATEST }}'
|
||||
prerelease: auto
|
||||
draft: false
|
||||
header: |
|
||||
@@ -89,7 +81,7 @@ release:
|
||||
All Argo CD container images are signed by cosign. A Provenance is generated for container images and CLI binaries which meet the SLSA Level 3 specifications. See the [documentation](https://argo-cd.readthedocs.io/en/stable/operator-manual/signed-release-assets) on how to verify.
|
||||
|
||||
## Release Notes Blog Post
|
||||
For a detailed breakdown of the key changes and improvements in this release, check out the [official blog post](https://blog.argoproj.io/argo-cd-v3-0-release-candidate-a0b933f4e58f)
|
||||
For a detailed breakdown of the key changes and improvements in this release, check out the [official blog post](https://blog.argoproj.io/announcing-argo-cd-v3-1-f4389bc783c8)
|
||||
|
||||
## Upgrading
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:80dd3c3b9c6cecb9f1667e9290b
|
||||
# Initial stage which pulls prepares build dependencies and CLI tooling we need for our final image
|
||||
# Also used as the image in CI jobs so needs all dependencies
|
||||
####################################################################################################
|
||||
FROM docker.io/library/golang:1.24.4@sha256:db5d0afbfb4ab648af2393b92e87eaae9ad5e01132803d80caef91b5752d289c AS builder
|
||||
FROM docker.io/library/golang:1.25.5@sha256:6cc2338c038bc20f96ab32848da2b5c0641bb9bb5363f2c33e9b7c8838f9a208 AS builder
|
||||
|
||||
WORKDIR /tmp
|
||||
|
||||
@@ -103,7 +103,7 @@ RUN HOST_ARCH=$TARGETARCH NODE_ENV='production' NODE_ONLINE_ENV='online' NODE_OP
|
||||
####################################################################################################
|
||||
# Argo CD Build stage which performs the actual build of Argo CD binaries
|
||||
####################################################################################################
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.24.4@sha256:db5d0afbfb4ab648af2393b92e87eaae9ad5e01132803d80caef91b5752d289c AS argocd-build
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.25.5@sha256:6cc2338c038bc20f96ab32848da2b5c0641bb9bb5363f2c33e9b7c8838f9a208 AS argocd-build
|
||||
|
||||
WORKDIR /go/src/github.com/argoproj/argo-cd
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ const (
|
||||
var defaultPreservedAnnotations = []string{
|
||||
NotifiedAnnotationKey,
|
||||
argov1alpha1.AnnotationKeyRefresh,
|
||||
argov1alpha1.AnnotationKeyHydrate,
|
||||
}
|
||||
|
||||
// ApplicationSetReconciler reconciles a ApplicationSet object
|
||||
@@ -92,6 +93,7 @@ type ApplicationSetReconciler struct {
|
||||
GlobalPreservedAnnotations []string
|
||||
GlobalPreservedLabels []string
|
||||
Metrics *metrics.ApplicationsetMetrics
|
||||
MaxResourcesStatusCount int
|
||||
}
|
||||
|
||||
// +kubebuilder:rbac:groups=argoproj.io,resources=applicationsets,verbs=get;list;watch;create;update;patch;delete
|
||||
@@ -230,6 +232,16 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque
|
||||
return ctrl.Result{}, fmt.Errorf("failed to perform progressive sync reconciliation for application set: %w", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Progressive Sync is disabled, clear any existing applicationStatus to prevent stale data
|
||||
if len(applicationSetInfo.Status.ApplicationStatus) > 0 {
|
||||
logCtx.Infof("Progressive Sync disabled, removing %v AppStatus entries from ApplicationSet %v", len(applicationSetInfo.Status.ApplicationStatus), applicationSetInfo.Name)
|
||||
|
||||
err := r.setAppSetApplicationStatus(ctx, logCtx, &applicationSetInfo, []argov1alpha1.ApplicationSetApplicationStatus{})
|
||||
if err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("failed to clear AppSet application statuses when Progressive Sync is disabled for %v: %w", applicationSetInfo.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var validApps []argov1alpha1.Application
|
||||
@@ -564,8 +576,9 @@ func (r *ApplicationSetReconciler) SetupWithManager(mgr ctrl.Manager, enableProg
|
||||
Watches(
|
||||
&corev1.Secret{},
|
||||
&clusterSecretEventHandler{
|
||||
Client: mgr.GetClient(),
|
||||
Log: log.WithField("type", "createSecretEventHandler"),
|
||||
Client: mgr.GetClient(),
|
||||
Log: log.WithField("type", "createSecretEventHandler"),
|
||||
ApplicationSetNamespaces: r.ApplicationSetNamespaces,
|
||||
}).
|
||||
Complete(r)
|
||||
}
|
||||
@@ -1310,6 +1323,11 @@ func (r *ApplicationSetReconciler) updateResourcesStatus(ctx context.Context, lo
|
||||
sort.Slice(statuses, func(i, j int) bool {
|
||||
return statuses[i].Name < statuses[j].Name
|
||||
})
|
||||
|
||||
if r.MaxResourcesStatusCount > 0 && len(statuses) > r.MaxResourcesStatusCount {
|
||||
logCtx.Warnf("Truncating ApplicationSet %s resource status from %d to max allowed %d entries", appset.Name, len(statuses), r.MaxResourcesStatusCount)
|
||||
statuses = statuses[:r.MaxResourcesStatusCount]
|
||||
}
|
||||
appset.Status.Resources = statuses
|
||||
// DefaultRetry will retry 5 times with a backoff factor of 1, jitter of 0.1 and a duration of 10ms
|
||||
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
|
||||
@@ -1614,14 +1632,15 @@ func shouldRequeueForApplicationSet(appSetOld, appSetNew *argov1alpha1.Applicati
|
||||
}
|
||||
}
|
||||
|
||||
// only compare the applicationset spec, annotations, labels and finalizers, specifically avoiding
|
||||
// only compare the applicationset spec, annotations, labels and finalizers, deletionTimestamp, specifically avoiding
|
||||
// the status field. status is owned by the applicationset controller,
|
||||
// and we do not need to requeue when it does bookkeeping
|
||||
// NB: the ApplicationDestination comes from the ApplicationSpec being embedded
|
||||
// in the ApplicationSetTemplate from the generators
|
||||
if !cmp.Equal(appSetOld.Spec, appSetNew.Spec, cmpopts.EquateEmpty(), cmpopts.EquateComparable(argov1alpha1.ApplicationDestination{})) ||
|
||||
!cmp.Equal(appSetOld.GetLabels(), appSetNew.GetLabels(), cmpopts.EquateEmpty()) ||
|
||||
!cmp.Equal(appSetOld.GetFinalizers(), appSetNew.GetFinalizers(), cmpopts.EquateEmpty()) {
|
||||
!cmp.Equal(appSetOld.GetFinalizers(), appSetNew.GetFinalizers(), cmpopts.EquateEmpty()) ||
|
||||
!cmp.Equal(appSetOld.DeletionTimestamp, appSetNew.DeletionTimestamp, cmpopts.EquateEmpty()) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -589,6 +589,72 @@ func TestCreateOrUpdateInCluster(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Ensure that hydrate annotation is preserved from an existing app",
|
||||
appSet: v1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "name",
|
||||
Namespace: "namespace",
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSetSpec{
|
||||
Template: v1alpha1.ApplicationSetTemplate{
|
||||
Spec: v1alpha1.ApplicationSpec{
|
||||
Project: "project",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
existingApps: []v1alpha1.Application{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: application.ApplicationKind,
|
||||
APIVersion: "argoproj.io/v1alpha1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "app1",
|
||||
Namespace: "namespace",
|
||||
ResourceVersion: "2",
|
||||
Annotations: map[string]string{
|
||||
"annot-key": "annot-value",
|
||||
v1alpha1.AnnotationKeyHydrate: string(v1alpha1.RefreshTypeNormal),
|
||||
},
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSpec{
|
||||
Project: "project",
|
||||
},
|
||||
},
|
||||
},
|
||||
desiredApps: []v1alpha1.Application{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "app1",
|
||||
Namespace: "namespace",
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSpec{
|
||||
Project: "project",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: []v1alpha1.Application{
|
||||
{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: application.ApplicationKind,
|
||||
APIVersion: "argoproj.io/v1alpha1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "app1",
|
||||
Namespace: "namespace",
|
||||
ResourceVersion: "3",
|
||||
Annotations: map[string]string{
|
||||
v1alpha1.AnnotationKeyHydrate: string(v1alpha1.RefreshTypeNormal),
|
||||
},
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSpec{
|
||||
Project: "project",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Ensure that configured preserved annotations are preserved from an existing app",
|
||||
appSet: v1alpha1.ApplicationSet{
|
||||
@@ -6117,10 +6183,11 @@ func TestUpdateResourceStatus(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, cc := range []struct {
|
||||
name string
|
||||
appSet v1alpha1.ApplicationSet
|
||||
apps []v1alpha1.Application
|
||||
expectedResources []v1alpha1.ResourceStatus
|
||||
name string
|
||||
appSet v1alpha1.ApplicationSet
|
||||
apps []v1alpha1.Application
|
||||
expectedResources []v1alpha1.ResourceStatus
|
||||
maxResourcesStatusCount int
|
||||
}{
|
||||
{
|
||||
name: "handles an empty application list",
|
||||
@@ -6284,6 +6351,73 @@ func TestUpdateResourceStatus(t *testing.T) {
|
||||
apps: []v1alpha1.Application{},
|
||||
expectedResources: nil,
|
||||
},
|
||||
{
|
||||
name: "truncates resources status list to",
|
||||
appSet: v1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "name",
|
||||
Namespace: "argocd",
|
||||
},
|
||||
Status: v1alpha1.ApplicationSetStatus{
|
||||
Resources: []v1alpha1.ResourceStatus{
|
||||
{
|
||||
Name: "app1",
|
||||
Status: v1alpha1.SyncStatusCodeOutOfSync,
|
||||
Health: &v1alpha1.HealthStatus{
|
||||
Status: health.HealthStatusProgressing,
|
||||
Message: "this is progressing",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "app2",
|
||||
Status: v1alpha1.SyncStatusCodeOutOfSync,
|
||||
Health: &v1alpha1.HealthStatus{
|
||||
Status: health.HealthStatusProgressing,
|
||||
Message: "this is progressing",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
apps: []v1alpha1.Application{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "app1",
|
||||
},
|
||||
Status: v1alpha1.ApplicationStatus{
|
||||
Sync: v1alpha1.SyncStatus{
|
||||
Status: v1alpha1.SyncStatusCodeSynced,
|
||||
},
|
||||
Health: v1alpha1.AppHealthStatus{
|
||||
Status: health.HealthStatusHealthy,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "app2",
|
||||
},
|
||||
Status: v1alpha1.ApplicationStatus{
|
||||
Sync: v1alpha1.SyncStatus{
|
||||
Status: v1alpha1.SyncStatusCodeSynced,
|
||||
},
|
||||
Health: v1alpha1.AppHealthStatus{
|
||||
Status: health.HealthStatusHealthy,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedResources: []v1alpha1.ResourceStatus{
|
||||
{
|
||||
Name: "app1",
|
||||
Status: v1alpha1.SyncStatusCodeSynced,
|
||||
Health: &v1alpha1.HealthStatus{
|
||||
Status: health.HealthStatusHealthy,
|
||||
},
|
||||
},
|
||||
},
|
||||
maxResourcesStatusCount: 1,
|
||||
},
|
||||
} {
|
||||
t.Run(cc.name, func(t *testing.T) {
|
||||
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
|
||||
@@ -6294,13 +6428,14 @@ func TestUpdateResourceStatus(t *testing.T) {
|
||||
argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset)
|
||||
|
||||
r := ApplicationSetReconciler{
|
||||
Client: client,
|
||||
Scheme: scheme,
|
||||
Recorder: record.NewFakeRecorder(1),
|
||||
Generators: map[string]generators.Generator{},
|
||||
ArgoDB: argodb,
|
||||
KubeClientset: kubeclientset,
|
||||
Metrics: metrics,
|
||||
Client: client,
|
||||
Scheme: scheme,
|
||||
Recorder: record.NewFakeRecorder(1),
|
||||
Generators: map[string]generators.Generator{},
|
||||
ArgoDB: argodb,
|
||||
KubeClientset: kubeclientset,
|
||||
Metrics: metrics,
|
||||
MaxResourcesStatusCount: cc.maxResourcesStatusCount,
|
||||
}
|
||||
|
||||
err := r.updateResourcesStatus(t.Context(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps)
|
||||
@@ -6813,6 +6948,28 @@ func TestApplicationSetOwnsHandlerUpdate(t *testing.T) {
|
||||
enableProgressiveSyncs: false,
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "deletionTimestamp present when progressive sync enabled",
|
||||
appSetOld: buildAppSet(map[string]string{}),
|
||||
appSetNew: &v1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
DeletionTimestamp: &metav1.Time{Time: time.Now()},
|
||||
},
|
||||
},
|
||||
enableProgressiveSyncs: true,
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "deletionTimestamp present when progressive sync disabled",
|
||||
appSetOld: buildAppSet(map[string]string{}),
|
||||
appSetNew: &v1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
DeletionTimestamp: &metav1.Time{Time: time.Now()},
|
||||
},
|
||||
},
|
||||
enableProgressiveSyncs: false,
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
@@ -6961,6 +7118,36 @@ func TestShouldRequeueForApplicationSet(t *testing.T) {
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "ApplicationSetWithDeletionTimestamp",
|
||||
args: args{
|
||||
appSetOld: &v1alpha1.ApplicationSet{
|
||||
Status: v1alpha1.ApplicationSetStatus{
|
||||
ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{
|
||||
{
|
||||
Application: "app1",
|
||||
Status: "Healthy",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
appSetNew: &v1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
DeletionTimestamp: &metav1.Time{Time: time.Now()},
|
||||
},
|
||||
Status: v1alpha1.ApplicationSetStatus{
|
||||
ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{
|
||||
{
|
||||
Application: "app1",
|
||||
Status: "Waiting",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
enableProgressiveSyncs: false,
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -7198,3 +7385,82 @@ func TestSyncApplication(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReconcileProgressiveSyncDisabled(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
err := v1alpha1.AddToScheme(scheme)
|
||||
require.NoError(t, err)
|
||||
|
||||
kubeclientset := kubefake.NewSimpleClientset([]runtime.Object{}...)
|
||||
|
||||
for _, cc := range []struct {
|
||||
name string
|
||||
appSet v1alpha1.ApplicationSet
|
||||
enableProgressiveSyncs bool
|
||||
expectedAppStatuses []v1alpha1.ApplicationSetApplicationStatus
|
||||
}{
|
||||
{
|
||||
name: "clears applicationStatus when Progressive Sync is disabled",
|
||||
appSet: v1alpha1.ApplicationSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-appset",
|
||||
Namespace: "argocd",
|
||||
},
|
||||
Spec: v1alpha1.ApplicationSetSpec{
|
||||
Generators: []v1alpha1.ApplicationSetGenerator{},
|
||||
Template: v1alpha1.ApplicationSetTemplate{},
|
||||
},
|
||||
Status: v1alpha1.ApplicationSetStatus{
|
||||
ApplicationStatus: []v1alpha1.ApplicationSetApplicationStatus{
|
||||
{
|
||||
Application: "test-appset-guestbook",
|
||||
Message: "Application resource became Healthy, updating status from Progressing to Healthy.",
|
||||
Status: "Healthy",
|
||||
Step: "1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
enableProgressiveSyncs: false,
|
||||
expectedAppStatuses: nil,
|
||||
},
|
||||
} {
|
||||
t.Run(cc.name, func(t *testing.T) {
|
||||
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&cc.appSet).WithStatusSubresource(&cc.appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build()
|
||||
metrics := appsetmetrics.NewFakeAppsetMetrics()
|
||||
|
||||
argodb := db.NewDB("argocd", settings.NewSettingsManager(t.Context(), kubeclientset, "argocd"), kubeclientset)
|
||||
|
||||
r := ApplicationSetReconciler{
|
||||
Client: client,
|
||||
Scheme: scheme,
|
||||
Renderer: &utils.Render{},
|
||||
Recorder: record.NewFakeRecorder(1),
|
||||
Generators: map[string]generators.Generator{},
|
||||
ArgoDB: argodb,
|
||||
KubeClientset: kubeclientset,
|
||||
Metrics: metrics,
|
||||
EnableProgressiveSyncs: cc.enableProgressiveSyncs,
|
||||
}
|
||||
|
||||
req := ctrl.Request{
|
||||
NamespacedName: types.NamespacedName{
|
||||
Namespace: cc.appSet.Namespace,
|
||||
Name: cc.appSet.Name,
|
||||
},
|
||||
}
|
||||
|
||||
// Run reconciliation
|
||||
_, err = r.Reconcile(t.Context(), req)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Fetch the updated ApplicationSet
|
||||
var updatedAppSet v1alpha1.ApplicationSet
|
||||
err = r.Get(t.Context(), req.NamespacedName, &updatedAppSet)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify the applicationStatus field
|
||||
assert.Equal(t, cc.expectedAppStatuses, updatedAppSet.Status.ApplicationStatus, "applicationStatus should match expected value")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/utils"
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
argoprojiov1alpha1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
)
|
||||
@@ -22,8 +23,9 @@ import (
|
||||
// requeue any related ApplicationSets.
|
||||
type clusterSecretEventHandler struct {
|
||||
// handler.EnqueueRequestForOwner
|
||||
Log log.FieldLogger
|
||||
Client client.Client
|
||||
Log log.FieldLogger
|
||||
Client client.Client
|
||||
ApplicationSetNamespaces []string
|
||||
}
|
||||
|
||||
func (h *clusterSecretEventHandler) Create(ctx context.Context, e event.CreateEvent, q workqueue.TypedRateLimitingInterface[reconcile.Request]) {
|
||||
@@ -68,6 +70,10 @@ func (h *clusterSecretEventHandler) queueRelatedAppGenerators(ctx context.Contex
|
||||
|
||||
h.Log.WithField("count", len(appSetList.Items)).Info("listed ApplicationSets")
|
||||
for _, appSet := range appSetList.Items {
|
||||
if !utils.IsNamespaceAllowed(h.ApplicationSetNamespaces, appSet.GetNamespace()) {
|
||||
// Ignore it as not part of the allowed list of namespaces in which to watch Appsets
|
||||
continue
|
||||
}
|
||||
foundClusterGenerator := false
|
||||
for _, generator := range appSet.Spec.Generators {
|
||||
if generator.Clusters != nil {
|
||||
|
||||
@@ -137,7 +137,7 @@ func TestClusterEventHandler(t *testing.T) {
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-app-set",
|
||||
Namespace: "another-namespace",
|
||||
Namespace: "argocd",
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSetSpec{
|
||||
Generators: []argov1alpha1.ApplicationSetGenerator{
|
||||
@@ -171,9 +171,37 @@ func TestClusterEventHandler(t *testing.T) {
|
||||
},
|
||||
},
|
||||
expectedRequests: []reconcile.Request{
|
||||
{NamespacedName: types.NamespacedName{Namespace: "another-namespace", Name: "my-app-set"}},
|
||||
{NamespacedName: types.NamespacedName{Namespace: "argocd", Name: "my-app-set"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cluster generators in other namespaces should not match",
|
||||
items: []argov1alpha1.ApplicationSet{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-app-set",
|
||||
Namespace: "my-namespace-not-allowed",
|
||||
},
|
||||
Spec: argov1alpha1.ApplicationSetSpec{
|
||||
Generators: []argov1alpha1.ApplicationSetGenerator{
|
||||
{
|
||||
Clusters: &argov1alpha1.ClusterGenerator{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
secret: corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "argocd",
|
||||
Name: "my-secret",
|
||||
Labels: map[string]string{
|
||||
argocommon.LabelKeySecretType: argocommon.LabelValueSecretTypeCluster,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedRequests: []reconcile.Request{},
|
||||
},
|
||||
{
|
||||
name: "non-argo cd secret should not match",
|
||||
items: []argov1alpha1.ApplicationSet{
|
||||
@@ -552,8 +580,9 @@ func TestClusterEventHandler(t *testing.T) {
|
||||
fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithLists(&appSetList).Build()
|
||||
|
||||
handler := &clusterSecretEventHandler{
|
||||
Client: fakeClient,
|
||||
Log: log.WithField("type", "createSecretEventHandler"),
|
||||
Client: fakeClient,
|
||||
Log: log.WithField("type", "createSecretEventHandler"),
|
||||
ApplicationSetNamespaces: []string{"argocd"},
|
||||
}
|
||||
|
||||
mockAddRateLimitingInterface := mockAddRateLimitingInterface{}
|
||||
|
||||
@@ -29,10 +29,10 @@ type GitGenerator struct {
|
||||
}
|
||||
|
||||
// NewGitGenerator creates a new instance of Git Generator
|
||||
func NewGitGenerator(repos services.Repos, namespace string) Generator {
|
||||
func NewGitGenerator(repos services.Repos, controllerNamespace string) Generator {
|
||||
g := &GitGenerator{
|
||||
repos: repos,
|
||||
namespace: namespace,
|
||||
namespace: controllerNamespace,
|
||||
}
|
||||
|
||||
return g
|
||||
@@ -78,11 +78,11 @@ func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Applic
|
||||
if !strings.Contains(appSet.Spec.Template.Spec.Project, "{{") {
|
||||
project := appSet.Spec.Template.Spec.Project
|
||||
appProject := &argoprojiov1alpha1.AppProject{}
|
||||
namespace := g.namespace
|
||||
if namespace == "" {
|
||||
namespace = appSet.Namespace
|
||||
controllerNamespace := g.namespace
|
||||
if controllerNamespace == "" {
|
||||
controllerNamespace = appSet.Namespace
|
||||
}
|
||||
if err := client.Get(context.TODO(), types.NamespacedName{Name: project, Namespace: namespace}, appProject); err != nil {
|
||||
if err := client.Get(context.TODO(), types.NamespacedName{Name: project, Namespace: controllerNamespace}, appProject); err != nil {
|
||||
return nil, fmt.Errorf("error getting project %s: %w", project, err)
|
||||
}
|
||||
// we need to verify the signature on the Git revision if GPG is enabled
|
||||
|
||||
@@ -10,15 +10,15 @@ import (
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/services"
|
||||
)
|
||||
|
||||
func GetGenerators(ctx context.Context, c client.Client, k8sClient kubernetes.Interface, namespace string, argoCDService services.Repos, dynamicClient dynamic.Interface, scmConfig SCMConfig) map[string]Generator {
|
||||
func GetGenerators(ctx context.Context, c client.Client, k8sClient kubernetes.Interface, controllerNamespace string, argoCDService services.Repos, dynamicClient dynamic.Interface, scmConfig SCMConfig) map[string]Generator {
|
||||
terminalGenerators := map[string]Generator{
|
||||
"List": NewListGenerator(),
|
||||
"Clusters": NewClusterGenerator(ctx, c, k8sClient, namespace),
|
||||
"Git": NewGitGenerator(argoCDService, namespace),
|
||||
"Clusters": NewClusterGenerator(ctx, c, k8sClient, controllerNamespace),
|
||||
"Git": NewGitGenerator(argoCDService, controllerNamespace),
|
||||
"SCMProvider": NewSCMProviderGenerator(c, scmConfig),
|
||||
"ClusterDecisionResource": NewDuckTypeGenerator(ctx, dynamicClient, k8sClient, namespace),
|
||||
"ClusterDecisionResource": NewDuckTypeGenerator(ctx, dynamicClient, k8sClient, controllerNamespace),
|
||||
"PullRequest": NewPullRequestGenerator(c, scmConfig),
|
||||
"Plugin": NewPluginGenerator(c, namespace),
|
||||
"Plugin": NewPluginGenerator(c, controllerNamespace),
|
||||
}
|
||||
|
||||
nestedGenerators := map[string]Generator{
|
||||
|
||||
@@ -3,12 +3,11 @@ package pull_request
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
bitbucketv1 "github.com/gfleury/go-bitbucket-v1"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/utils"
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/services"
|
||||
)
|
||||
|
||||
type BitbucketService struct {
|
||||
@@ -49,15 +48,10 @@ func NewBitbucketServiceNoAuth(ctx context.Context, url, projectKey, repositoryS
|
||||
}
|
||||
|
||||
func newBitbucketService(ctx context.Context, bitbucketConfig *bitbucketv1.Configuration, projectKey, repositorySlug string, scmRootCAPath string, insecure bool, caCerts []byte) (PullRequestService, error) {
|
||||
bitbucketConfig.BasePath = utils.NormalizeBitbucketBasePath(bitbucketConfig.BasePath)
|
||||
tlsConfig := utils.GetTlsConfig(scmRootCAPath, insecure, caCerts)
|
||||
bitbucketConfig.HTTPClient = &http.Client{Transport: &http.Transport{
|
||||
TLSClientConfig: tlsConfig,
|
||||
}}
|
||||
bitbucketClient := bitbucketv1.NewAPIClient(ctx, bitbucketConfig)
|
||||
bbClient := services.SetupBitbucketClient(ctx, bitbucketConfig, scmRootCAPath, insecure, caCerts)
|
||||
|
||||
return &BitbucketService{
|
||||
client: bitbucketClient,
|
||||
client: bbClient,
|
||||
projectKey: projectKey,
|
||||
repositorySlug: repositorySlug,
|
||||
}, nil
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
bitbucketv1 "github.com/gfleury/go-bitbucket-v1"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/utils"
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/services"
|
||||
)
|
||||
|
||||
type BitbucketServerProvider struct {
|
||||
@@ -49,15 +49,10 @@ func NewBitbucketServerProviderNoAuth(ctx context.Context, url, projectKey strin
|
||||
}
|
||||
|
||||
func newBitbucketServerProvider(ctx context.Context, bitbucketConfig *bitbucketv1.Configuration, projectKey string, allBranches bool, scmRootCAPath string, insecure bool, caCerts []byte) (*BitbucketServerProvider, error) {
|
||||
bitbucketConfig.BasePath = utils.NormalizeBitbucketBasePath(bitbucketConfig.BasePath)
|
||||
tlsConfig := utils.GetTlsConfig(scmRootCAPath, insecure, caCerts)
|
||||
bitbucketConfig.HTTPClient = &http.Client{Transport: &http.Transport{
|
||||
TLSClientConfig: tlsConfig,
|
||||
}}
|
||||
bitbucketClient := bitbucketv1.NewAPIClient(ctx, bitbucketConfig)
|
||||
bbClient := services.SetupBitbucketClient(ctx, bitbucketConfig, scmRootCAPath, insecure, caCerts)
|
||||
|
||||
return &BitbucketServerProvider{
|
||||
client: bitbucketClient,
|
||||
client: bbClient,
|
||||
projectKey: projectKey,
|
||||
allBranches: allBranches,
|
||||
}, nil
|
||||
|
||||
22
applicationset/services/util.go
Normal file
22
applicationset/services/util.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
bitbucketv1 "github.com/gfleury/go-bitbucket-v1"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/applicationset/utils"
|
||||
)
|
||||
|
||||
// SetupBitbucketClient configures and creates a Bitbucket API client with TLS settings
|
||||
func SetupBitbucketClient(ctx context.Context, config *bitbucketv1.Configuration, scmRootCAPath string, insecure bool, caCerts []byte) *bitbucketv1.APIClient {
|
||||
config.BasePath = utils.NormalizeBitbucketBasePath(config.BasePath)
|
||||
tlsConfig := utils.GetTlsConfig(scmRootCAPath, insecure, caCerts)
|
||||
|
||||
transport := http.DefaultTransport.(*http.Transport).Clone()
|
||||
transport.TLSClientConfig = tlsConfig
|
||||
config.HTTPClient = &http.Client{Transport: transport}
|
||||
|
||||
return bitbucketv1.NewAPIClient(ctx, config)
|
||||
}
|
||||
36
applicationset/services/util_test.go
Normal file
36
applicationset/services/util_test.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
bitbucketv1 "github.com/gfleury/go-bitbucket-v1"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSetupBitbucketClient(t *testing.T) {
|
||||
ctx := t.Context()
|
||||
cfg := &bitbucketv1.Configuration{}
|
||||
|
||||
// Act
|
||||
client := SetupBitbucketClient(ctx, cfg, "", false, nil)
|
||||
|
||||
// Assert
|
||||
require.NotNil(t, client, "expected client to be created")
|
||||
require.NotNil(t, cfg.HTTPClient, "expected HTTPClient to be set")
|
||||
|
||||
// The transport should be a clone of DefaultTransport
|
||||
tr, ok := cfg.HTTPClient.Transport.(*http.Transport)
|
||||
require.True(t, ok, "expected HTTPClient.Transport to be *http.Transport")
|
||||
require.NotSame(t, http.DefaultTransport, tr, "transport should be a clone, not the global DefaultTransport")
|
||||
|
||||
// Ensure TLSClientConfig is set
|
||||
require.IsType(t, &tls.Config{}, tr.TLSClientConfig)
|
||||
|
||||
// Defaults from http.DefaultTransport.Clone() should be preserved
|
||||
require.Greater(t, tr.IdleConnTimeout, time.Duration(0), "IdleConnTimeout should be non-zero")
|
||||
require.Positive(t, tr.MaxIdleConns, "MaxIdleConns should be non-zero")
|
||||
require.Greater(t, tr.TLSHandshakeTimeout, time.Duration(0), "TLSHandshakeTimeout should be non-zero")
|
||||
}
|
||||
@@ -26,10 +26,14 @@ import (
|
||||
"github.com/go-playground/webhooks/v6/github"
|
||||
"github.com/go-playground/webhooks/v6/gitlab"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/util/guard"
|
||||
)
|
||||
|
||||
const payloadQueueSize = 50000
|
||||
|
||||
const panicMsgAppSet = "panic while processing applicationset-controller webhook event"
|
||||
|
||||
type WebhookHandler struct {
|
||||
sync.WaitGroup // for testing
|
||||
github *github.Webhook
|
||||
@@ -102,6 +106,7 @@ func NewWebhookHandler(webhookParallelism int, argocdSettingsMgr *argosettings.S
|
||||
}
|
||||
|
||||
func (h *WebhookHandler) startWorkerPool(webhookParallelism int) {
|
||||
compLog := log.WithField("component", "applicationset-webhook")
|
||||
for i := 0; i < webhookParallelism; i++ {
|
||||
h.Add(1)
|
||||
go func() {
|
||||
@@ -111,7 +116,7 @@ func (h *WebhookHandler) startWorkerPool(webhookParallelism int) {
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
h.HandleEvent(payload)
|
||||
guard.RecoverAndLog(func() { h.HandleEvent(payload) }, compLog, panicMsgAppSet)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
# p, <role/user/group>, <resource>, <action>, <object>, <allow/deny>
|
||||
|
||||
p, role:readonly, applications, get, */*, allow
|
||||
p, role:readonly, applicationsets, get, */*, allow
|
||||
p, role:readonly, certificates, get, *, allow
|
||||
p, role:readonly, clusters, get, *, allow
|
||||
p, role:readonly, repositories, get, *, allow
|
||||
|
||||
|
81
assets/swagger.json
generated
81
assets/swagger.json
generated
@@ -1473,10 +1473,11 @@
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"description": "Deprecated: use RunResourceActionV2 instead. This version does not support resource action parameters but is\nmaintained for backward compatibility. It will be removed in a future release.",
|
||||
"tags": [
|
||||
"ApplicationService"
|
||||
],
|
||||
"summary": "RunResourceAction run resource action",
|
||||
"summary": "RunResourceAction runs a resource action",
|
||||
"operationId": "ApplicationService_RunResourceAction",
|
||||
"parameters": [
|
||||
{
|
||||
@@ -1490,7 +1491,81 @@
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/applicationResourceActionRunRequest"
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "namespace",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "resourceName",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "version",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "group",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "kind",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "appNamespace",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "project",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/applicationApplicationResponse"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/runtimeError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/applications/{name}/resource/actions/v2": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"ApplicationService"
|
||||
],
|
||||
"summary": "RunResourceActionV2 runs a resource action with parameters",
|
||||
"operationId": "ApplicationService_RunResourceActionV2",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/applicationResourceActionRunRequestV2"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -5127,7 +5202,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"applicationResourceActionRunRequest": {
|
||||
"applicationResourceActionRunRequestV2": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
|
||||
@@ -79,6 +79,7 @@ func NewCommand() *cobra.Command {
|
||||
enableScmProviders bool
|
||||
webhookParallelism int
|
||||
tokenRefStrictMode bool
|
||||
maxResourcesStatusCount int
|
||||
)
|
||||
scheme := runtime.NewScheme()
|
||||
_ = clientgoscheme.AddToScheme(scheme)
|
||||
@@ -231,6 +232,7 @@ func NewCommand() *cobra.Command {
|
||||
GlobalPreservedAnnotations: globalPreservedAnnotations,
|
||||
GlobalPreservedLabels: globalPreservedLabels,
|
||||
Metrics: &metrics,
|
||||
MaxResourcesStatusCount: maxResourcesStatusCount,
|
||||
}).SetupWithManager(mgr, enableProgressiveSyncs, maxConcurrentReconciliations); err != nil {
|
||||
log.Error(err, "unable to create controller", "controller", "ApplicationSet")
|
||||
os.Exit(1)
|
||||
@@ -275,6 +277,7 @@ func NewCommand() *cobra.Command {
|
||||
command.Flags().IntVar(&webhookParallelism, "webhook-parallelism-limit", env.ParseNumFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT", 50, 1, 1000), "Number of webhook requests processed concurrently")
|
||||
command.Flags().StringSliceVar(&metricsAplicationsetLabels, "metrics-applicationset-labels", []string{}, "List of Application labels that will be added to the argocd_applicationset_labels metric")
|
||||
command.Flags().BoolVar(&enableGitHubAPIMetrics, "enable-github-api-metrics", env.ParseBoolFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_GITHUB_API_METRICS", false), "Enable GitHub API metrics for generators that use the GitHub API")
|
||||
command.Flags().IntVar(&maxResourcesStatusCount, "max-resources-status-count", env.ParseNumFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_MAX_RESOURCES_STATUS_COUNT", 0, 0, math.MaxInt), "Max number of resources stored in appset status.")
|
||||
|
||||
return &command
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
//go:build !darwin || (cgo && darwin)
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
25
cmd/argocd-k8s-auth/commands/azure_no_cgo.go
Normal file
25
cmd/argocd-k8s-auth/commands/azure_no_cgo.go
Normal file
@@ -0,0 +1,25 @@
|
||||
//go:build darwin && !cgo
|
||||
|
||||
// Package commands
|
||||
// This file is used when the GOOS is darwin and CGO is not enabled.
|
||||
// It provides a no-op implementation of newAzureCommand to allow goreleaser to build
|
||||
// a darwin binary on a linux machine.
|
||||
package commands
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/util/workloadidentity"
|
||||
)
|
||||
|
||||
func newAzureCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: "azure",
|
||||
Run: func(c *cobra.Command, _ []string) {
|
||||
log.Fatalf(workloadidentity.CGOError)
|
||||
},
|
||||
}
|
||||
return command
|
||||
}
|
||||
@@ -30,11 +30,12 @@ func NewNotificationsCommand() *cobra.Command {
|
||||
)
|
||||
|
||||
var argocdService service.Service
|
||||
|
||||
toolsCommand := cmd.NewToolsCommand(
|
||||
"notifications",
|
||||
"argocd admin notifications",
|
||||
applications,
|
||||
settings.GetFactorySettingsForCLI(argocdService, "argocd-notifications-secret", "argocd-notifications-cm", false),
|
||||
settings.GetFactorySettingsForCLI(func() service.Service { return argocdService }, "argocd-notifications-secret", "argocd-notifications-cm", false),
|
||||
func(clientConfig clientcmd.ClientConfig) {
|
||||
k8sCfg, err := clientConfig.ClientConfig()
|
||||
if err != nil {
|
||||
|
||||
@@ -8,23 +8,23 @@ import (
|
||||
"strconv"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/util/templates"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/cmd/util"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc/codes"
|
||||
"k8s.io/utils/ptr"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/cmd/argocd/commands/headless"
|
||||
"github.com/argoproj/argo-cd/v3/cmd/util"
|
||||
argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient"
|
||||
applicationpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/application"
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application"
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/util/argo"
|
||||
"github.com/argoproj/argo-cd/v3/util/errors"
|
||||
"github.com/argoproj/argo-cd/v3/util/grpc"
|
||||
utilio "github.com/argoproj/argo-cd/v3/util/io"
|
||||
"github.com/argoproj/argo-cd/v3/util/templates"
|
||||
)
|
||||
|
||||
type DisplayedAction struct {
|
||||
@@ -192,7 +192,26 @@ func NewApplicationResourceActionsRunCommand(clientOpts *argocdclient.ClientOpti
|
||||
obj := filteredObjects[i]
|
||||
gvk := obj.GroupVersionKind()
|
||||
objResourceName := obj.GetName()
|
||||
_, err := appIf.RunResourceAction(ctx, &applicationpkg.ResourceActionRunRequest{
|
||||
_, err := appIf.RunResourceActionV2(ctx, &applicationpkg.ResourceActionRunRequestV2{
|
||||
Name: &appName,
|
||||
AppNamespace: &appNs,
|
||||
Namespace: ptr.To(obj.GetNamespace()),
|
||||
ResourceName: ptr.To(objResourceName),
|
||||
Group: ptr.To(gvk.Group),
|
||||
Kind: ptr.To(gvk.Kind),
|
||||
Version: ptr.To(gvk.GroupVersion().Version),
|
||||
Action: ptr.To(actionName),
|
||||
// TODO: add support for parameters
|
||||
})
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
if grpc.UnwrapGRPCStatus(err).Code() != codes.Unimplemented {
|
||||
errors.CheckError(err)
|
||||
}
|
||||
fmt.Println("RunResourceActionV2 is not supported by the server, falling back to RunResourceAction.")
|
||||
//nolint:staticcheck // RunResourceAction is deprecated, but we still need to support it for backward compatibility.
|
||||
_, err = appIf.RunResourceAction(ctx, &applicationpkg.ResourceActionRunRequest{
|
||||
Name: &appName,
|
||||
AppNamespace: &appNs,
|
||||
Namespace: ptr.To(obj.GetNamespace()),
|
||||
|
||||
@@ -2228,10 +2228,15 @@ func (c *fakeAppServiceClient) ListResourceActions(_ context.Context, _ *applica
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// nolint:staticcheck // ResourceActionRunRequest is deprecated, but we still need to implement it to satisfy the server interface.
|
||||
func (c *fakeAppServiceClient) RunResourceAction(_ context.Context, _ *applicationpkg.ResourceActionRunRequest, _ ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *fakeAppServiceClient) RunResourceActionV2(_ context.Context, _ *applicationpkg.ResourceActionRunRequestV2, _ ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *fakeAppServiceClient) DeleteResource(_ context.Context, _ *applicationpkg.ApplicationResourceDeleteRequest, _ ...grpc.CallOption) (*applicationpkg.ApplicationResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ func extractHealthStatusAndReason(node v1alpha1.ResourceNode) (healthStatus heal
|
||||
healthStatus = node.Health.Status
|
||||
reason = node.Health.Message
|
||||
}
|
||||
return
|
||||
return healthStatus, reason
|
||||
}
|
||||
|
||||
func treeViewAppGet(prefix string, uidToNodeMap map[string]v1alpha1.ResourceNode, parentToChildMap map[string][]string, parent v1alpha1.ResourceNode, mapNodeNameToResourceState map[string]*resourceState, w *tabwriter.Writer) {
|
||||
|
||||
@@ -220,6 +220,7 @@ type hydratorMetadataFile struct {
|
||||
// Subject is the subject line of the DRY commit message, i.e. `git show --format=%s`.
|
||||
Subject string `json:"subject,omitempty"`
|
||||
// Body is the body of the DRY commit message, excluding the subject line, i.e. `git show --format=%b`.
|
||||
// Known Argocd- trailers with valid values are removed, but all other trailers are kept.
|
||||
Body string `json:"body,omitempty"`
|
||||
References []v1alpha1.RevisionReference `json:"references,omitempty"`
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/commitserver/apiclient"
|
||||
appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/util/git"
|
||||
"github.com/argoproj/argo-cd/v3/util/io"
|
||||
)
|
||||
|
||||
@@ -48,8 +49,10 @@ func WriteForPaths(root *os.Root, repoUrl, drySha string, dryCommitMetadata *app
|
||||
|
||||
subject, body, _ := strings.Cut(message, "\n\n")
|
||||
|
||||
_, bodyMinusTrailers := git.GetReferences(log.WithFields(log.Fields{"repo": repoUrl, "revision": drySha}), body)
|
||||
|
||||
// Write the top-level readme.
|
||||
err := writeMetadata(root, "", hydratorMetadataFile{DrySHA: drySha, RepoURL: repoUrl, Author: author, Subject: subject, Body: body, Date: date, References: references})
|
||||
err := writeMetadata(root, "", hydratorMetadataFile{DrySHA: drySha, RepoURL: repoUrl, Author: author, Subject: subject, Body: bodyMinusTrailers, Date: date, References: references})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write top-level hydrator metadata: %w", err)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -73,9 +72,13 @@ func TestWriteForPaths(t *testing.T) {
|
||||
|
||||
now := metav1.NewTime(time.Now())
|
||||
metadata := &appsv1.RevisionMetadata{
|
||||
Author: "test-author",
|
||||
Date: &now,
|
||||
Message: "test-message",
|
||||
Author: "test-author",
|
||||
Date: &now,
|
||||
Message: `test-message
|
||||
|
||||
Signed-off-by: Test User <test@example.com>
|
||||
Argocd-reference-commit-sha: abc123
|
||||
`,
|
||||
References: []appsv1.RevisionReference{
|
||||
{
|
||||
Commit: &appsv1.CommitMetadata{
|
||||
@@ -97,16 +100,15 @@ func TestWriteForPaths(t *testing.T) {
|
||||
topMetadataBytes, err := os.ReadFile(topMetadataPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedSubject, expectedBody, _ := strings.Cut(metadata.Message, "\n\n")
|
||||
|
||||
var topMetadata hydratorMetadataFile
|
||||
err = json.Unmarshal(topMetadataBytes, &topMetadata)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, repoURL, topMetadata.RepoURL)
|
||||
assert.Equal(t, drySha, topMetadata.DrySHA)
|
||||
assert.Equal(t, metadata.Author, topMetadata.Author)
|
||||
assert.Equal(t, expectedSubject, topMetadata.Subject)
|
||||
assert.Equal(t, expectedBody, topMetadata.Body)
|
||||
assert.Equal(t, "test-message", topMetadata.Subject)
|
||||
// The body should exclude the Argocd- trailers.
|
||||
assert.Equal(t, "Signed-off-by: Test User <test@example.com>\n", topMetadata.Body)
|
||||
assert.Equal(t, metadata.Date.Format(time.RFC3339), topMetadata.Date)
|
||||
assert.Equal(t, metadata.References, topMetadata.References)
|
||||
|
||||
|
||||
@@ -996,7 +996,7 @@ func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext b
|
||||
appKey, shutdown := ctrl.appOperationQueue.Get()
|
||||
if shutdown {
|
||||
processNext = false
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
processNext = true
|
||||
defer func() {
|
||||
@@ -1009,16 +1009,16 @@ func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext b
|
||||
obj, exists, err := ctrl.appInformer.GetIndexer().GetByKey(appKey)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to get application '%s' from informer index: %+v", appKey, err)
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
if !exists {
|
||||
// This happens after app was deleted, but the work queue still had an entry for it.
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
origApp, ok := obj.(*appv1.Application)
|
||||
if !ok {
|
||||
log.Warnf("Key '%s' in index is not an application", appKey)
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
app := origApp.DeepCopy()
|
||||
logCtx := log.WithFields(applog.GetAppLogFields(app))
|
||||
@@ -1038,7 +1038,7 @@ func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext b
|
||||
freshApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.ObjectMeta.Namespace).Get(context.Background(), app.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
logCtx.Errorf("Failed to retrieve latest application state: %v", err)
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
app = freshApp
|
||||
}
|
||||
@@ -1060,7 +1060,7 @@ func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext b
|
||||
}
|
||||
ts.AddCheckpoint("finalize_application_deletion_ms")
|
||||
}
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
|
||||
func (ctrl *ApplicationController) processAppComparisonTypeQueueItem() (processNext bool) {
|
||||
@@ -1075,7 +1075,7 @@ func (ctrl *ApplicationController) processAppComparisonTypeQueueItem() (processN
|
||||
}()
|
||||
if shutdown {
|
||||
processNext = false
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
|
||||
if parts := strings.Split(key, "/"); len(parts) != 3 {
|
||||
@@ -1084,11 +1084,11 @@ func (ctrl *ApplicationController) processAppComparisonTypeQueueItem() (processN
|
||||
compareWith, err := strconv.Atoi(parts[2])
|
||||
if err != nil {
|
||||
log.Warnf("Unable to parse comparison type: %v", err)
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
ctrl.requestAppRefresh(ctrl.toAppQualifiedName(parts[1], parts[0]), CompareWith(compareWith).Pointer(), nil)
|
||||
}
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
|
||||
func (ctrl *ApplicationController) processProjectQueueItem() (processNext bool) {
|
||||
@@ -1103,21 +1103,21 @@ func (ctrl *ApplicationController) processProjectQueueItem() (processNext bool)
|
||||
}()
|
||||
if shutdown {
|
||||
processNext = false
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
obj, exists, err := ctrl.projInformer.GetIndexer().GetByKey(key)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to get project '%s' from informer index: %+v", key, err)
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
if !exists {
|
||||
// This happens after appproj was deleted, but the work queue still had an entry for it.
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
origProj, ok := obj.(*appv1.AppProject)
|
||||
if !ok {
|
||||
log.Warnf("Key '%s' in index is not an appproject", key)
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
|
||||
if origProj.DeletionTimestamp != nil && origProj.HasFinalizer() {
|
||||
@@ -1125,7 +1125,7 @@ func (ctrl *ApplicationController) processProjectQueueItem() (processNext bool)
|
||||
log.Warnf("Failed to finalize project deletion: %v", err)
|
||||
}
|
||||
}
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
|
||||
func (ctrl *ApplicationController) finalizeProjectDeletion(proj *appv1.AppProject) error {
|
||||
@@ -1202,7 +1202,7 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic
|
||||
if err != nil {
|
||||
logCtx.Warnf("Unable to get destination cluster: %v", err)
|
||||
app.UnSetCascadedDeletion()
|
||||
app.UnSetPostDeleteFinalizer()
|
||||
app.UnSetPostDeleteFinalizerAll()
|
||||
if err := ctrl.updateFinalizers(app); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1483,7 +1483,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli
|
||||
} else {
|
||||
state.Phase = synccommon.OperationRunning
|
||||
state.RetryCount++
|
||||
state.Message = fmt.Sprintf("%s. Retrying attempt #%d at %s.", state.Message, state.RetryCount, retryAt.Format(time.Kitchen))
|
||||
state.Message = fmt.Sprintf("%s due to application controller sync timeout. Retrying attempt #%d at %s.", state.Message, state.RetryCount, retryAt.Format(time.Kitchen))
|
||||
}
|
||||
} else if state.RetryCount > 0 {
|
||||
state.Message = fmt.Sprintf("%s (retried %d times).", state.Message, state.RetryCount)
|
||||
@@ -1618,7 +1618,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
appKey, shutdown := ctrl.appRefreshQueue.Get()
|
||||
if shutdown {
|
||||
processNext = false
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
processNext = true
|
||||
defer func() {
|
||||
@@ -1633,22 +1633,22 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
obj, exists, err := ctrl.appInformer.GetIndexer().GetByKey(appKey)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to get application '%s' from informer index: %+v", appKey, err)
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
if !exists {
|
||||
// This happens after app was deleted, but the work queue still had an entry for it.
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
origApp, ok := obj.(*appv1.Application)
|
||||
if !ok {
|
||||
log.Warnf("Key '%s' in index is not an application", appKey)
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
origApp = origApp.DeepCopy()
|
||||
needRefresh, refreshType, comparisonLevel := ctrl.needRefreshAppStatus(origApp, ctrl.statusRefreshTimeout, ctrl.statusHardRefreshTimeout)
|
||||
|
||||
if !needRefresh {
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
app := origApp.DeepCopy()
|
||||
logCtx := log.WithFields(applog.GetAppLogFields(app)).WithFields(log.Fields{
|
||||
@@ -1691,12 +1691,12 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
app.Status.Summary = tree.GetSummary(app)
|
||||
if err := ctrl.cache.SetAppResourcesTree(app.InstanceName(ctrl.namespace), tree); err != nil {
|
||||
logCtx.Errorf("Failed to cache resources tree: %v", err)
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
}
|
||||
|
||||
patchDuration = ctrl.persistAppStatus(origApp, &app.Status)
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
logCtx.Warnf("Failed to get cached managed resources for tree reconciliation, fall back to full reconciliation")
|
||||
}
|
||||
@@ -1718,14 +1718,14 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
logCtx.Warnf("failed to set app managed resources tree: %v", err)
|
||||
}
|
||||
ts.AddCheckpoint("process_refresh_app_conditions_errors_ms")
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
|
||||
destCluster, err = argo.GetDestinationCluster(context.Background(), app.Spec.Destination, ctrl.db)
|
||||
if err != nil {
|
||||
logCtx.Errorf("Failed to get destination cluster: %v", err)
|
||||
// exit the reconciliation. ctrl.refreshAppConditions should have caught the error
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
|
||||
var localManifests []string
|
||||
@@ -1766,7 +1766,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
|
||||
if stderrors.Is(err, ErrCompareStateRepo) {
|
||||
logCtx.Warnf("Ignoring temporary failed attempt to compare app state against repo: %v", err)
|
||||
return // short circuit if git error is encountered
|
||||
return processNext // short circuit if git error is encountered
|
||||
}
|
||||
|
||||
for k, v := range compareResult.timings {
|
||||
@@ -1835,14 +1835,14 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
|
||||
}
|
||||
}
|
||||
ts.AddCheckpoint("process_finalizers_ms")
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
|
||||
func (ctrl *ApplicationController) processAppHydrateQueueItem() (processNext bool) {
|
||||
appKey, shutdown := ctrl.appHydrateQueue.Get()
|
||||
if shutdown {
|
||||
processNext = false
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
processNext = true
|
||||
defer func() {
|
||||
@@ -1854,29 +1854,29 @@ func (ctrl *ApplicationController) processAppHydrateQueueItem() (processNext boo
|
||||
obj, exists, err := ctrl.appInformer.GetIndexer().GetByKey(appKey)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to get application '%s' from informer index: %+v", appKey, err)
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
if !exists {
|
||||
// This happens after app was deleted, but the work queue still had an entry for it.
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
origApp, ok := obj.(*appv1.Application)
|
||||
if !ok {
|
||||
log.Warnf("Key '%s' in index is not an application", appKey)
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
|
||||
ctrl.hydrator.ProcessAppHydrateQueueItem(origApp)
|
||||
|
||||
log.WithFields(applog.GetAppLogFields(origApp)).Debug("Successfully processed app hydrate queue item")
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
|
||||
func (ctrl *ApplicationController) processHydrationQueueItem() (processNext bool) {
|
||||
hydrationKey, shutdown := ctrl.hydrationQueue.Get()
|
||||
if shutdown {
|
||||
processNext = false
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
processNext = true
|
||||
defer func() {
|
||||
@@ -1897,7 +1897,7 @@ func (ctrl *ApplicationController) processHydrationQueueItem() (processNext bool
|
||||
ctrl.hydrator.ProcessHydrationQueueItem(hydrationKey)
|
||||
|
||||
logCtx.Debug("Successfully processed hydration queue item")
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
|
||||
func resourceStatusKey(res appv1.ResourceStatus) string {
|
||||
@@ -2060,11 +2060,11 @@ func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, new
|
||||
&appv1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: newAnnotations}, Status: *newStatus})
|
||||
if err != nil {
|
||||
logCtx.Errorf("Error constructing app status patch: %v", err)
|
||||
return
|
||||
return patchDuration
|
||||
}
|
||||
if !modified {
|
||||
logCtx.Infof("No status changes. Skipping patch")
|
||||
return
|
||||
return patchDuration
|
||||
}
|
||||
// calculate time for path call
|
||||
start := time.Now()
|
||||
|
||||
@@ -2090,7 +2090,7 @@ func TestProcessRequestedAppOperation_FailedHasRetries(t *testing.T) {
|
||||
phase, _, _ := unstructured.NestedString(receivedPatch, "status", "operationState", "phase")
|
||||
assert.Equal(t, string(synccommon.OperationRunning), phase)
|
||||
message, _, _ := unstructured.NestedString(receivedPatch, "status", "operationState", "message")
|
||||
assert.Contains(t, message, "Retrying attempt #1")
|
||||
assert.Contains(t, message, "due to application controller sync timeout. Retrying attempt #1")
|
||||
retryCount, _, _ := unstructured.NestedFloat64(receivedPatch, "status", "operationState", "retryCount")
|
||||
assert.InEpsilon(t, float64(1), retryCount, 0.0001)
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ func (h *Hydrator) ProcessHydrationQueueItem(hydrationKey HydrationQueueKey) (pr
|
||||
logCtx = logCtx.WithFields(applog.GetAppLogFields(app))
|
||||
logCtx.Errorf("Failed to hydrate app: %v", err)
|
||||
}
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
logCtx.WithField("appCount", len(relevantApps)).Debug("Successfully hydrated apps")
|
||||
finishedAt := metav1.Now()
|
||||
@@ -174,7 +174,7 @@ func (h *Hydrator) ProcessHydrationQueueItem(hydrationKey HydrationQueueKey) (pr
|
||||
logCtx.WithField("app", app.QualifiedName()).WithError(err).Error("Failed to request app refresh after hydration")
|
||||
}
|
||||
}
|
||||
return
|
||||
return processNext
|
||||
}
|
||||
|
||||
func (h *Hydrator) hydrateAppsLatestCommit(logCtx *log.Entry, hydrationKey HydrationQueueKey) ([]*appv1.Application, string, string, error) {
|
||||
|
||||
@@ -267,7 +267,7 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
|
||||
Revision: revision,
|
||||
SyncedRevision: syncedRevision,
|
||||
NoRevisionCache: noRevisionCache,
|
||||
Paths: path.GetAppRefreshPaths(app),
|
||||
Paths: path.GetSourceRefreshPaths(app, source),
|
||||
AppLabelKey: appLabelKey,
|
||||
AppName: app.InstanceName(m.namespace),
|
||||
Namespace: appNamespace,
|
||||
|
||||
@@ -108,15 +108,6 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
|
||||
}
|
||||
syncOp = *state.Operation.Sync
|
||||
|
||||
// validates if it should fail the sync if it finds shared resources
|
||||
hasSharedResource, sharedResourceMessage := hasSharedResourceCondition(app)
|
||||
if syncOp.SyncOptions.HasOption("FailOnSharedResource=true") &&
|
||||
hasSharedResource {
|
||||
state.Phase = common.OperationFailed
|
||||
state.Message = "Shared resource found: " + sharedResourceMessage
|
||||
return
|
||||
}
|
||||
|
||||
isMultiSourceRevision := app.Spec.HasMultipleSources()
|
||||
rollback := len(syncOp.Sources) > 0 || syncOp.Source != nil
|
||||
if rollback {
|
||||
@@ -207,6 +198,15 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
|
||||
syncRes.Revision = compareResult.syncStatus.Revision
|
||||
syncRes.Revisions = compareResult.syncStatus.Revisions
|
||||
|
||||
// validates if it should fail the sync if it finds shared resources
|
||||
hasSharedResource, sharedResourceMessage := hasSharedResourceCondition(app)
|
||||
if syncOp.SyncOptions.HasOption("FailOnSharedResource=true") &&
|
||||
hasSharedResource {
|
||||
state.Phase = common.OperationFailed
|
||||
state.Message = "Shared resource found: %s" + sharedResourceMessage
|
||||
return
|
||||
}
|
||||
|
||||
// If there are any comparison or spec errors error conditions do not perform the operation
|
||||
if errConditions := app.Status.GetConditions(map[v1alpha1.ApplicationConditionType]bool{
|
||||
v1alpha1.ApplicationConditionComparisonError: true,
|
||||
@@ -324,7 +324,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
|
||||
return
|
||||
}
|
||||
if impersonationEnabled {
|
||||
serviceAccountToImpersonate, err := deriveServiceAccountToImpersonate(proj, app)
|
||||
serviceAccountToImpersonate, err := deriveServiceAccountToImpersonate(proj, app, destCluster)
|
||||
if err != nil {
|
||||
state.Phase = common.OperationError
|
||||
state.Message = fmt.Sprintf("failed to find a matching service account to impersonate: %v", err)
|
||||
@@ -607,7 +607,7 @@ func syncWindowPreventsSync(app *v1alpha1.Application, proj *v1alpha1.AppProject
|
||||
|
||||
// deriveServiceAccountToImpersonate determines the service account to be used for impersonation for the sync operation.
|
||||
// The returned service account will be fully qualified including namespace and the service account name in the format system:serviceaccount:<namespace>:<service_account>
|
||||
func deriveServiceAccountToImpersonate(project *v1alpha1.AppProject, application *v1alpha1.Application) (string, error) {
|
||||
func deriveServiceAccountToImpersonate(project *v1alpha1.AppProject, application *v1alpha1.Application, destCluster *v1alpha1.Cluster) (string, error) {
|
||||
// spec.Destination.Namespace is optional. If not specified, use the Application's
|
||||
// namespace
|
||||
serviceAccountNamespace := application.Spec.Destination.Namespace
|
||||
@@ -617,7 +617,7 @@ func deriveServiceAccountToImpersonate(project *v1alpha1.AppProject, application
|
||||
// Loop through the destinationServiceAccounts and see if there is any destination that is a candidate.
|
||||
// if so, return the service account specified for that destination.
|
||||
for _, item := range project.Spec.DestinationServiceAccounts {
|
||||
dstServerMatched, err := glob.MatchWithError(item.Server, application.Spec.Destination.Server)
|
||||
dstServerMatched, err := glob.MatchWithError(item.Server, destCluster.Server)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid glob pattern for destination server: %w", err)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/argoproj/gitops-engine/pkg/sync"
|
||||
"github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
|
||||
"github.com/argoproj/gitops-engine/pkg/utils/kube"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"github.com/argoproj/argo-cd/v3/common"
|
||||
"github.com/argoproj/argo-cd/v3/controller/testdata"
|
||||
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
|
||||
"github.com/argoproj/argo-cd/v3/reposerver/apiclient"
|
||||
@@ -196,11 +197,15 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
|
||||
controller *ApplicationController
|
||||
}
|
||||
|
||||
setup := func() *fixture {
|
||||
setup := func(liveObjects map[kube.ResourceKey]*unstructured.Unstructured) *fixture {
|
||||
app := newFakeApp()
|
||||
app.Status.OperationState = nil
|
||||
app.Status.History = nil
|
||||
|
||||
if liveObjects == nil {
|
||||
liveObjects = make(map[kube.ResourceKey]*unstructured.Unstructured)
|
||||
}
|
||||
|
||||
project := &v1alpha1.AppProject{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: test.FakeArgoCDNamespace,
|
||||
@@ -208,6 +213,12 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
|
||||
},
|
||||
Spec: v1alpha1.AppProjectSpec{
|
||||
SignatureKeys: []v1alpha1.SignatureKey{{KeyID: "test"}},
|
||||
Destinations: []v1alpha1.ApplicationDestination{
|
||||
{
|
||||
Namespace: "*",
|
||||
Server: "*",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
data := fakeData{
|
||||
@@ -218,7 +229,7 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
|
||||
Server: test.FakeClusterURL,
|
||||
Revision: "abc123",
|
||||
},
|
||||
managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured),
|
||||
managedLiveObjs: liveObjects,
|
||||
}
|
||||
ctrl := newFakeController(&data, nil)
|
||||
|
||||
@@ -231,13 +242,23 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
|
||||
t.Run("will fail the sync if finds shared resources", func(t *testing.T) {
|
||||
// given
|
||||
t.Parallel()
|
||||
f := setup()
|
||||
syncErrorMsg := "deployment already applied by another application"
|
||||
condition := v1alpha1.ApplicationCondition{
|
||||
Type: v1alpha1.ApplicationConditionSharedResourceWarning,
|
||||
Message: syncErrorMsg,
|
||||
}
|
||||
f.application.Status.Conditions = append(f.application.Status.Conditions, condition)
|
||||
|
||||
sharedObject := kube.MustToUnstructured(&corev1.ConfigMap{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "ConfigMap",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "configmap1",
|
||||
Namespace: "default",
|
||||
Annotations: map[string]string{
|
||||
common.AnnotationKeyAppInstance: "guestbook:/ConfigMap:default/configmap1",
|
||||
},
|
||||
},
|
||||
})
|
||||
liveObjects := make(map[kube.ResourceKey]*unstructured.Unstructured)
|
||||
liveObjects[kube.GetResourceKey(sharedObject)] = sharedObject
|
||||
f := setup(liveObjects)
|
||||
|
||||
// Sync with source unspecified
|
||||
opState := &v1alpha1.OperationState{Operation: v1alpha1.Operation{
|
||||
@@ -251,8 +272,8 @@ func TestAppStateManager_SyncAppState(t *testing.T) {
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then
|
||||
assert.Equal(t, common.OperationFailed, opState.Phase)
|
||||
assert.Contains(t, opState.Message, syncErrorMsg)
|
||||
assert.Equal(t, synccommon.OperationFailed, opState.Phase)
|
||||
assert.Contains(t, opState.Message, "ConfigMap/configmap1 is part of applications fake-argocd-ns/my-app and guestbook")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -315,13 +336,13 @@ func TestSyncWindowDeniesSync(t *testing.T) {
|
||||
Source: &v1alpha1.ApplicationSource{},
|
||||
},
|
||||
},
|
||||
Phase: common.OperationRunning,
|
||||
Phase: synccommon.OperationRunning,
|
||||
}
|
||||
// when
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then
|
||||
assert.Equal(t, common.OperationRunning, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationRunning, opState.Phase)
|
||||
assert.Contains(t, opState.Message, opMessage)
|
||||
})
|
||||
}
|
||||
@@ -651,6 +672,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
type fixture struct {
|
||||
project *v1alpha1.AppProject
|
||||
application *v1alpha1.Application
|
||||
cluster *v1alpha1.Cluster
|
||||
}
|
||||
|
||||
setup := func(destinationServiceAccounts []v1alpha1.ApplicationDestinationServiceAccount, destinationNamespace, destinationServerURL, applicationNamespace string) *fixture {
|
||||
@@ -676,9 +698,14 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
cluster := &v1alpha1.Cluster{
|
||||
Server: "https://kubernetes.svc.local",
|
||||
Name: "test-cluster",
|
||||
}
|
||||
return &fixture{
|
||||
project: project,
|
||||
application: app,
|
||||
cluster: cluster,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -694,7 +721,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
assert.Equal(t, expectedSA, sa)
|
||||
|
||||
// then, there should be an error saying no valid match was found
|
||||
@@ -718,7 +745,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should be no error and should use the right service account for impersonation
|
||||
require.NoError(t, err)
|
||||
@@ -757,7 +784,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should be no error and should use the right service account for impersonation
|
||||
require.NoError(t, err)
|
||||
@@ -796,7 +823,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should be no error and it should use the first matching service account for impersonation
|
||||
require.NoError(t, err)
|
||||
@@ -830,7 +857,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should not be any error and should use the first matching glob pattern service account for impersonation
|
||||
require.NoError(t, err)
|
||||
@@ -865,7 +892,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should be an error saying no match was found
|
||||
require.EqualError(t, err, expectedErrMsg)
|
||||
@@ -893,7 +920,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should not be any error and the service account configured for with empty namespace should be used.
|
||||
require.NoError(t, err)
|
||||
@@ -927,7 +954,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should not be any error and the catch all service account should be returned
|
||||
require.NoError(t, err)
|
||||
@@ -951,7 +978,7 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there must be an error as the glob pattern is invalid.
|
||||
require.ErrorContains(t, err, "invalid glob pattern for destination namespace")
|
||||
@@ -985,7 +1012,35 @@ func TestDeriveServiceAccountMatchingNamespaces(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
assert.Equal(t, expectedSA, sa)
|
||||
|
||||
// then, there should not be any error and the service account with its namespace should be returned.
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("app destination name instead of server URL", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{
|
||||
{
|
||||
Server: "https://kubernetes.svc.local",
|
||||
Namespace: "*",
|
||||
DefaultServiceAccount: "test-sa",
|
||||
},
|
||||
}
|
||||
destinationNamespace := "testns"
|
||||
destinationServerURL := "https://kubernetes.svc.local"
|
||||
applicationNamespace := "argocd-ns"
|
||||
expectedSA := "system:serviceaccount:testns:test-sa"
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
|
||||
// Use destination name instead of server URL
|
||||
f.application.Spec.Destination.Server = ""
|
||||
f.application.Spec.Destination.Name = f.cluster.Name
|
||||
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
assert.Equal(t, expectedSA, sa)
|
||||
|
||||
// then, there should not be any error and the service account with its namespace should be returned.
|
||||
@@ -999,6 +1054,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
type fixture struct {
|
||||
project *v1alpha1.AppProject
|
||||
application *v1alpha1.Application
|
||||
cluster *v1alpha1.Cluster
|
||||
}
|
||||
|
||||
setup := func(destinationServiceAccounts []v1alpha1.ApplicationDestinationServiceAccount, destinationNamespace, destinationServerURL, applicationNamespace string) *fixture {
|
||||
@@ -1024,9 +1080,14 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
cluster := &v1alpha1.Cluster{
|
||||
Server: "https://kubernetes.svc.local",
|
||||
Name: "test-cluster",
|
||||
}
|
||||
return &fixture{
|
||||
project: project,
|
||||
application: app,
|
||||
cluster: cluster,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1062,7 +1123,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should not be any error and the right service account must be returned.
|
||||
require.NoError(t, err)
|
||||
@@ -1101,7 +1162,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should not be any error and first matching service account should be used
|
||||
require.NoError(t, err)
|
||||
@@ -1135,7 +1196,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
assert.Equal(t, expectedSA, sa)
|
||||
|
||||
// then, there should not be any error and the service account of the glob pattern, being the first match should be returned.
|
||||
@@ -1170,7 +1231,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, &v1alpha1.Cluster{Server: destinationServerURL})
|
||||
|
||||
// then, there an error with appropriate message must be returned
|
||||
require.EqualError(t, err, expectedErr)
|
||||
@@ -1204,7 +1265,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there should not be any error and the service account of the glob pattern match must be returned.
|
||||
require.NoError(t, err)
|
||||
@@ -1228,7 +1289,7 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
|
||||
// then, there must be an error as the glob pattern is invalid.
|
||||
require.ErrorContains(t, err, "invalid glob pattern for destination server")
|
||||
@@ -1262,12 +1323,40 @@ func TestDeriveServiceAccountMatchingServers(t *testing.T) {
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application)
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, &v1alpha1.Cluster{Server: destinationServerURL})
|
||||
|
||||
// then, there should not be any error and the service account with the given namespace prefix must be returned.
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expectedSA, sa)
|
||||
})
|
||||
|
||||
t.Run("app destination name instead of server URL", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
destinationServiceAccounts := []v1alpha1.ApplicationDestinationServiceAccount{
|
||||
{
|
||||
Server: "https://kubernetes.svc.local",
|
||||
Namespace: "*",
|
||||
DefaultServiceAccount: "test-sa",
|
||||
},
|
||||
}
|
||||
destinationNamespace := "testns"
|
||||
destinationServerURL := "https://kubernetes.svc.local"
|
||||
applicationNamespace := "argocd-ns"
|
||||
expectedSA := "system:serviceaccount:testns:test-sa"
|
||||
|
||||
f := setup(destinationServiceAccounts, destinationNamespace, destinationServerURL, applicationNamespace)
|
||||
|
||||
// Use destination name instead of server URL
|
||||
f.application.Spec.Destination.Server = ""
|
||||
f.application.Spec.Destination.Name = f.cluster.Name
|
||||
|
||||
// when
|
||||
sa, err := deriveServiceAccountToImpersonate(f.project, f.application, f.cluster)
|
||||
assert.Equal(t, expectedSA, sa)
|
||||
|
||||
// then, there should not be any error and the service account with its namespace should be returned.
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSyncWithImpersonate(t *testing.T) {
|
||||
@@ -1337,13 +1426,13 @@ func TestSyncWithImpersonate(t *testing.T) {
|
||||
Source: &v1alpha1.ApplicationSource{},
|
||||
},
|
||||
},
|
||||
Phase: common.OperationRunning,
|
||||
Phase: synccommon.OperationRunning,
|
||||
}
|
||||
// when
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then, app sync should fail with expected error message in operation state
|
||||
assert.Equal(t, common.OperationError, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationError, opState.Phase)
|
||||
assert.Contains(t, opState.Message, opMessage)
|
||||
})
|
||||
|
||||
@@ -1358,13 +1447,13 @@ func TestSyncWithImpersonate(t *testing.T) {
|
||||
Source: &v1alpha1.ApplicationSource{},
|
||||
},
|
||||
},
|
||||
Phase: common.OperationRunning,
|
||||
Phase: synccommon.OperationRunning,
|
||||
}
|
||||
// when
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then app sync should fail with expected error message in operation state
|
||||
assert.Equal(t, common.OperationError, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationError, opState.Phase)
|
||||
assert.Contains(t, opState.Message, opMessage)
|
||||
})
|
||||
|
||||
@@ -1379,13 +1468,13 @@ func TestSyncWithImpersonate(t *testing.T) {
|
||||
Source: &v1alpha1.ApplicationSource{},
|
||||
},
|
||||
},
|
||||
Phase: common.OperationRunning,
|
||||
Phase: synccommon.OperationRunning,
|
||||
}
|
||||
// when
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then app sync should not fail
|
||||
assert.Equal(t, common.OperationSucceeded, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationSucceeded, opState.Phase)
|
||||
assert.Contains(t, opState.Message, opMessage)
|
||||
})
|
||||
|
||||
@@ -1400,13 +1489,38 @@ func TestSyncWithImpersonate(t *testing.T) {
|
||||
Source: &v1alpha1.ApplicationSource{},
|
||||
},
|
||||
},
|
||||
Phase: common.OperationRunning,
|
||||
Phase: synccommon.OperationRunning,
|
||||
}
|
||||
// when
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then application sync should pass using the control plane service account
|
||||
assert.Equal(t, common.OperationSucceeded, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationSucceeded, opState.Phase)
|
||||
assert.Contains(t, opState.Message, opMessage)
|
||||
})
|
||||
|
||||
t.Run("app destination name instead of server URL", func(t *testing.T) {
|
||||
// given app sync impersonation feature is enabled with an application referring a project matching service account
|
||||
f := setup(true, test.FakeDestNamespace, "test-sa")
|
||||
opMessage := "successfully synced (no more tasks)"
|
||||
|
||||
opState := &v1alpha1.OperationState{
|
||||
Operation: v1alpha1.Operation{
|
||||
Sync: &v1alpha1.SyncOperation{
|
||||
Source: &v1alpha1.ApplicationSource{},
|
||||
},
|
||||
},
|
||||
Phase: synccommon.OperationRunning,
|
||||
}
|
||||
|
||||
f.application.Spec.Destination.Server = ""
|
||||
f.application.Spec.Destination.Name = "minikube"
|
||||
|
||||
// when
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then app sync should not fail
|
||||
assert.Equal(t, synccommon.OperationSucceeded, opState.Phase)
|
||||
assert.Contains(t, opState.Message, opMessage)
|
||||
})
|
||||
}
|
||||
@@ -1474,7 +1588,7 @@ func TestClientSideApplyMigration(t *testing.T) {
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then
|
||||
assert.Equal(t, common.OperationSucceeded, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationSucceeded, opState.Phase)
|
||||
assert.Contains(t, opState.Message, "successfully synced")
|
||||
})
|
||||
|
||||
@@ -1492,7 +1606,7 @@ func TestClientSideApplyMigration(t *testing.T) {
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then
|
||||
assert.Equal(t, common.OperationSucceeded, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationSucceeded, opState.Phase)
|
||||
assert.Contains(t, opState.Message, "successfully synced")
|
||||
})
|
||||
|
||||
@@ -1510,7 +1624,7 @@ func TestClientSideApplyMigration(t *testing.T) {
|
||||
f.controller.appStateManager.SyncAppState(f.application, opState)
|
||||
|
||||
// then
|
||||
assert.Equal(t, common.OperationSucceeded, opState.Phase)
|
||||
assert.Equal(t, synccommon.OperationSucceeded, opState.Phase)
|
||||
assert.Contains(t, opState.Message, "successfully synced")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,214 +0,0 @@
|
||||
# Contributors Quick-Start
|
||||
|
||||
This guide is a starting point for first-time contributors running Argo CD locally for the first time.
|
||||
|
||||
It skips advanced topics such as codegen, which are covered in the [running locally guide](running-locally.md)
|
||||
and the [toolchain guide](toolchain-guide.md).
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Before starting, ensure you have the following tools installed with the specified minimum versions:
|
||||
|
||||
* Git (v2.0.0+)
|
||||
* Go (version specified in `go.mod` - check with `go version`)
|
||||
* Docker (v20.10.0+) Or Podman (v3.0.0+)
|
||||
* Kind (v0.11.0+) Or Minikube (v1.23.0+)
|
||||
* Yarn (v1.22.0+)
|
||||
* Goreman (latest version)
|
||||
|
||||
### Fork and Clone the Repository
|
||||
|
||||
1. Fork the Argo CD repository to your personal GitHub Account
|
||||
|
||||
2. Clone the forked repository:
|
||||
```shell
|
||||
git clone https://github.com/YOUR-USERNAME/argo-cd.git
|
||||
```
|
||||
|
||||
Please note that the local build process uses GOPATH and that path should not be used, unless the Argo CD repository was directly cloned in it.
|
||||
|
||||
3. Add the upstream remote for rebasing:
|
||||
```shell
|
||||
cd argo-cd
|
||||
git remote add upstream https://github.com/argoproj/argo-cd.git
|
||||
```
|
||||
|
||||
### Install Required Tools
|
||||
|
||||
1. Install development tools:
|
||||
```shell
|
||||
make install-go-tools-local
|
||||
make install-codegen-tools-local
|
||||
```
|
||||
|
||||
### Install Go
|
||||
|
||||
<https://go.dev/doc/install/>
|
||||
|
||||
Install Go with a version equal to or greater than the version listed in `go.mod` (verify go version with `go version`).
|
||||
|
||||
|
||||
### Install Docker or Podman
|
||||
|
||||
#### Installation guide for docker:
|
||||
|
||||
<https://docs.docker.com/engine/install/>
|
||||
|
||||
#### Installation guide for podman:
|
||||
|
||||
<https://podman.io/docs/installation>
|
||||
|
||||
### Install or Upgrade a Tool for Running Local Clusters (e.g. kind or minikube)
|
||||
|
||||
#### Installation guide for kind:
|
||||
|
||||
<https://kind.sigs.k8s.io/docs/user/quick-start/>
|
||||
|
||||
#### Installation guide for minikube:
|
||||
|
||||
<https://minikube.sigs.k8s.io/docs/start/>
|
||||
|
||||
### Start Your Local Cluster
|
||||
|
||||
For example, if you are using kind:
|
||||
```shell
|
||||
kind create cluster
|
||||
```
|
||||
|
||||
Or, if you are using minikube:
|
||||
|
||||
```shell
|
||||
minikube start
|
||||
```
|
||||
|
||||
Or, if you are using minikube with podman driver:
|
||||
|
||||
```shell
|
||||
minikube start --driver=podman
|
||||
```
|
||||
|
||||
### Install Argo CD
|
||||
|
||||
```shell
|
||||
kubectl create namespace argocd &&
|
||||
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/master/manifests/install.yaml
|
||||
```
|
||||
|
||||
Set kubectl config to avoid specifying the namespace in every kubectl command.
|
||||
All following commands in this guide assume the namespace is already set.
|
||||
|
||||
```shell
|
||||
kubectl config set-context --current --namespace=argocd
|
||||
```
|
||||
|
||||
### Install `yarn`
|
||||
|
||||
<https://classic.yarnpkg.com/lang/en/docs/install/>
|
||||
|
||||
### Install `goreman`
|
||||
|
||||
<https://github.com/mattn/goreman#getting-started>
|
||||
|
||||
### Run Argo CD
|
||||
|
||||
```shell
|
||||
cd argo-cd
|
||||
make start-local ARGOCD_GPG_ENABLED=false
|
||||
```
|
||||
|
||||
By default, Argo CD uses Docker. To use Podman instead, set the `DOCKER` environment variable to `podman` before running the `make` command:
|
||||
|
||||
```shell
|
||||
cd argo-cd
|
||||
DOCKER=podman make start-local ARGOCD_GPG_ENABLED=false
|
||||
```
|
||||
|
||||
- Navigate to [localhost:4000](http://localhost:4000) in your browser to load the Argo CD UI
|
||||
- It may take a few minutes for the UI to be responsive
|
||||
|
||||
!!! note
|
||||
If the UI is not working, check the logs from `make start-local`. The logs are `DEBUG` level by default. If the logs are
|
||||
too noisy to find the problem, try editing log levels for the commands in the `Procfile` in the root of the Argo CD repo.
|
||||
|
||||
## Common Make Targets
|
||||
|
||||
Here are some frequently used make targets (all will run on your machine):
|
||||
|
||||
### Local Toolchain Make Targets
|
||||
|
||||
* `make build-local` - Build Argo CD binaries
|
||||
* `make test-local` - Run unit tests
|
||||
* `make codegen-local` - Re-generate auto generated Swagger and Protobuf (after changing API code)
|
||||
* `make lint-local` - Run linting
|
||||
* `make pre-commit-local` - Run pre-commit checks
|
||||
* `make start-e2e-local` - Start server for end-to-end tests
|
||||
* `make test-e2e-local` - Run end-to-end tests
|
||||
* `make serve-docs-local` - Serve documentation
|
||||
* `make start-local` - Start Argo CD
|
||||
|
||||
### Virtualized Toolchain Make Targets
|
||||
|
||||
* `make build` - Build Argo CD binaries
|
||||
* `make test` - Run unit tests
|
||||
* `make codegen` - Re-generate auto generated Swagger and Protobuf (after changing API code)
|
||||
* `make lint` - Run linting
|
||||
* `make pre-commit` - Run pre-commit checks
|
||||
* `make start-e2e` - Start server for end-to-end tests
|
||||
* `make test-e2e` - Run end-to-end tests
|
||||
* `make serve-docs` - Serve documentation
|
||||
* `make start` - Start Argo CD
|
||||
|
||||
## Making Changes
|
||||
|
||||
### Before Submitting a PR
|
||||
|
||||
1. Rebase your branch against upstream main:
|
||||
```shell
|
||||
git fetch upstream
|
||||
git rebase upstream/main
|
||||
```
|
||||
|
||||
2. Run pre-commit checks:
|
||||
```shell
|
||||
make pre-commit-local
|
||||
```
|
||||
|
||||
### Docs Changes
|
||||
|
||||
Modifying the docs auto-reloads the changes on the [documentation website](https://argo-cd.readthedocs.io/) that can be locally built using `make serve-docs` command.
|
||||
Once running, you can view your locally built documentation on port 8000.
|
||||
|
||||
Read more about this [here](https://argo-cd.readthedocs.io/en/latest/developer-guide/docs-site/).
|
||||
|
||||
### UI Changes
|
||||
|
||||
Modifying the User-Interface (by editing .tsx or .scss files) auto-reloads the changes on port 4000.
|
||||
|
||||
### Backend Changes
|
||||
|
||||
Modifying the API server, repo server, or a controller requires restarting the current `make start-local` session to reflect the changes.
|
||||
|
||||
### CLI Changes
|
||||
|
||||
Modifying the CLI requires restarting the current `make start-local` session to reflect the changes.
|
||||
|
||||
To test most CLI commands, you will need to log in.
|
||||
|
||||
First, get the auto-generated secret:
|
||||
|
||||
```shell
|
||||
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
|
||||
```
|
||||
|
||||
Then log in using that password and username `admin`:
|
||||
|
||||
```shell
|
||||
dist/argocd login localhost:8080
|
||||
```
|
||||
|
||||
---
|
||||
Congrats on making it to the end of this runbook! 🚀
|
||||
|
||||
For more on Argo CD, find us in Slack - <https://slack.cncf.io/> [#argo-contributors](https://cloud-native.slack.com/archives/C020XM04CUW)
|
||||
146
docs/developer-guide/debugging-locally.md
Normal file
146
docs/developer-guide/debugging-locally.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# Debugging a local Argo CD instance
|
||||
|
||||
## Prerequisites
|
||||
1. [Development Environment](development-environment.md)
|
||||
2. [Toolchain Guide](toolchain-guide.md)
|
||||
3. [Development Cycle](development-cycle.md)
|
||||
4. [Running Locally](running-locally.md)
|
||||
|
||||
## Preface
|
||||
Please make sure you are familiar with running Argo CD locally using the [local toolchain](running-locally.md#start-local-services-local-toolchain).
|
||||
|
||||
When running Argo CD locally for manual tests, the quickest way to do so is to run all the Argo CD components together, as described in [Running Locally](running-locally.md),
|
||||
|
||||
However, when you need to debug a single Argo CD component (for example, `api-server`, `repo-server`, etc), you will need to run this component separately in your IDE, using your IDE launch and debug configuration, while the other components will be running as described previously, using the local toolchain.
|
||||
|
||||
For the next steps, we will use Argo CD `api-server` as an example of running a component in an IDE.
|
||||
|
||||
## Configure your IDE
|
||||
|
||||
### Locate your component configuration in `Procfile`
|
||||
The `Procfile` is used by Goreman when running Argo CD locally with the local toolchain. The file is located in the top-level directory in your cloned Argo CD repo folder, you can view it's latest version [here](https://github.com/argoproj/argo-cd/blob/master/Procfile). It contains all the needed component run configuration, and you will need to copy parts of this configuration to your IDE.
|
||||
|
||||
Example for `api-server` configuration in `Procfile`:
|
||||
``` text
|
||||
api-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "GOCOVERDIR=${ARGOCD_COVERAGE_DIR:-/tmp/coverage/api-server} FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-server $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} --hydrator-enabled=${ARGOCD_HYDRATOR_ENABLED:='false'}"
|
||||
```
|
||||
This configuration example will be used as the basis for the next steps.
|
||||
|
||||
!!! note
|
||||
The Procfile for a component may change with time. Please go through the Procfile and make sure you use the latest configuration for debugging.
|
||||
|
||||
### Configure component env variables
|
||||
The component that you will run in your IDE for debugging (`api-server` in our case) will need env variables. Copy the env variables from `Procfile`, located in the `argo-cd` root folder of your development branch. The env variables are located before the `$COMMAND` section in the `sh -c` section of the component run command.
|
||||
You can keep them in `.env` file and then have the IDE launch configuration point to that file. Obviously, you can adjust the env variables to your needs when debugging a specific configuration.
|
||||
|
||||
Example for an `api-server.env` file:
|
||||
``` bash
|
||||
ARGOCD_BINARY_NAME=argocd-server
|
||||
ARGOCD_FAKE_IN_CLUSTER=true
|
||||
ARGOCD_GNUPGHOME=/tmp/argocd-local/gpg/keys
|
||||
ARGOCD_GPG_DATA_PATH=/tmp/argocd-local/gpg/source
|
||||
ARGOCD_GPG_ENABLED=false
|
||||
ARGOCD_LOG_FORMAT_ENABLE_FULL_TIMESTAMP=1
|
||||
ARGOCD_SSH_DATA_PATH=/tmp/argocd-local/ssh
|
||||
ARGOCD_TLS_DATA_PATH=/tmp/argocd-local/tls
|
||||
ARGOCD_TRACING_ENABLED=1
|
||||
FORCE_LOG_COLORS=1
|
||||
KUBECONFIG=/Users/<YOUR_USERNAME>/.kube/config # Must be an absolute full path
|
||||
...
|
||||
# and so on, for example: when you test the app-in-any-namespace feature,
|
||||
# you'll need to add ARGOCD_APPLICATION_NAMESPACES to this list
|
||||
# only for testing this functionality and remove it afterwards.
|
||||
```
|
||||
|
||||
### Install DotENV / EnvFile plugin
|
||||
Using the market place / plugin manager of your IDE. The below example configurations require the plugin to be installed.
|
||||
|
||||
|
||||
### Configure component IDE launch configuration
|
||||
#### VSCode example
|
||||
Next, you will need to create a launch configuration, with the relevant args. Copy the args from `Procfile`, located in the `argo-cd` root folder of your development branch. The args are located after the `$COMMAND` section in the `sh -c` section of the component run command.
|
||||
Example for an `api-server` launch configuration, based on our above example for `api-server` configuration in `Procfile`:
|
||||
``` json
|
||||
{
|
||||
"name": "api-server",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "YOUR_CLONED_ARGO_CD_REPO_PATH/argo-cd/cmd",
|
||||
"args": [
|
||||
"--loglevel",
|
||||
"debug",
|
||||
"--redis",
|
||||
"localhost:6379",
|
||||
"--repo-server",
|
||||
"localhost:8081",
|
||||
"--dex-server",
|
||||
"http://localhost:5556",
|
||||
"--port",
|
||||
"8080",
|
||||
"--insecure"
|
||||
],
|
||||
"envFile": "YOUR_ENV_FILES_PATH/api-server.env", # Assuming you installed DotENV plugin
|
||||
}
|
||||
```
|
||||
|
||||
#### Goland example
|
||||
Next, you will need to create a launch configuration, with the relevant parameters. Copy the parameters from `Procfile`, located in the `argo-cd` root folder of your development branch. The parameters are located after the `$COMMAND` section in the `sh -c` section of the component run command.
|
||||
Example for an `api-server` launch configuration snippet, based on our above example for `api-server` configuration in `Procfile`:
|
||||
``` xml
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="api-server" type="GoApplicationRunConfiguration" factoryName="Go Application">
|
||||
<module name="argo-cd" />
|
||||
<working_directory value="$PROJECT_DIR$" />
|
||||
<parameters value="--loglevel debug --redis localhost:6379 --insecure --dex-server http://localhost:5556 --repo-server localhost:8081 --port 8080" />
|
||||
<EXTENSION ID="net.ashald.envfile"> <!-- Assuming you installed the EnvFile plugin-->
|
||||
<option name="IS_ENABLED" value="true" />
|
||||
<option name="IS_SUBST" value="false" />
|
||||
<option name="IS_PATH_MACRO_SUPPORTED" value="false" />
|
||||
<option name="IS_IGNORE_MISSING_FILES" value="false" />
|
||||
<option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
|
||||
<ENTRIES>
|
||||
<ENTRY IS_ENABLED="true" PARSER="runconfig" IS_EXECUTABLE="false" />
|
||||
<ENTRY IS_ENABLED="true" PARSER="env" IS_EXECUTABLE="false" PATH="<YOUR_ENV_FILES_PATH>/api-server.env" />
|
||||
</ENTRIES>
|
||||
</EXTENSION>
|
||||
<kind value="DIRECTORY" />
|
||||
<directory value="$PROJECT_DIR$/cmd" />
|
||||
<filePath value="$PROJECT_DIR$" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
```
|
||||
|
||||
!!! note
|
||||
As an alternative to importing the above file to Goland, you can create a Run/Debug Configuration using the official [Goland docs](https://www.jetbrains.com/help/go/go-build.html) and just copy the `parameters`, `directory` and `PATH` sections from the example above (specifying `Run kind` as `Directory` in the Run/Debug Configurations wizard)
|
||||
|
||||
## Run Argo CD without the debugged component
|
||||
Next, we need to run all Argo CD components, except for the debugged component (cause we will run this component separately in the IDE).
|
||||
There is a mix-and-match approach to running the other components - you can run them in your K8s cluster or locally with the local toolchain.
|
||||
Below are the different options.
|
||||
|
||||
### Run the other components locally
|
||||
#### Run with "make start-local"
|
||||
`make start-local` runs all the components by default, but it is also possible to run it with a whitelist of components, enabling the separation we need.
|
||||
|
||||
So for the case of debugging the `api-server`, run:
|
||||
`make start-local ARGOCD_START="notification applicationset-controller repo-server redis dex controller ui"`
|
||||
|
||||
#### Run with "make run"
|
||||
`make run` runs all the components by default, but it is also possible to run it with a blacklist of components, enabling the separation we need.
|
||||
|
||||
So for the case of debugging the `api-server`, run:
|
||||
`make run exclude=api-server`
|
||||
|
||||
#### Run with "goreman start"
|
||||
`goreman start` runs all the components by default, but it is also possible to run it with a whitelist of components, enabling separation as needed.
|
||||
|
||||
To debug the `api-server`, run:
|
||||
`goreman start notification applicationset-controller repo-server redis dex controller ui`
|
||||
|
||||
## Run Argo CD debugged component from your IDE
|
||||
Finally, run the component you wish to debug from your IDE and make sure it does not have any errors.
|
||||
|
||||
## Important
|
||||
When running Argo CD components separately, ensure components aren't creating conflicts - each component needs to be up exactly once, be it running locally with the local toolchain or running from your IDE. Otherwise you may get errors about ports not available or even debugging a process that does not contain your code changes.
|
||||
@@ -33,21 +33,61 @@ After your GitOps Engine PR has been merged, ArgoCD needs to be updated to pull
|
||||
- See https://github.com/argoproj/argo-cd/pull/4434 as an example
|
||||
- The PR might require additional, dependent changes in ArgoCD that are directly impacted by the changes made in the engine.
|
||||
|
||||
## Argo UI Components
|
||||
## Notifications Engine (`github.com/argoproj/notifications-engine`)
|
||||
|
||||
### Repository
|
||||
|
||||
https://github.com/argoproj/argo-ui
|
||||
[notifications-engine](https://github.com/argoproj/notifications-engine)
|
||||
|
||||
### Pulling changes from Argo UI into Argo CD
|
||||
### Pulling changes from `notifications-engine`
|
||||
|
||||
If you make changes to the Argo UI component, and your Argo CD changes depend on those changes, follow these steps:
|
||||
After your Notifications Engine PR has been merged, ArgoCD needs to be updated to pull in the version of the notifications engine that contains your change. Here are the steps:
|
||||
|
||||
1. Make changes to Argo UI and submit the PR request.
|
||||
2. Also, prepare your Argo CD changes, but don't create the PR just yet.
|
||||
3. **After** the Argo UI PR has been merged to master, then as part of your Argo CD changes:
|
||||
- Run `yarn add git+https://github.com/argoproj/argo-ui.git` in the `ui/` directory, and then,
|
||||
- Check in the regenerated `yarn.lock` file as part of your Argo CD commit
|
||||
4. Create the Argo CD PR when you are ready. The PR build and test checks should pass.
|
||||
- Retrieve the SHA hash for your commit. You will use this in the next step.
|
||||
- From the `argo-cd` folder, run the following command
|
||||
|
||||
If your Argo UI change is a 'stand-alone' fix, and you simply want Argo CD to pull in your change, then simply create an Argo CD PR with the `yarn.lock` file change.
|
||||
`go get github.com/argoproj/notifications-engine@<git-commit-sha>`
|
||||
|
||||
If you get an error message `invalid version: unknown revision` then you got the wrong SHA hash
|
||||
|
||||
- Run:
|
||||
|
||||
`go mod tidy`
|
||||
|
||||
- The following files are changed:
|
||||
|
||||
- `go.mod`
|
||||
- `go.sum`
|
||||
|
||||
- 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.
|
||||
|
||||
## Argo UI Components (`github.com/argoproj/argo-ui`)
|
||||
### Contributing to Argo CD UI
|
||||
|
||||
Argo CD, along with Argo Workflows, uses shared React components from [Argo UI](https://github.com/argoproj/argo-ui). Examples of some of these components include buttons, containers, form controls,
|
||||
and others. Although you can make changes to these files and run them locally, in order to have these changes added to the Argo CD repo, you will need to follow these steps.
|
||||
|
||||
1. Fork and clone the [Argo UI repository](https://github.com/argoproj/argo-ui).
|
||||
|
||||
2. `cd` into your `argo-ui` directory, and then run `yarn install`.
|
||||
|
||||
3. Make your file changes.
|
||||
|
||||
4. Run `yarn start` to start a [storybook](https://storybook.js.org/) dev server and view the components in your browser. Make sure all your changes work as expected.
|
||||
|
||||
5. Use [yarn link](https://classic.yarnpkg.com/en/docs/cli/link/) to link Argo UI package to your Argo CD repository. (Commands below assume that `argo-ui` and `argo-cd` are both located within the same parent folder)
|
||||
|
||||
* `cd argo-ui`
|
||||
* `yarn link`
|
||||
* `cd ../argo-cd/ui`
|
||||
* `yarn link argo-ui`
|
||||
|
||||
Once the `argo-ui` package has been successfully linked, test changes in your local development environment.
|
||||
|
||||
6. Commit changes and open a PR to [Argo UI](https://github.com/argoproj/argo-ui).
|
||||
|
||||
7. Once your PR has been merged in Argo UI, `cd` into your `argo-cd/ui` folder and run `yarn add git+https://github.com/argoproj/argo-ui.git`. This will update the commit SHA in the `ui/yarn.lock` file to use the latest master commit for argo-ui.
|
||||
|
||||
8. Submit changes to `ui/yarn.lock`in a PR to Argo CD.
|
||||
|
||||
119
docs/developer-guide/development-cycle.md
Normal file
119
docs/developer-guide/development-cycle.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# The Development Cycle
|
||||
|
||||
## Prerequisites
|
||||
1. [Development Environment](development-environment.md)
|
||||
2. [Toolchain Guide](toolchain-guide.md)
|
||||
|
||||
## Preface
|
||||
When you have developed and possibly manually tested the code you want to contribute, you should ensure that everything builds correctly. Commit your changes locally and perform the following steps, for each step the commands for both local and virtualized toolchain are listed.
|
||||
|
||||
### Docker priviliges for virtualized toolchain users
|
||||
[These instructions](toolchain-guide.md#docker-privileges) are relevant for most of the steps below
|
||||
|
||||
### Using Podman for virtualized toolchain users
|
||||
[These instructions](toolchain-guide.md#using-podman) are relevant for most of the steps below
|
||||
|
||||
## Development cycle steps
|
||||
### Set kubectl context to argocd namespace
|
||||
|
||||
Setting kubectl config to the argocd namespace is required for these steps to succeed.
|
||||
All following commands in this guide assume the namespace is already set.
|
||||
|
||||
```shell
|
||||
kubectl config set-context --current --namespace=argocd
|
||||
```
|
||||
|
||||
### Pull in all build dependencies
|
||||
|
||||
As build dependencies change over time, you have to synchronize your development environment with the current specification. In order to pull in all required dependencies, issue:
|
||||
|
||||
* `make dep-ui` or `make dep-ui-local`
|
||||
|
||||
Argo CD recently migrated to Go modules. Usually, dependencies will be downloaded at build time, but the Makefile provides two targets to download and vendor all dependencies:
|
||||
|
||||
* `make mod-download` or `make mod-download-local` will download all required Go modules and
|
||||
* `make mod-vendor` or `make mod-vendor-local` will vendor those dependencies into the Argo CD source tree
|
||||
|
||||
### Generate API glue code and other assets
|
||||
|
||||
Argo CD relies on Google's [Protocol Buffers](https://developers.google.com/protocol-buffers) for its API, and this makes heavy use of auto-generated glue code and stubs. Whenever you touched parts of the API code, you must re-generate the auto generated code.
|
||||
|
||||
* Run `make codegen` or `make codegen-local`, this might take a while
|
||||
* Check if something has changed by running `git status` or `git diff`
|
||||
* Commit any possible changes to your local Git branch, an appropriate commit message would be `Changes from codegen`, for example.
|
||||
|
||||
!!!note
|
||||
There are a few non-obvious assets that are auto-generated. You should not change the autogenerated assets, as they will be overwritten by a subsequent run of `make codegen`. Instead, change their source files. Prominent examples of non-obvious auto-generated code are `swagger.json` or the installation manifest YAMLs.
|
||||
|
||||
### Build your code and run unit tests
|
||||
|
||||
After the code glue has been generated, your code should build and the unit tests should run without any errors. Execute the following statements:
|
||||
|
||||
* `make build` or `make build-local`
|
||||
* `make test` or `make test-local`
|
||||
|
||||
These steps are non-modifying, so there's no need to check for changes afterward.
|
||||
|
||||
### Lint your code base
|
||||
|
||||
In order to keep a consistent code style in our source tree, your code must be well-formed in accordance to some widely accepted rules, which are applied by a Linter.
|
||||
|
||||
The Linter might make some automatic changes to your code, such as indentation fixes. Some other errors reported by the Linter have to be fixed manually.
|
||||
|
||||
* Run `make lint` or `make lint-local` and observe any errors reported by the Linter
|
||||
* Fix any of the errors reported and commit to your local branch
|
||||
* Finally, after the Linter reports no errors, run `git status` or `git diff` to check for any changes made automatically by Lint
|
||||
* If there were automatic changes, commit them to your local branch
|
||||
|
||||
If you touched UI code, you should also run the Yarn linter on it:
|
||||
|
||||
* Run `make lint-ui` or `make lint-ui-local`
|
||||
* Fix any of the errors reported by it
|
||||
|
||||
### Run end-to-end tests
|
||||
|
||||
The final step is running the End-to-End testsuite, which ensures that your Kubernetes dependencies are working properly. This will involve starting all the Argo CD components on your computer. The end-to-end tests consists of two parts: a server component, and a client component.
|
||||
|
||||
* First, start the End-to-End server: `make start-e2e` or `make start-e2e-local`. This will spawn a number of processes and services on your system.
|
||||
* When all components have started, run `make test-e2e` or `make test-e2e-local` to run the end-to-end tests against your local services.
|
||||
|
||||
To run a single test with a local toolchain, you can use `TEST_FLAGS="-run TestName" make test-e2e-local`.
|
||||
|
||||
For more information about End-to-End tests, refer to the [End-to-End test documentation](test-e2e.md).
|
||||
|
||||
## Common Make Targets
|
||||
|
||||
Here are some frequently used make targets (all will run on your machine):
|
||||
|
||||
### Local Toolchain Make Targets
|
||||
|
||||
* `make install-tools-local` - Install testing and building tools for the local toolchain
|
||||
* `make build-local` - Build Argo CD binaries
|
||||
* `make test-local` - Run unit tests
|
||||
* `make codegen-local` - Re-generate auto generated Swagger and Protobuf (after changing API code)
|
||||
* `make lint-local` - Run linting
|
||||
* `make pre-commit-local` - Run pre-commit checks
|
||||
* `make start-e2e-local` - Start server for end-to-end tests
|
||||
* `make test-e2e-local` - Run end-to-end tests
|
||||
* `make serve-docs-local` - Serve documentation
|
||||
* `make start-local` - Start Argo CD
|
||||
* `make cli-local` - Build Argo CD CLI binary
|
||||
|
||||
### Virtualized Toolchain Make Targets
|
||||
|
||||
* `make verify-kube-connect` - Test whether the virtualized toolchain has access to your K8s cluster
|
||||
* `make test-tools-image` - Prepare the environment of the virtualized chain
|
||||
* `make build` - Build Argo CD binaries
|
||||
* `make test` - Run unit tests
|
||||
* `make codegen` - Re-generate auto generated Swagger and Protobuf (after changing API code)
|
||||
* `make lint` - Run linting
|
||||
* `make pre-commit` - Run pre-commit checks
|
||||
* `make start-e2e` - Start server for end-to-end tests
|
||||
* `make test-e2e` - Run end-to-end tests
|
||||
* `make serve-docs` - Serve documentation
|
||||
* `make start` - Start Argo CD
|
||||
|
||||
---
|
||||
Congrats on making it to the end of this runbook! 🚀
|
||||
|
||||
For more on Argo CD, find us in Slack - <https://slack.cncf.io/> [#argo-contributors](https://cloud-native.slack.com/archives/C020XM04CUW)
|
||||
120
docs/developer-guide/development-environment.md
Normal file
120
docs/developer-guide/development-environment.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Setting Up the Development Environment
|
||||
|
||||
## Required Tools Overview
|
||||
|
||||
You will need to install the following tools with the specified minimum versions:
|
||||
|
||||
* Git (v2.0.0+)
|
||||
* Go (version specified in `go.mod` - check with `go version`)
|
||||
* Docker (v20.10.0+) Or Podman (v3.0.0+)
|
||||
* Kind (v0.11.0+) Or Minikube (v1.23.0+) Or K3d (v5.7.3+)
|
||||
|
||||
|
||||
|
||||
## Install Required Tools
|
||||
|
||||
### Install Git
|
||||
|
||||
Obviously, you will need a `git` client for pulling source code and pushing back your changes.
|
||||
|
||||
<https://github.com/git-guides/install-git>
|
||||
|
||||
|
||||
### Install Go
|
||||
|
||||
You will need a Go SDK and related tools (such as GNU `make`) installed and working on your development environment.
|
||||
|
||||
<https://go.dev/doc/install/>
|
||||
|
||||
Install Go with a version equal to or greater than the version listed in `go.mod` (verify go version with `go version`).
|
||||
We will assume that your Go workspace is at `~/go`.
|
||||
|
||||
Verify: run `go version`
|
||||
|
||||
### Install Docker or Podman
|
||||
|
||||
#### Installation guide for docker
|
||||
|
||||
<https://docs.docker.com/engine/install/>
|
||||
|
||||
You will need a working Docker runtime environment, to be able to build and run images. Argo CD is using multi-stage builds.
|
||||
|
||||
Verify: run `docker version`
|
||||
|
||||
#### Installation guide for podman
|
||||
|
||||
<https://podman.io/docs/installation>
|
||||
|
||||
### Install a Local K8s Cluster
|
||||
|
||||
You won't need a fully blown multi-master, multi-node cluster, but you will need something like K3S, K3d, Minikube, Kind or microk8s. You will also need a working Kubernetes client (`kubectl`) configuration in your development environment. The configuration must reside in `~/.kube/config`.
|
||||
|
||||
#### Kind
|
||||
|
||||
##### [Installation guide](https://kind.sigs.k8s.io/docs/user/quick-start)
|
||||
|
||||
You can use `kind` to run Kubernetes inside Docker. But pointing to any other development cluster works fine as well as long as Argo CD can reach it.
|
||||
|
||||
##### Start the Cluster
|
||||
```shell
|
||||
kind create cluster
|
||||
```
|
||||
|
||||
#### Minikube
|
||||
|
||||
##### [Installation guide](https://minikube.sigs.k8s.io/docs/start)
|
||||
|
||||
##### Start the Cluster
|
||||
```shell
|
||||
minikube start
|
||||
```
|
||||
|
||||
Or, if you are using minikube with podman driver:
|
||||
|
||||
```shell
|
||||
minikube start --driver=podman
|
||||
```
|
||||
|
||||
#### K3d
|
||||
|
||||
##### [Installation guide](https://k3d.io/stable/#quick-start)
|
||||
|
||||
### Verify cluster installation
|
||||
|
||||
* Run `kubectl version`
|
||||
|
||||
## Fork and Clone the Repository
|
||||
1. Fork the Argo CD repository to your personal GitHub Account
|
||||
2. Clone the forked repository:
|
||||
```shell
|
||||
git clone https://github.com/YOUR-USERNAME/argo-cd.git
|
||||
```
|
||||
Please note that the local build process uses GOPATH and that path should not be used, unless the Argo CD repository was directly cloned in it.
|
||||
|
||||
3. While everyone has their own Git workflow, the author of this document recommends to create a remote called `upstream` in your local copy pointing to the original Argo CD repository. This way, you can easily keep your local branches up-to-date by merging in latest changes from the Argo CD repository, i.e. by doing a `git pull upstream master` in your locally checked out branch.
|
||||
To create the remote, run:
|
||||
```shell
|
||||
cd argo-cd
|
||||
git remote add upstream https://github.com/argoproj/argo-cd.git
|
||||
```
|
||||
|
||||
## Install Additional Required Development Tools
|
||||
|
||||
```shell
|
||||
make install-go-tools-local
|
||||
make install-codegen-tools-local
|
||||
```
|
||||
|
||||
## Install Latest Argo CD on Your Local Cluster
|
||||
|
||||
```shell
|
||||
kubectl create namespace argocd &&
|
||||
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/master/manifests/install.yaml
|
||||
```
|
||||
|
||||
Set kubectl config to avoid specifying the namespace in every kubectl command.
|
||||
|
||||
```shell
|
||||
kubectl config set-context --current --namespace=argocd
|
||||
```
|
||||
|
||||
@@ -1,25 +1,102 @@
|
||||
# Overview
|
||||
|
||||
!!! warning "You probably don't want to be reading this section of the docs."
|
||||
This part of the manual is aimed at helping people contribute to Argo CD, the documentation, or to develop third-party applications that interact with Argo CD, e.g.
|
||||
!!! warning "As an Argo CD user, you probably don't want to be reading this section of the docs."
|
||||
This part of the manual is aimed at helping people contribute to Argo CD, documentation, or to develop third-party applications that interact with Argo CD, e.g.
|
||||
|
||||
* A chat bot
|
||||
* A Slack integration
|
||||
|
||||
|
||||
## Contributing to Argo CD
|
||||
* [Code Contribution Guide](code-contributions/)
|
||||
* [Contributors Quickstart](contributors-quickstart/)
|
||||
* [Running Argo CD Locally](running-locally/)
|
||||
## Preface
|
||||
#### Understand the [Code Contribution Guide](code-contributions.md)
|
||||
#### Understand the [Code Contribution Preface](submit-your-pr.md#preface)
|
||||
|
||||
## Contributing to Argo CD documentation
|
||||
|
||||
This guide will help you get started quickly with contributing documentation changes, performing the minimum setup you'll need.
|
||||
For backend and frontend contributions, that require a full building-testing-running-locally cycle, please refer to [Contributing to Argo CD backend and frontend ](index.md#contributing-to-argo-cd-backend-and-frontend)
|
||||
|
||||
### Fork and clone Argo CD repository
|
||||
- [Fork and clone Argo CD repository](development-environment.md#fork-and-clone-the-repository)
|
||||
|
||||
### Submit your PR
|
||||
- [Before submitting a PR](submit-your-pr.md#before-submitting-a-pr)
|
||||
- [Choose a correct title for your PR](submit-your-pr.md#choose-a-correct-title-for-your-pr)
|
||||
- [Perform the PR template checklist](submit-your-pr.md#perform-the-PR-template-checklist)
|
||||
|
||||
## Contributing to Argo CD Notifications documentation
|
||||
|
||||
This guide will help you get started quickly with contributing documentation changes, performing the minimum setup you'll need.
|
||||
The notificaions docs are located in [notifications-engine](https://github.com/argoproj/notifications-engine) Git repository and require 2 pull requests: one for the `notifications-engine` repo and one for the `argo-cd` repo.
|
||||
For backend and frontend contributions, that require a full building-testing-running-locally cycle, please refer to [Contributing to Argo CD backend and frontend ](index.md#contributing-to-argo-cd-backend-and-frontend)
|
||||
|
||||
### Fork and clone Argo CD repository
|
||||
- [Fork and clone Argo CD repository](development-environment.md#fork-and-clone-the-repository)
|
||||
|
||||
### Submit your PR to notifications-engine
|
||||
- [Before submitting a PR](submit-your-pr.md#before-submitting-a-pr)
|
||||
- [Choose a correct title for your PR](submit-your-pr.md#choose-a-correct-title-for-your-pr)
|
||||
- [Perform the PR template checklist](submit-your-pr.md#perform-the-PR-template-checklist)
|
||||
|
||||
### Install Go on your machine
|
||||
- [Install Go](development-environment.md#install-go)
|
||||
|
||||
### Submit your PR to argo-cd
|
||||
- [Contributing to notifications-engine](dependencies.md#notifications-engine-githubcomargoprojnotifications-engine)
|
||||
- [Before submitting a PR](submit-your-pr.md#before-submitting-a-pr)
|
||||
- [Choose a correct title for your PR](submit-your-pr.md#choose-a-correct-title-for-your-pr)
|
||||
- [Perform the PR template checklist](submit-your-pr.md#perform-the-PR-template-checklist)
|
||||
|
||||
## Contributing to Argo CD backend and frontend
|
||||
|
||||
This guide will help you set up your build & test environment, so that you can start developing and testing bug fixes and feature enhancements without having to make too much effort in setting up a local toolchain.
|
||||
|
||||
As is the case with the development process, this document is under constant change. If you notice any error, or if you think this document is out-of-date, or if you think it is missing something: Feel free to submit a PR or submit a bug to our GitHub issue tracker.
|
||||
|
||||
### Set up your development environment
|
||||
- [Install required tools (Git, Go, Docker, etc)](development-environment.md#install-required-tools)
|
||||
- [Install and start a local K8s cluster (Kind, Minikube or K3d)](development-environment.md#install-a-local-k8s-cluster)
|
||||
- [Fork and clone Argo CD repository](development-environment.md#fork-and-clone-the-repository)
|
||||
- [Install additional required development tools](development-environment.md#install-additional-required-development-tools)
|
||||
- [Install latest Argo CD on your local cluster](development-environment.md#install-latest-argo-cd-on-your-local-cluster)
|
||||
|
||||
### Set up a development toolchain (local or virtualized)
|
||||
- [Understand the differences between the toolchains](toolchain-guide.md#local-vs-virtualized-toolchain)
|
||||
- Choose a development toolchain
|
||||
|
||||
- Either [set up a local toolchain](toolchain-guide.md#setting-up-a-local-toolchain)
|
||||
- Or [set up a virtualized toolchain](toolchain-guide.md#setting-up-a-virtualized-toolchain)
|
||||
|
||||
### Perform the development cycle
|
||||
- [Set kubectl context to argocd namespace](development-cycle.md#set-kubectl-context-to-argocd-namespace)
|
||||
- [Pull in all build dependencies](development-cycle.md#pull-in-all-build-dependencies)
|
||||
- [Generate API glue code and other assets](development-cycle.md#generate-API-glue-code-and-other-assets)
|
||||
- [Build your code and run unit tests](development-cycle.md#build-your-code-and-run-unit-tests)
|
||||
- [Lint your code base](development-cycle.md#lint-your-code-base)
|
||||
- [Run e2e tests](development-cycle.md#run-end-to-end-tests)
|
||||
- How to contribute to documentation: [build and run documentation site](docs-site/) on your machine for manual testing
|
||||
|
||||
### Run and debug Argo CD locally
|
||||
- [Run Argo CD on your machine for manual testing](running-locally.md)
|
||||
- [Debug Argo CD in an IDE on your machine](debugging-locally.md)
|
||||
|
||||
### Submit your PR
|
||||
- [Before submitting a PR](submit-your-pr.md#before-submitting-a-pr)
|
||||
- [Understand the Continuous Integration process](submit-your-pr.md#understand-the-continuous-integration-process)
|
||||
- [Choose a correct title for your PR](submit-your-pr.md#choose-a-correct-title-for-your-pr)
|
||||
- [Perform the PR template checklist](submit-your-pr.md#perform-the-PR-template-checklist)
|
||||
- [Understand the CI automated builds & tests](submit-your-pr.md#automated-builds-&-tests)
|
||||
- [Understand & make sure your PR meets the CI code test coverage requirements](submit-your-pr.md#code-test-coverage)
|
||||
|
||||
Need help? Start with the [Contributors FAQ](faq/)
|
||||
|
||||
## Contributing to the Documentation
|
||||
* [Building and Running Documentation Site Locally](docs-site/)
|
||||
## Contributing to Argo CD dependencies
|
||||
- [Contributing to argo-ui](dependencies.md#argo-ui-components-githubcomargoprojargo-ui)
|
||||
- [Contributing to gitops-engine](dependencies.md#gitops-engine-githubcomargoprojgitops-engine)
|
||||
- [Contributing to notifications-engine](dependencies.md#notifications-engine-githubcomargoprojnotifications-engine)
|
||||
|
||||
## Extensions and Third-Party Applications
|
||||
* [UI Extensions](ui-extensions/)
|
||||
* [Proxy Extensions](proxy-extensions/)
|
||||
* [UI Extensions](extensions/ui-extensions.md)
|
||||
* [Proxy Extensions](extensions/proxy-extensions.md)
|
||||
* [Config Management Plugins](../operator-manual/config-management-plugins/)
|
||||
|
||||
## Contributing to Argo Website
|
||||
|
||||
20
docs/developer-guide/mac-users.md
Normal file
20
docs/developer-guide/mac-users.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# MacOS users
|
||||
Below are known issues specific to macOS
|
||||
|
||||
## Port 5000
|
||||
|
||||
You may get an error listening on port 5000 on macOS:
|
||||
|
||||
```text
|
||||
docker: Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:5000 -> 0.0.0.0:0: listen tcp 0.0.0.0:5000: bind: address already in use.
|
||||
```
|
||||
|
||||
In that case, you can disable "AirPlay Receiver" in macOS System Preferences.
|
||||
|
||||
## Firewall dialogs
|
||||
If you get firewall dialogs, you can click "Deny", since no access from outside your computer is typically desired.
|
||||
|
||||
## Exec format error for virtualized toolchain make targets
|
||||
If you get `/go/src/github.com/argoproj/argo-cd/dist/mockery: cannot execute binary file: Exec format error`, this typically means that you ran a virtualized `make` target after you ran the a local `make` target.
|
||||
To fix this and continue with the virtualized toolchain, delete the contents of `argo-cd/dist` folder.
|
||||
If later on you wish to run `make` targets of the local toolchain again, run `make install-tools-local` to re-populate the contents of the `argo-cd/dist` folder.
|
||||
@@ -1,14 +1,21 @@
|
||||
# Running Argo CD locally
|
||||
|
||||
## Run Argo CD outside of Kubernetes
|
||||
## Prerequisites
|
||||
1. [Development Environment](development-environment.md)
|
||||
2. [Toolchain Guide](toolchain-guide.md)
|
||||
3. [Development Cycle](development-cycle.md)
|
||||
|
||||
During development, it might be viable to run Argo CD outside a Kubernetes cluster. This will greatly speed up development, as you don't have to constantly build, push and install new Argo CD Docker images with your latest changes.
|
||||
## Preface
|
||||
During development, it is recommended to start with Argo CD running locally (outside of a K8s cluster). This will greatly speed up development, as you don't have to constantly build, push and install new Argo CD Docker images with your latest changes.
|
||||
|
||||
You will still need a working Kubernetes cluster, as described in the [Toolchain Guide](toolchain-guide.md), where Argo CD will store all of its resources and configuration.
|
||||
After you have tested locally, you can move to the second phase of building a docker image, running Argo CD in your cluster and testing further.
|
||||
|
||||
If you followed the [Toolchain Guide](toolchain-guide.md) in setting up your toolchain, you can run Argo CD locally with these simple steps:
|
||||
For both cases, you will need a working K8s cluster, where Argo CD will store all of its resources and configuration.
|
||||
|
||||
### Install Argo CD resources to your cluster
|
||||
In order to have all the required resources in your cluster, you will deploy Argo CD from your development branch and then scale down all it's instances.
|
||||
This will ensure you have all the relevant configuration (such as Argo CD Config Maps and CRDs) in the cluster while the instances themselves are stopped.
|
||||
|
||||
### Deploy Argo CD resources to your cluster
|
||||
|
||||
First push the installation manifest into argocd namespace:
|
||||
|
||||
@@ -17,6 +24,12 @@ kubectl create namespace argocd
|
||||
kubectl apply -n argocd --force -f manifests/install.yaml
|
||||
```
|
||||
|
||||
The services you will start later assume you are running in the namespace where Argo CD is installed. You can set the current context default namespace as follows:
|
||||
|
||||
```bash
|
||||
kubectl config set-context --current --namespace=argocd
|
||||
```
|
||||
|
||||
### Scale down any Argo CD instance in your cluster
|
||||
|
||||
Make sure that Argo CD is not running in your development cluster by scaling down the deployments:
|
||||
@@ -31,34 +44,32 @@ kubectl -n argocd scale deployment/argocd-applicationset-controller --replicas 0
|
||||
kubectl -n argocd scale deployment/argocd-notifications-controller --replicas 0
|
||||
```
|
||||
|
||||
### Start local services (virtualized toolchain inside Docker)
|
||||
|
||||
The started services assume you are running in the namespace where Argo CD is installed. You can set the current context default namespace as follows:
|
||||
|
||||
```bash
|
||||
kubectl config set-context --current --namespace=argocd
|
||||
```
|
||||
## Running Argo CD locally, outside of K8s cluster
|
||||
#### Prerequisites
|
||||
1. [Deploy Argo CD resources to your cluster](running-locally.md#deploy-argo-cd-resources-to-your-cluster)
|
||||
2. [Scale down any Argo CD instance in your cluster](running-locally.md#scale-down-any-argo-cd-instance-in-your-cluster)
|
||||
|
||||
### Start local services (virtualized toolchain)
|
||||
When you use the virtualized toolchain, starting local services is as simple as running
|
||||
|
||||
```bash
|
||||
cd argo-cd
|
||||
make start
|
||||
```
|
||||
|
||||
By default, Argo CD uses Docker. To use Podman instead, set the `DOCKER` environment variable to `podman` before running the `make` command:
|
||||
|
||||
```shell
|
||||
cd argo-cd
|
||||
DOCKER=podman make start
|
||||
```
|
||||
|
||||
This will start all Argo CD services and the UI in a Docker container and expose the following ports to your host:
|
||||
|
||||
* The Argo CD API server on port 8080
|
||||
* The Argo CD UI server on port 4000
|
||||
* The Helm registry server on port 5000
|
||||
|
||||
You may get an error listening on port 5000 on macOS:
|
||||
|
||||
```text
|
||||
docker: Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:5000 -> 0.0.0.0:0: listen tcp 0.0.0.0:5000: bind: address already in use.
|
||||
```
|
||||
|
||||
In that case, you can disable "AirPlay Receiver" in macOS System Preferences.
|
||||
|
||||
You can now use either the web UI by pointing your browser to `http://localhost:4000` or use the CLI against the API at `http://localhost:8080`. Be sure to use the `--insecure` and `--plaintext` options to the CLI. Webpack will take a while to bundle resources initially, so the first page load can take several seconds or minutes.
|
||||
|
||||
As an alternative to using the above command line parameters each time you call `argocd` CLI, you can set the following environment variables:
|
||||
@@ -68,51 +79,33 @@ export ARGOCD_SERVER=127.0.0.1:8080
|
||||
export ARGOCD_OPTS="--plaintext --insecure"
|
||||
```
|
||||
|
||||
### Start local services (running on local machine)
|
||||
### Start local services (local toolchain)
|
||||
When you use the local toolchain, starting local services can be performed in 3 ways:
|
||||
|
||||
The `make start` command of the virtualized toolchain runs the build and programs inside a Docker container using the test tools image. That makes everything repeatable, but can slow down the development workflow. Particularly on macOS where Docker and the Linux kernel run inside a VM, you may want to try developing fully locally.
|
||||
|
||||
Docker should be installed already. Assuming you manage installed software using [Homebrew](https://brew.sh/), you can install other prerequisites like this:
|
||||
|
||||
```sh
|
||||
# goreman is used to start all needed processes to get a working Argo CD development
|
||||
# environment (defined in `Procfile`)
|
||||
brew install goreman
|
||||
|
||||
# You can use `kind` to run Kubernetes inside Docker. But pointing to any other
|
||||
# development cluster works fine as well as long as Argo CD can reach it.
|
||||
brew install kind
|
||||
#### With "make start-local"
|
||||
```shell
|
||||
cd argo-cd
|
||||
make start-local ARGOCD_GPG_ENABLED=false
|
||||
```
|
||||
|
||||
To set up Kubernetes, you can use kind:
|
||||
|
||||
```sh
|
||||
kind create cluster --kubeconfig ~/.kube/config-kind
|
||||
|
||||
# The started services assume you are running in the namespace where Argo CD is
|
||||
# installed. Set the current context default namespace.
|
||||
export KUBECONFIG=~/.kube/config-kind
|
||||
kubectl config set-context --current --namespace=argocd
|
||||
#### With "make run"
|
||||
```shell
|
||||
cd argo-cd
|
||||
make run ARGOCD_GPG_ENABLED=false
|
||||
```
|
||||
|
||||
Follow the above sections "Install Argo CD resources to your cluster" and "Scale down any Argo CD instance in your cluster" to deploy all needed manifests such as config maps.
|
||||
|
||||
Start local services:
|
||||
|
||||
```sh
|
||||
# Ensure you point to the correct Kubernetes cluster as shown above. For example:
|
||||
export KUBECONFIG=~/.kube/config-kind
|
||||
|
||||
make start-local
|
||||
#### With "goreman start"
|
||||
```shell
|
||||
cd argo-cd
|
||||
ARGOCD_GPG_ENABLED=false && goreman start
|
||||
```
|
||||
|
||||
This will start all Argo CD services and the UI in a Docker container and expose the following ports to your host:
|
||||
Any of those options will start all Argo CD services and the UI:
|
||||
|
||||
* The Argo CD API server on port 8080
|
||||
* The Argo CD UI server on port 4000
|
||||
* The Helm registry server on port 5000
|
||||
|
||||
If you get firewall dialogs, for example on macOS, you can click "Deny", since no access from outside your computer is typically desired.
|
||||
|
||||
Check that all programs have started:
|
||||
|
||||
@@ -123,23 +116,9 @@ $ goreman run status
|
||||
[...]
|
||||
```
|
||||
|
||||
If some of the processes fail to start (not marked with `*`), check logs to see why they are not running.
|
||||
If some of the processes fail to start (not marked with `*`), check logs to see why they are not running. The logs are on `DEBUG` level by default. If the logs are too noisy to find the problem, try editing log levels for the commands in the `Procfile` in the root of the Argo CD repo.
|
||||
|
||||
In case of an error like `gpg: key generation failed: Unknown elliptic curve` (a [gnupg bug](https://dev.gnupg.org/T5444)), disable GPG verification before running `make start-local`:
|
||||
|
||||
```sh
|
||||
export ARGOCD_GPG_ENABLED=false
|
||||
```
|
||||
|
||||
You may get an error listening on port 5000 on macOS:
|
||||
|
||||
```text
|
||||
docker: Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:5000 -> 0.0.0.0:0: listen tcp 0.0.0.0:5000: bind: address already in use.
|
||||
```
|
||||
|
||||
In that case, you can disable "AirPlay Receiver" in macOS System Preferences.
|
||||
|
||||
You can now use either the web UI by pointing your browser to `http://localhost:4000` or use the CLI against the API at `http://localhost:8080`. Be sure to use the `--insecure` and `--plaintext` options to the CLI. Webpack will take a while to bundle resources initially, so the first page load can take several seconds or minutes.
|
||||
You can now use either use the web UI by pointing your browser to `http://localhost:4000` or use the CLI against the API at `http://localhost:8080`. Be sure to use the `--insecure` and `--plaintext` options to the CLI. Webpack will take a while to bundle resources initially, so the first page load can take several seconds or minutes.
|
||||
|
||||
As an alternative to using the above command line parameters each time you call `argocd` CLI, you can set the following environment variables:
|
||||
|
||||
@@ -147,37 +126,67 @@ As an alternative to using the above command line parameters each time you call
|
||||
export ARGOCD_SERVER=127.0.0.1:8080
|
||||
export ARGOCD_OPTS="--plaintext --insecure"
|
||||
```
|
||||
### Making code changes while Argo CD is running on your machine
|
||||
|
||||
After making a code change, ensure to rebuild and restart the respective service:
|
||||
#### Docs Changes
|
||||
|
||||
Modifying the docs auto-reloads the changes on the [documentation website](https://argo-cd.readthedocs.io/) that can be locally built using `make serve-docs-local` command.
|
||||
Once running, you can view your locally built documentation on port 8000.
|
||||
|
||||
Read more about this [here](https://argo-cd.readthedocs.io/en/latest/developer-guide/docs-site/).
|
||||
|
||||
#### UI Changes
|
||||
|
||||
Modifying the User-Interface (by editing .tsx or .scss files) auto-reloads the changes on port 4000.
|
||||
|
||||
#### Backend Changes
|
||||
|
||||
Modifying the API server, repo server, or a controller requires restarting the current `make start` for virtualized toolchain.
|
||||
For `make start-local` with the local toolchain, it is enough to rebuild and restart only the respective service:
|
||||
|
||||
```sh
|
||||
# Example for working on the repo server Go code, see other service names in `Procfile`
|
||||
goreman run restart repo-server
|
||||
```
|
||||
|
||||
Clean up when you're done:
|
||||
#### CLI Changes
|
||||
|
||||
```sh
|
||||
kind delete cluster; rm -f ~/.kube/config-kind
|
||||
Modifying the CLI requires restarting the current `make start` or `make start-local` session to reflect the changes. Those targets also rebuild the CLI.
|
||||
|
||||
To test most CLI commands, you will need to log in.
|
||||
|
||||
First, get the auto-generated secret:
|
||||
|
||||
```shell
|
||||
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
|
||||
```
|
||||
|
||||
Then log in using that password and username `admin`:
|
||||
|
||||
```shell
|
||||
dist/argocd login localhost:8080
|
||||
```
|
||||
|
||||
## Running Argo CD inside of K8s cluster
|
||||
### Scale up Argo CD in your cluster
|
||||
|
||||
Once you have finished testing your changes locally and want to bring back Argo CD in your development cluster, simply scale the deployments up again:
|
||||
|
||||
```bash
|
||||
kubectl -n argocd scale statefulset/argocd-application-controller --replicas 1
|
||||
kubectl -n argocd scale deployment/argocd-applicationset-controller --replicas 1
|
||||
kubectl -n argocd scale deployment/argocd-dex-server --replicas 1
|
||||
kubectl -n argocd scale deployment/argocd-repo-server --replicas 1
|
||||
kubectl -n argocd scale deployment/argocd-server --replicas 1
|
||||
kubectl -n argocd scale deployment/argocd-redis --replicas 1
|
||||
kubectl -n argocd scale deployment/argocd-notifications-controller --replicas 1
|
||||
```
|
||||
|
||||
## Run your own Argo CD images on your cluster
|
||||
### Run your own Argo CD images on your cluster
|
||||
|
||||
For your final tests, it might be necessary to build your own images and run them in your development cluster.
|
||||
|
||||
### Create Docker account and login
|
||||
#### Create Docker account and login
|
||||
|
||||
You might need to create an account on [Docker Hub](https://hub.docker.com) if you don't have one already. Once you created your account, login from your development environment:
|
||||
|
||||
@@ -185,7 +194,7 @@ You might need to create an account on [Docker Hub](https://hub.docker.com) if y
|
||||
docker login
|
||||
```
|
||||
|
||||
### Create and push Docker images
|
||||
#### Create and push Docker images
|
||||
|
||||
You will need to push the built images to your own Docker namespace:
|
||||
|
||||
@@ -205,7 +214,7 @@ Then you can build & push the image in one step:
|
||||
DOCKER_PUSH=true make image
|
||||
```
|
||||
|
||||
### Configure manifests for your image
|
||||
#### Configure manifests for your image
|
||||
|
||||
With `IMAGE_NAMESPACE` and `IMAGE_TAG` still set, run:
|
||||
|
||||
@@ -213,12 +222,18 @@ With `IMAGE_NAMESPACE` and `IMAGE_TAG` still set, run:
|
||||
make manifests
|
||||
```
|
||||
|
||||
to build a new set of installation manifests which include your specific image reference.
|
||||
or
|
||||
|
||||
```bash
|
||||
make manifests-local
|
||||
```
|
||||
|
||||
(depending on your toolchain) to build a new set of installation manifests which include your specific image reference.
|
||||
|
||||
!!!note
|
||||
Do not commit these manifests to your repository. If you want to revert the changes, the easiest way is to unset `IMAGE_NAMESPACE` and `IMAGE_TAG` from your environment and run `make manifests` again. This will re-create the default manifests.
|
||||
|
||||
### Configure your cluster with custom manifests
|
||||
#### Configure your cluster with custom manifests
|
||||
|
||||
The final step is to push the manifests to your cluster, so it will pull and run your image:
|
||||
|
||||
|
||||
86
docs/developer-guide/submit-your-pr.md
Normal file
86
docs/developer-guide/submit-your-pr.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# Submitting PRs
|
||||
|
||||
## Prerequisites
|
||||
1. [Development Environment](development-environment.md)
|
||||
2. [Toolchain Guide](toolchain-guide.md)
|
||||
3. [Development Cycle](development-cycle.md)
|
||||
|
||||
## Preface
|
||||
|
||||
!!!note "Before you start"
|
||||
The Argo CD project continuously grows, both in terms of features and community size. It gets adopted by more and more organizations which entrust Argo CD to handle their critical production workloads. Thus, we need to take great care with any changes that affect compatibility, performance, scalability, stability and security of Argo CD. For this reason, every new feature or larger enhancement must be properly designed and discussed before it gets accepted into the code base.
|
||||
|
||||
We do welcome and encourage everyone to participate in the Argo CD project, but please understand that we can't accept each and every contribution from the community, for various reasons. If you want to submit code for a great new feature or enhancement, we kindly ask you to take a look at the
|
||||
[code contribution guide](code-contributions.md#) before you start to write code or submit a PR.
|
||||
|
||||
If you want to submit a PR, please read this document carefully, as it contains important information guiding you through our PR quality gates.
|
||||
|
||||
If you need guidance with submitting a PR, or have any other questions regarding development of Argo CD, do not hesitate to [join our Slack](https://argoproj.github.io/community/join-slack) and get in touch with us in the `#argo-cd-contributors` channel!
|
||||
|
||||
## Before Submitting a PR
|
||||
|
||||
1. Rebase your branch against upstream main:
|
||||
```shell
|
||||
git fetch upstream
|
||||
git rebase upstream/main
|
||||
```
|
||||
|
||||
2. Run pre-commit checks:
|
||||
```shell
|
||||
make pre-commit-local
|
||||
```
|
||||
|
||||
## Continuous Integration process
|
||||
|
||||
When you submit a PR against Argo CD's GitHub repository, a couple of CI checks will be run automatically to ensure your changes will build fine and meet certain quality standards. Your contribution needs to pass those checks in order to be merged into the repository.
|
||||
|
||||
!!!note
|
||||
Please make sure that you always create PRs from a branch that is up-to-date with the latest changes from Argo CD's master branch. Depending on how long it takes for the maintainers to review and merge your PR, it might be necessary to pull in latest changes into your branch again.
|
||||
|
||||
Please understand that we, as an Open Source project, have limited capacities for reviewing and merging PRs to Argo CD. We will do our best to review your PR and give you feedback as soon as possible, but please bear with us if it takes a little longer as expected.
|
||||
|
||||
The following read will help you to submit a PR that meets the standards of our CI tests:
|
||||
|
||||
## Title of the PR
|
||||
|
||||
Please use a meaningful and concise title for your PR. This will help us to pick PRs for review quickly, and the PR title will also end up in the Changelog.
|
||||
|
||||
We use [PR title checker](https://github.com/marketplace/actions/pr-title-checker) to categorize your PR into one of the following categories:
|
||||
|
||||
* `fix` - Your PR contains one or more code bug fixes
|
||||
* `feat` - Your PR contains a new feature
|
||||
* `docs` - Your PR improves the documentation
|
||||
* `chore` - Your PR improves any internals of Argo CD, such as the build process, unit tests, etc
|
||||
|
||||
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.
|
||||
|
||||
## PR template checklist
|
||||
|
||||
Upon opening a PR, the details will contain a checklist from a template. Please read the checklist, and tick those marks that apply to you.
|
||||
|
||||
## Automated builds & tests
|
||||
|
||||
After you have submitted your PR, and whenever you push new commits to that branch, GitHub will run a number of Continuous Integration checks against your code. It will execute the following actions, and each of them has to pass:
|
||||
|
||||
* Build the Go code (`make build`)
|
||||
* Generate API glue code and manifests (`make codegen`)
|
||||
* Run a Go linter on the code (`make lint`)
|
||||
* Run the unit tests (`make test`)
|
||||
* Run the End-to-End tests (`make test-e2e`)
|
||||
* Build and lint the UI code (`make lint-ui`)
|
||||
* Build the `argocd` CLI (`make cli`)
|
||||
|
||||
If any of these tests in the CI pipeline fail, it means that some of your contribution is considered faulty (or a test might be flaky, see below).
|
||||
|
||||
## Code test coverage
|
||||
|
||||
We use [CodeCov](https://codecov.io) in our CI pipeline to check for test coverage, and once you submit your PR, it will run and report on the coverage difference as a comment within your PR. If the difference is too high in the negative, i.e. your submission introduced a significant drop in code coverage, the CI check will fail.
|
||||
|
||||
Whenever you develop a new feature or submit a bug fix, please also write appropriate unit tests for it. If you write a completely new module, please aim for at least 80% of coverage.
|
||||
If you want to see how much coverage just a specific module (i.e. your new one) has, you can set the `TEST_MODULE` to the (fully qualified) name of that module with `make test`, i.e.:
|
||||
|
||||
```bash
|
||||
make test TEST_MODULE=github.com/argoproj/argo-cd/server/cache
|
||||
...
|
||||
ok github.com/argoproj/argo-cd/server/cache 0.029s coverage: 89.3% of statements
|
||||
```
|
||||
@@ -1,109 +1,22 @@
|
||||
# Development toolchain
|
||||
# Development Toolchain
|
||||
|
||||
## Preface
|
||||
|
||||
!!!note "Before you start"
|
||||
The Argo CD project continuously grows, both in terms of features and community size. It gets adopted by more and more organisations which entrust Argo CD to handle their critical production workloads. Thus, we need to take great care with any changes that affect compatibility, performance, scalability, stability and security of Argo CD. For this reason, every new feature or larger enhancement must be properly designed and discussed before it gets accepted into the code base.
|
||||
|
||||
We do welcome and encourage everyone to participate in the Argo CD project, but please understand that we can't accept each and every contribution from the community, for various reasons. If you want to submit code for a great new feature or enhancement, we kindly ask you to take a look at the
|
||||
[code contribution guide](code-contributions.md#) before you start to write code or submit a PR.
|
||||
|
||||
We want to make contributing to Argo CD as simple and smooth as possible.
|
||||
|
||||
This guide shall help you in setting up your build & test environment, so that you can start developing and testing bug fixes and feature enhancements without having to make too much effort in setting up a local toolchain.
|
||||
|
||||
If you want to submit a PR, please read this document carefully, as it contains important information guiding you through our PR quality gates.
|
||||
|
||||
As is the case with the development process, this document is under constant change. If you notice any error, or if you think this document is out-of-date, or if you think it is missing something: Feel free to submit a PR or submit a bug to our GitHub issue tracker.
|
||||
|
||||
If you need guidance with submitting a PR, or have any other questions regarding development of Argo CD, do not hesitate to [join our Slack](https://argoproj.github.io/community/join-slack) and get in touch with us in the `#argo-cd-contributors` channel!
|
||||
|
||||
## Before you start
|
||||
|
||||
You will need at least the following things in your toolchain in order to develop and test Argo CD locally:
|
||||
|
||||
* A Kubernetes cluster. You won't need a fully blown multi-master, multi-node cluster, but you will need something like K3S, Minikube or microk8s. You will also need a working Kubernetes client (`kubectl`) configuration in your development environment. The configuration must reside in `~/.kube/config` and the API server URL must point to the IP address of your local machine (or VM), and **not** to `localhost` or `127.0.0.1` if you are using the virtualized development toolchain (see below)
|
||||
|
||||
* You will also need a working Docker runtime environment, to be able to build and run images. The Docker version must be 17.05.0 or higher, to support multi-stage builds.
|
||||
|
||||
* Obviously, you will need a `git` client for pulling source code and pushing back your changes.
|
||||
|
||||
* Last but not least, you will need a Go SDK and related tools (such as GNU `make`) installed and working on your development environment. The minimum required Go version for building and testing Argo CD is **v1.17**.
|
||||
|
||||
* We will assume that your Go workspace is at `~/go`.
|
||||
|
||||
!!! note
|
||||
**Attention minikube users**: By default, minikube will create Kubernetes client configuration that uses authentication data from files. This is incompatible with the virtualized toolchain. So if you intend to use the virtualized toolchain, you have to embed this authentication data into the client configuration. To do so, start minikube using `minikube start --embed-certs`. Please also note that minikube using the Docker driver is currently not supported with the virtualized toolchain, because the Docker driver exposes the API server on 127.0.0.1 hard-coded. If in doubt, run `make verify-kube-connect` to find out.
|
||||
|
||||
## Submitting PRs
|
||||
|
||||
### Continuous Integration process
|
||||
|
||||
When you submit a PR against Argo CD's GitHub repository, a couple of CI checks will be run automatically to ensure your changes will build fine and meet certain quality standards. Your contribution needs to pass those checks in order to be merged into the repository.
|
||||
|
||||
!!!note
|
||||
Please make sure that you always create PRs from a branch that is up-to-date with the latest changes from Argo CD's master branch. Depending on how long it takes for the maintainers to review and merge your PR, it might be necessary to pull in latest changes into your branch again.
|
||||
|
||||
Please understand that we, as an Open Source project, have limited capacities for reviewing and merging PRs to Argo CD. We will do our best to review your PR and give you feedback as soon as possible, but please bear with us if it takes a little longer as expected.
|
||||
|
||||
The following read will help you to submit a PR that meets the standards of our CI tests:
|
||||
|
||||
### Title of the PR
|
||||
|
||||
Please use a meaningful and concise title for your PR. This will help us to pick PRs for review quickly, and the PR title will also end up in the Changelog.
|
||||
|
||||
We use [PR title checker](https://github.com/marketplace/actions/pr-title-checker) to categorize your PR into one of the following categories:
|
||||
|
||||
* `fix` - Your PR contains one or more code bug fixes
|
||||
* `feat` - Your PR contains a new feature
|
||||
* `docs` - Your PR improves the documentation
|
||||
* `chore` - Your PR improves any internals of Argo CD, such as the build process, unit tests, etc
|
||||
|
||||
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.
|
||||
|
||||
### PR template checklist
|
||||
|
||||
Upon opening a PR, the details will contain a checklist from a template. Please read the checklist, and tick those marks that apply to you.
|
||||
|
||||
### Automated builds & tests
|
||||
|
||||
After you have submitted your PR, and whenever you push new commits to that branch, GitHub will run a number of Continuous Integration checks against your code. It will execute the following actions, and each of them has to pass:
|
||||
|
||||
* Build the Go code (`make build`)
|
||||
* Generate API glue code and manifests (`make codegen`)
|
||||
* Run a Go linter on the code (`make lint`)
|
||||
* Run the unit tests (`make test`)
|
||||
* Run the End-to-End tests (`make test-e2e`)
|
||||
* Build and lint the UI code (`make lint-ui`)
|
||||
* Build the `argocd` CLI (`make cli`)
|
||||
|
||||
If any of these tests in the CI pipeline fail, it means that some of your contribution is considered faulty (or a test might be flaky, see below).
|
||||
|
||||
### Code test coverage
|
||||
|
||||
We use [CodeCov](https://codecov.io) in our CI pipeline to check for test coverage, and once you submit your PR, it will run and report on the coverage difference as a comment within your PR. If the difference is too high in the negative, i.e. your submission introduced a significant drop in code coverage, the CI check will fail.
|
||||
|
||||
Whenever you develop a new feature or submit a bug fix, please also write appropriate unit tests for it. If you write a completely new module, please aim for at least 80% of coverage.
|
||||
If you want to see how much coverage just a specific module (i.e. your new one) has, you can set the `TEST_MODULE` to the (fully qualified) name of that module with `make test`, i.e.:
|
||||
|
||||
```bash
|
||||
make test TEST_MODULE=github.com/argoproj/argo-cd/server/cache
|
||||
...
|
||||
ok github.com/argoproj/argo-cd/server/cache 0.029s coverage: 89.3% of statements
|
||||
```
|
||||
## Prerequisites
|
||||
[Development Environment](development-environment.md)
|
||||
|
||||
## Local vs Virtualized toolchain
|
||||
|
||||
Argo CD provides a fully virtualized development and testing toolchain using Docker images. It is recommended to use those images, as they provide the same runtime environment as the final product, and it is much easier to keep up-to-date with changes to the toolchain and dependencies. But as using Docker comes with a slight performance penalty, you might want to set up a local toolchain.
|
||||
Argo CD provides a fully virtualized development and testing toolchain using Docker images. Those images provide the same runtime environment as the final product, and it is much easier to keep up-to-date with changes to the toolchain and dependencies. The virtualized toolchain runs the build and programs inside a Docker container using the test tools image. That makes everything repeatable. The dynamic nature of requirements is another reason to choose this toolchain. This setup may also require configuring the default K8s API URL that comes with installing a local K8s cluster.
|
||||
|
||||
Most relevant targets for the build & test cycles in the `Makefile` provide two variants, one of them suffixed with `-local`. For example, `make test` will run unit tests in the Docker container, `make test-local` will run it natively on your local system.
|
||||
The local toolchain results in a faster development and testing cycle. Particularly on macOS where Docker and the Linux kernel run inside a VM, you may want to try developing fully locally. Local toolchain also requires installing additional tools on your machine. This toolchain is a good choice for working with an IDE debugger.
|
||||
|
||||
Most relevant targets for the build & test cycles in the `Makefile` provide two variants, one of them suffixed with `-local`. For example, `make test` will run unit tests in the Docker container (virtualized toolchain), `make test-local` (local toolchain) will run it natively on your local system.
|
||||
|
||||
### Setting up a virtualized toolchain
|
||||
|
||||
If you are going to use the virtualized toolchain, please bear in mind the following things:
|
||||
|
||||
* Your Kubernetes API server must listen on the interface of your local machine or VM, and not on `127.0.0.1` only.
|
||||
* Your Kubernetes client configuration (`~/.kube/config`) must not use an API URL that points to `localhost` or `127.0.0.1`.
|
||||
|
||||
You can test whether the virtualized toolchain has access to your Kubernetes cluster by running `make verify-kube-connect` (*after* you have set up your development environment, as described below), which will run `kubectl version` inside the Docker container used for running all tests.
|
||||
* Your Kubernetes API server must listen on the interface of your local machine or VM, and not on `127.0.0.1` or `localhost` only.
|
||||
* Your Kubernetes client configuration (`~/.kube/config`) must not use an API URL that points to `localhost`, `127.0.0.1` or `0.0.0.0`
|
||||
|
||||
The Docker container for the virtualized toolchain will use the following local mounts from your workstation, and possibly modify its contents:
|
||||
|
||||
@@ -112,78 +25,43 @@ The Docker container for the virtualized toolchain will use the following local
|
||||
* `~/.kube` - Your Kubernetes client configuration (no modifications)
|
||||
* `/tmp` - Your system's temp directory (modifications expected)
|
||||
|
||||
## Setting up your development environment
|
||||
#### Known issues on macOS
|
||||
[Known issues](mac-users.md)
|
||||
|
||||
The following steps are required no matter whether you chose to use a virtualized or a local toolchain.
|
||||
#### Docker privileges
|
||||
|
||||
!!!note "Docker privileges"
|
||||
If you opt in to use the virtualized toolchain, you will need to have the
|
||||
appropriate privileges to interact with the Docker daemon. It is not
|
||||
recommended to work as the root user, and if your user does not have the
|
||||
permissions to talk to the Docker user, but you have `sudo` setup on your
|
||||
system, you can set the environment variable `SUDO` to `sudo` in order to
|
||||
have the build scripts make any calls to the `docker` CLI using sudo,
|
||||
without affecting the other parts of the build scripts (which should be
|
||||
executed with your normal user privileges).
|
||||
If you opt in to use the virtualized toolchain, you will need to have the appropriate privileges to interact with the Docker daemon. It is not recommended to work as the root user, and if your user does not have the permissions to talk to the Docker user, but you have `sudo` setup on your system, you can set the environment variable `SUDO` to `sudo` in order to have the build scripts make any calls to the `docker` CLI using sudo, without affecting the other parts of the build scripts (which should be executed with your normal user privileges).
|
||||
|
||||
You can either set this before calling `make`, like so for example:
|
||||
You can either set this before calling `make`, like so for example:
|
||||
|
||||
```
|
||||
SUDO=sudo make sometarget
|
||||
```
|
||||
```
|
||||
SUDO=sudo make sometarget
|
||||
```
|
||||
|
||||
Or you can opt to export this permanently to your environment, for example
|
||||
```
|
||||
export SUDO=sudo
|
||||
```
|
||||
Or you can opt to export this permanently to your environment, for example
|
||||
```
|
||||
export SUDO=sudo
|
||||
```
|
||||
|
||||
If you have podman installed, you can also leverage its rootless mode. In
|
||||
order to use podman for running and testing Argo CD locally, set the
|
||||
`DOCKER` environment variable to `podman` before you run `make`, e.g.
|
||||
#### Using Podman
|
||||
In order to use podman for running and testing Argo CD locally, set the `DOCKER` environment variable to `podman` before you run `make`, e.g:
|
||||
|
||||
```
|
||||
DOCKER=podman make start
|
||||
```
|
||||
```
|
||||
DOCKER=podman make start
|
||||
```
|
||||
If you have podman installed, you can leverage its rootless mode.
|
||||
|
||||
### Clone the Argo CD repository from your personal fork on GitHub
|
||||
|
||||
* `git clone https://github.com/YOUR-USERNAME/argo-cd`
|
||||
* `cd argo-cd`
|
||||
|
||||
### Optional: Set up an additional Git remote
|
||||
|
||||
While everyone has their own Git workflow, the author of this document recommends to create a remote called `upstream` in your local copy pointing to the original Argo CD repository. This way, you can easily keep your local branches up-to-date by merging in latest changes from the Argo CD repository, i.e. by doing a `git pull upstream master` in your locally checked out branch. To create the remote, run `git remote add upstream https://github.com/argoproj/argo-cd`
|
||||
|
||||
### Install the must-have requirements
|
||||
|
||||
Make sure you fulfill the pre-requisites above and run some preliminary tests. Neither of them should report an error.
|
||||
|
||||
* Run `kubectl version`
|
||||
* Run `docker version`
|
||||
* Run `go version`
|
||||
|
||||
### Build the required Docker image
|
||||
#### Build the required Docker image
|
||||
|
||||
Build the required Docker image by running `make test-tools-image`. This image offers the environment of the virtualized toolchain.
|
||||
|
||||
The `Dockerfile` used to build these images can be found at `test/container/Dockerfile`.
|
||||
|
||||
### Test connection from build container to your K8s cluster
|
||||
#### Configure your K8s cluster for connection from the build container
|
||||
##### K3d
|
||||
K3d is a minimal Kubernetes distribution, in docker. Because it's running in a docker container, you're dealing with docker's internal networking rules when using k3d. A typical Kubernetes cluster running on your local machine is part of the same network that you're on, so you can access it using **kubectl**. However, a Kubernetes cluster running within a docker container (in this case, the one launched by make) cannot access 0.0.0.0 from inside the container itself, when 0.0.0.0 is a network resource outside the container itself (and/or the container's network). This is the cost of a fully self-contained, disposable Kubernetes cluster.
|
||||
|
||||
Run `make verify-kube-connect`, it should execute without error.
|
||||
|
||||
If you receive an error similar to the following:
|
||||
|
||||
```
|
||||
The connection to the server 127.0.0.1:6443 was refused - did you specify the right host or port?
|
||||
make: *** [Makefile:386: verify-kube-connect] Error 1
|
||||
```
|
||||
|
||||
you should edit your `~/.kube/config` and modify the `server` option to point to your correct K8s API (as described above).
|
||||
|
||||
### Using k3d
|
||||
|
||||
[k3d](https://github.com/rancher/k3d) is a lightweight wrapper to run [k3s](https://github.com/rancher/k3s), a minimal Kubernetes distribution, in docker. Because it's running in a docker container, you're dealing with docker's internal networking rules when using k3d. A typical Kubernetes cluster running on your local machine is part of the same network that you're on, so you can access it using **kubectl**. However, a Kubernetes cluster running within a docker container (in this case, the one launched by make) cannot access 0.0.0.0 from inside the container itself, when 0.0.0.0 is a network resource outside the container itself (and/or the container's network). This is the cost of a fully self-contained, disposable Kubernetes cluster. The following steps should help with a successful `make verify-kube-connect` execution.
|
||||
The configuration you will need for Argo CD virtualized toolchain:
|
||||
|
||||
1. Find your host IP by executing `ifconfig` on Mac/Linux and `ipconfig` on Windows. For most users, the following command works to find the IP address.
|
||||
|
||||
@@ -203,103 +81,45 @@ you should edit your `~/.kube/config` and modify the `server` option to point to
|
||||
|
||||
Keep in mind that this IP is dynamically assigned by the router so if your router restarts for any reason, your IP might change.
|
||||
|
||||
2. Edit your ~/.kube/config and replace 0.0.0.0 with the above IP address.
|
||||
2. Edit your ~/.kube/config and replace 0.0.0.0 with the above IP address, delete the cluster cert and add `insecure-skip-tls-verify: true`
|
||||
|
||||
3. Execute a `kubectl version` to make sure you can still connect to the Kubernetes API server via this new IP. Run `make verify-kube-connect` and check if it works.
|
||||
3. Execute a `kubectl version` to make sure you can still connect to the Kubernetes API server via this new IP.
|
||||
|
||||
4. Finally, so that you don't have to keep updating your kube-config whenever you spin up a new k3d cluster, add `--api-port $IP:6550` to your **k3d cluster create** command, where $IP is the value from step 1. An example command is provided here:
|
||||
##### Minikube
|
||||
|
||||
By default, minikube will create Kubernetes client configuration that uses authentication data from files. This is incompatible with the virtualized toolchain. So if you intend to use the virtualized toolchain, you have to embed this authentication data into the client configuration. To do so, start minikube using `minikube start --embed-certs`. Please also note that minikube using the Docker driver is currently not supported with the virtualized toolchain, because the Docker driver exposes the API server on 127.0.0.1 hard-coded.
|
||||
|
||||
#### Test connection from the build container to your K8s cluster
|
||||
|
||||
You can test whether the virtualized toolchain has access to your Kubernetes cluster by running `make verify-kube-connect` which will run `kubectl version` inside the Docker container used for running all tests.
|
||||
|
||||
|
||||
If you receive an error similar to the following:
|
||||
|
||||
```
|
||||
k3d cluster create my-cluster --wait --k3s-arg '--disable=traefik@server:*' --api-port $IP:6550 -p 443:443@loadbalancer
|
||||
The connection to the server 127.0.0.1:6443 was refused - did you specify the right host or port?
|
||||
make: *** [Makefile:386: verify-kube-connect] Error 1
|
||||
```
|
||||
|
||||
!!!note
|
||||
For k3d versions less than v5.0.0, the example command flags `--k3s-arg` and `'--disable=traefik@server:*'` should change to `--k3s-server-arg` and `'--disable=traefik'`, respectively.
|
||||
you should edit your `~/.kube/config` and modify the `server` option to point to your correct K8s API (as described above).
|
||||
|
||||
## The development cycle
|
||||
### Setting up a local toolchain
|
||||
|
||||
When you have developed and possibly manually tested the code you want to contribute, you should ensure that everything will build correctly. Commit your changes to the local copy of your Git branch and perform the following steps:
|
||||
#### Install `node`
|
||||
|
||||
### Pull in all build dependencies
|
||||
<https://nodejs.org/en/download>
|
||||
|
||||
As build dependencies change over time, you have to synchronize your development environment with the current specification. In order to pull in all required dependencies, issue:
|
||||
#### Install `yarn`
|
||||
|
||||
* `make dep-ui`
|
||||
<https://classic.yarnpkg.com/lang/en/docs/install/>
|
||||
|
||||
Argo CD recently migrated to Go modules. Usually, dependencies will be downloaded on build time, but the Makefile provides two targets to download and vendor all dependencies:
|
||||
#### Install `goreman`
|
||||
|
||||
* `make mod-download` will download all required Go modules and
|
||||
* `make mod-vendor` will vendor those dependencies into the Argo CD source tree
|
||||
<https://github.com/mattn/goreman#getting-started>
|
||||
|
||||
### Generate API glue code and other assets
|
||||
Goreman is used to start all needed processes to get a working Argo CD development environment (defined in `Procfile`)
|
||||
|
||||
Argo CD relies on Google's [Protocol Buffers](https://developers.google.com/protocol-buffers) for its API, and this makes heavy use of auto-generated glue code and stubs. Whenever you touched parts of the API code, you must re-generate the auto generated code.
|
||||
|
||||
* Run `make codegen`, this might take a while
|
||||
* Check if something has changed by running `git status` or `git diff`
|
||||
* Commit any possible changes to your local Git branch, an appropriate commit message would be `Changes from codegen`, for example.
|
||||
|
||||
!!!note
|
||||
There are a few non-obvious assets that are auto-generated. You should not change the autogenerated assets, as they will be overwritten by a subsequent run of `make codegen`. Instead, change their source files. Prominent examples of non-obvious auto-generated code are `swagger.json` or the installation manifest YAMLs.
|
||||
|
||||
### Build your code and run unit tests
|
||||
|
||||
After the code glue has been generated, your code should build and the unit tests should run without any errors. Execute the following statements:
|
||||
|
||||
* `make build`
|
||||
* `make test`
|
||||
|
||||
These steps are non-modifying, so there's no need to check for changes afterward.
|
||||
|
||||
### Lint your code base
|
||||
|
||||
In order to keep a consistent code style in our source tree, your code must be well-formed in accordance to some widely accepted rules, which are applied by a Linter.
|
||||
|
||||
The Linter might make some automatic changes to your code, such as indentation fixes. Some other errors reported by the Linter have to be fixed manually.
|
||||
|
||||
* Run `make lint` and observe any errors reported by the Linter
|
||||
* Fix any of the errors reported and commit to your local branch
|
||||
* Finally, after the Linter reports no errors anymore, run `git status` or `git diff` to check for any changes made automatically by Lint
|
||||
* If there were automatic changes, commit them to your local branch
|
||||
|
||||
If you touched UI code, you should also run the Yarn linter on it:
|
||||
|
||||
* Run `make lint-ui`
|
||||
* Fix any of the errors reported by it
|
||||
|
||||
## Contributing to Argo CD UI
|
||||
|
||||
Argo CD, along with Argo Workflows, uses shared React components from [Argo UI](https://github.com/argoproj/argo-ui). Examples of some of these components include buttons, containers, form controls,
|
||||
and others. Although you can make changes to these files and run them locally, in order to have these changes added to the Argo CD repo, you will need to follow these steps.
|
||||
|
||||
1. Fork and clone the [Argo UI repository](https://github.com/argoproj/argo-ui).
|
||||
|
||||
2. `cd` into your `argo-ui` directory, and then run `yarn install`.
|
||||
|
||||
3. Make your file changes.
|
||||
|
||||
4. Run `yarn start` to start a [storybook](https://storybook.js.org/) dev server and view the components in your browser. Make sure all your changes work as expected.
|
||||
|
||||
5. Use [yarn link](https://classic.yarnpkg.com/en/docs/cli/link/) to link Argo UI package to your Argo CD repository. (Commands below assume that `argo-ui` and `argo-cd` are both located within the same parent folder)
|
||||
|
||||
* `cd argo-ui`
|
||||
* `yarn link`
|
||||
* `cd ../argo-cd/ui`
|
||||
* `yarn link argo-ui`
|
||||
|
||||
Once `argo-ui` package has been successfully linked, test out changes in your local development environment.
|
||||
|
||||
6. Commit changes and open a PR to [Argo UI](https://github.com/argoproj/argo-ui).
|
||||
|
||||
7. Once your PR has been merged in Argo UI, `cd` into your `argo-cd/ui` folder and run `yarn add git+https://github.com/argoproj/argo-ui.git`. This will update the commit SHA in the `ui/yarn.lock` file to use the latest master commit for argo-ui.
|
||||
|
||||
8. Submit changes to `ui/yarn.lock`in a PR to Argo CD.
|
||||
|
||||
## Setting up a local toolchain
|
||||
|
||||
For development, you can either use the fully virtualized toolchain provided as Docker images, or you can set up the toolchain on your local development machine. Due to the dynamic nature of requirements, you might want to stay with the virtualized environment.
|
||||
|
||||
### Install required dependencies and build-tools
|
||||
#### Install required dependencies and build-tools
|
||||
|
||||
!!!note
|
||||
The installations instructions are valid for Linux hosts only. Mac instructions will follow shortly.
|
||||
@@ -316,36 +136,3 @@ Additionally, you have to install at least the following tools via your OS's pac
|
||||
|
||||
* Git LFS plugin
|
||||
* GnuPG version 2
|
||||
|
||||
### Install Go dependencies
|
||||
|
||||
You need to pull in all required Go dependencies. To do so, run
|
||||
|
||||
* `make mod-download-local`
|
||||
* `make mod-vendor-local`
|
||||
|
||||
### Test your build toolchain
|
||||
|
||||
The first thing you can do to test whether your build toolchain is set up correctly is by generating the glue code for the API and after that, run a normal build:
|
||||
|
||||
* `make codegen-local`
|
||||
* `make build-local`
|
||||
|
||||
This should return without any error.
|
||||
|
||||
### Run unit-tests
|
||||
|
||||
The next thing is to make sure that unit tests are running correctly on your system. These will require that all dependencies, such as Helm, Kustomize, Git, GnuPG, etc. are correctly installed and fully functioning:
|
||||
|
||||
* `make test-local`
|
||||
|
||||
### Run end-to-end tests
|
||||
|
||||
The final step is running the End-to-End testsuite, which makes sure that your Kubernetes dependencies are working properly. This will involve starting all the Argo CD components locally on your computer. The end-to-end tests consists of two parts: a server component, and a client component.
|
||||
|
||||
* First, start the End-to-End server: `make start-e2e-local`. This will spawn a number of processes and services on your system.
|
||||
* When all components have started, run `make test-e2e-local` to run the end-to-end tests against your local services.
|
||||
|
||||
To run a single test, you can use `TEST_FLAGS="-run TestName" make test-e2e-local`.
|
||||
|
||||
For more information about End-to-End tests, refer to the [End-to-End test documentation](test-e2e.md).
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
Gitpod is not currently available for Argo CD development.
|
||||
|
||||
See the [Contributors Quickstart](contributors-quickstart.md) guide to set up a minimal development environment.
|
||||
See the [Overview](index.md) guide to set up a development environment.
|
||||
|
||||
@@ -205,6 +205,12 @@ data:
|
||||
reposerver.streamed.manifest.max.tar.size: "100M"
|
||||
# Maximum size of extracted manifests when streaming manifests to the repo server for generation
|
||||
reposerver.streamed.manifest.max.extracted.size: "1G"
|
||||
# Maximum size of extracted manifests when streaming manifests to the repo server for generation
|
||||
reposerver.oci.manifest.max.extracted.size: "1G"
|
||||
# Whether to disable manifest size check for OCI artifacts
|
||||
reposerver.disable.oci.manifest.max.extracted.size: "false"
|
||||
# The allowlist of the OCI media types which the repo-server will make use of. If an OCI media type for a given artifact is not in the given list, the repo-server will return an error.
|
||||
reposerver.oci.layer.media.types: "application/vnd.oci.image.layer.v1.tar,application/vnd.oci.image.layer.v1.tar+gzip,application/vnd.cncf.helm.chart.content.v1.tar+gzip"
|
||||
# Enable git submodule support
|
||||
reposerver.enable.git.submodule: "true"
|
||||
# Number of concurrent git ls-remote requests. Any value less than 1 means no limit.
|
||||
@@ -284,6 +290,8 @@ data:
|
||||
applicationsetcontroller.global.preserved.labels: "acme.com/label1,acme.com/label2"
|
||||
# Enable GitHub API metrics for generators that use GitHub API
|
||||
applicationsetcontroller.enable.github.api.metrics: "true"
|
||||
# The maximum number of resources stored in the status of an ApplicationSet. This is a safeguard to prevent the status from growing too large.
|
||||
applicationsetcontroller.status.max.resources.count: "5000"
|
||||
|
||||
## Argo CD Notifications Controller Properties
|
||||
# Set the logging level. One of: debug|info|warn|error (default "info")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
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.
|
||||
|
||||
A set of [HA manifests](https://github.com/argoproj/argo-cd/tree/master/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.
|
||||
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
|
||||
|
||||
|
||||
@@ -209,6 +209,7 @@ argocd_cluster_labels{label_environment="production",label_team_name="team3",nam
|
||||
|
||||
Metrics about API Server API request and response activity (request totals, response codes, etc...).
|
||||
Scraped at the `argocd-server-metrics:8083/metrics` endpoint.
|
||||
For GRPC metrics to show up environment variable ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM must be set to true.
|
||||
|
||||
| Metric | Type | Description |
|
||||
| ------------------------------------------------- | :-------: | ------------------------------------------------------------------------------------------- |
|
||||
@@ -248,9 +249,11 @@ Scraped at the `argocd-server-metrics:8083/metrics` endpoint.
|
||||
|
||||
## Repo Server Metrics
|
||||
|
||||
Metrics about the Repo Server.
|
||||
Metrics about the Repo Server. The gRPC metrics are not exposed by default. Metrics can be enabled using
|
||||
`ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM=true` environment variable.
|
||||
Scraped at the `argocd-repo-server:8084/metrics` endpoint.
|
||||
|
||||
|
||||
| Metric | Type | Description |
|
||||
| --------------------------------------- | :-------: | ------------------------------------------------------------------------- |
|
||||
| `argocd_git_request_duration_seconds` | histogram | Git requests duration seconds. |
|
||||
|
||||
@@ -35,14 +35,26 @@ metadata:
|
||||
name: argocd-notifications-cm
|
||||
data:
|
||||
trigger.sync-operation-change: |
|
||||
- when: app.status.operationState.phase in ['Succeeded']
|
||||
- when: app.status?.operationState.phase in ['Succeeded']
|
||||
send: [github-commit-status]
|
||||
- when: app.status.operationState.phase in ['Running']
|
||||
- when: app.status?.operationState.phase in ['Running']
|
||||
send: [github-commit-status]
|
||||
- when: app.status.operationState.phase in ['Error', 'Failed']
|
||||
- when: app.status?.operationState.phase in ['Error', 'Failed']
|
||||
send: [app-sync-failed, github-commit-status]
|
||||
```
|
||||
|
||||
|
||||
## Accessing Optional Manifest Sections and Fields
|
||||
|
||||
Note that in the trigger example above, the `?.` (optional chaining) operator is used to access the Application's
|
||||
`status.operationState` section. This section is optional; it is not present when an operation has been initiated but has not yet
|
||||
started by the Application Controller.
|
||||
|
||||
If the `?.` operator were not used, `status.operationState` would resolve to `nil` and the evaluation of the
|
||||
`app.status.operationState.phase` expression would fail. The `app.status?.operationState.phase` expression is equivalent to
|
||||
`app.status.operationState != nil ? app.status.operationState.phase : nil`.
|
||||
|
||||
|
||||
## Avoid Sending Same Notification Too Often
|
||||
|
||||
In some cases, the trigger condition might be "flapping". The example below illustrates the problem.
|
||||
@@ -60,14 +72,14 @@ data:
|
||||
# Optional 'oncePer' property ensure that notification is sent only once per specified field value
|
||||
# E.g. following is triggered once per sync revision
|
||||
trigger.on-deployed: |
|
||||
when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'
|
||||
when: app.status?.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'
|
||||
oncePer: app.status.sync.revision
|
||||
send: [app-sync-succeeded]
|
||||
```
|
||||
|
||||
**Mono Repo Usage**
|
||||
|
||||
When one repo is used to sync multiple applications, the `oncePer: app.status.sync.revision` field will trigger a notification for each commit. For mono repos, the better approach will be using `oncePer: app.status.operationState.syncResult.revision` statement. This way a notification will be sent only for a particular Application's revision.
|
||||
When one repo is used to sync multiple applications, the `oncePer: app.status.sync.revision` field will trigger a notification for each commit. For mono repos, the better approach will be using `oncePer: app.status?.operationState.syncResult.revision` statement. This way a notification will be sent only for a particular Application's revision.
|
||||
|
||||
### oncePer
|
||||
|
||||
@@ -122,7 +134,7 @@ Triggers have access to the set of built-in functions.
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
when: time.Now().Sub(time.Parse(app.status.operationState.startedAt)).Minutes() >= 5
|
||||
when: time.Now().Sub(time.Parse(app.status?.operationState.startedAt)).Minutes() >= 5
|
||||
```
|
||||
|
||||
{!docs/operator-manual/notifications/functions.md!}
|
||||
|
||||
@@ -221,3 +221,17 @@ actions["create-workflow"] = {
|
||||
}
|
||||
return actions
|
||||
```
|
||||
|
||||
### Action Parameters
|
||||
|
||||
You can define parameters for your custom actions. The parameters are defined in the `parameters` key of the action discovery definition.
|
||||
|
||||
<!-- Link directly to the script for people reading the docs in GitHub where embedding doesn't work. -->
|
||||
See the [Deployment actions discovery script](https://github.com/argoproj/argo-cd/blob/master/resource_customizations/apps/Deployment/actions/discovery.lua):
|
||||
|
||||
<!-- Embed the actual script so ReadTheDocs always has an up-to-date example. -->
|
||||
```lua
|
||||
{!resource_customizations/apps/Deployment/actions/discovery.lua!}
|
||||
```
|
||||
|
||||
The [resource scale actions](../user-guide/scale_application_resources.md) documentation shows how this function behaves in the UI.
|
||||
|
||||
@@ -37,6 +37,7 @@ argocd-applicationset-controller [flags]
|
||||
--kubeconfig string Path to a kube config. Only required if out-of-cluster
|
||||
--logformat string Set the logging format. One of: json|text (default "json")
|
||||
--loglevel string Set the logging level. One of: debug|info|warn|error (default "info")
|
||||
--max-resources-status-count int Max number of resources stored in appset status.
|
||||
--metrics-addr string The address the metric endpoint binds to. (default ":8080")
|
||||
--metrics-applicationset-labels strings List of Application labels that will be added to the argocd_applicationset_labels metric
|
||||
-n, --namespace string If present, the namespace scope for this CLI request
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
This page is populated for released Argo CD versions. Use the version selector to view this table for a specific
|
||||
version.
|
||||
| Argo CD version | Kubernetes versions |
|
||||
|-----------------|---------------------|
|
||||
| 3.1 | v1.34, v1.33, v1.32, v1.31 |
|
||||
| 3.0 | v1.32, v1.31, v1.30, v1.29 |
|
||||
| 2.14 | v1.31, v1.30, v1.29, v1.28 |
|
||||
|
||||
@@ -11,4 +11,12 @@ Eg, `https://github.com/argoproj/argo-cd/manifests/ha/cluster-install?ref=v2.14.
|
||||
## Upgraded Helm Version
|
||||
|
||||
Helm was upgraded to 3.16.2 and the skipSchemaValidation Flag was added to
|
||||
the [CLI and Application CR](https://argo-cd.readthedocs.io/en/latest/user-guide/helm/#helm-skip-schema-validation).
|
||||
the [CLI and Application CR](https://argo-cd.readthedocs.io/en/latest/user-guide/helm/#helm-skip-schema-validation).
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
## Sanitized project API response
|
||||
|
||||
Due to security reasons ([GHSA-786q-9hcg-v9ff](https://github.com/argoproj/argo-cd/security/advisories/GHSA-786q-9hcg-v9ff)),
|
||||
the project API response was sanitized to remove sensitive information. This includes
|
||||
credentials of project-scoped repositories and clusters.
|
||||
|
||||
@@ -7,6 +7,13 @@ applicable) restore Argo CD 2.x default behavior.
|
||||
Once 3.0 is released, no more 2.x minor versions will be released. We will continue to cut patch releases for the two
|
||||
most recent minor versions (so 2.14 until 3.2 is released and 2.13 until 3.1 is released).
|
||||
|
||||
## Images missing release notes on GitHub
|
||||
|
||||
!!! important
|
||||
Images 3.0.7 - 3.0.9 are missing release notes on GitHub. There was an issue with GoReleaser and building the darwin
|
||||
CLI that prevented the release notes from being published. More information can be found
|
||||
on [PR #23507](https://github.com/argoproj/argo-cd/pull/23507)
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
### Fine-Grained RBAC for application `update` and `delete` sub-resources
|
||||
@@ -239,16 +246,36 @@ external code copying tracking labels from one resource to another.
|
||||
|
||||
#### Detection
|
||||
|
||||
To detect if you are impacted, check the `argocd-cm` ConfigMap for the `application.resourceTrackingMethod` field. If it
|
||||
To detect if you are impacted, check the `argocd-cm` ConfigMap for the `application.resourceTrackingMethod` field. If it is
|
||||
unset or is set to `label`, you are using label-based tracking. If it is set to `annotation`, you are already using
|
||||
annotation-based tracking and are not impacted by this change.
|
||||
|
||||
```sh
|
||||
kubectl get cm argocd-cm -n argocd -o jsonpath='{.data.application\.resourceTrackingMethod}'
|
||||
```
|
||||
If you are using label-based tracking, it is also important to detect whether you have Applications that use `ApplyOutOfSyncOnly=true` syncOptions, as such Applications are likely to have orphan resources after switching to `annotation` tracking method and need to be synced explicitly right after the upgrade.
|
||||
|
||||
To detect whether you have such Applications, run:
|
||||
```sh
|
||||
kubectl get applications.argoproj.io -A -o json | jq -r '.items[] | select(.spec.syncPolicy.syncOptions[]? == "ApplyOutOfSyncOnly=true") | .metadata.name'
|
||||
```
|
||||
|
||||
#### Remediation
|
||||
|
||||
##### Users with ApplyOutOfSyncOnly=true syncOptions and label-based tracking
|
||||
|
||||
For users with label-based tracking and Applications that have `ApplyOutOfSyncOnly=true` syncOptions, an explicit sync has to be run for those Applications after you upgrade.
|
||||
Here is an example command, that syncs such an Application, it can be run after you [obtain a token](../../developer-guide/api-docs.md#authorization) to Argo CD API:
|
||||
```sh
|
||||
curl -X POST -H "Authorization: Bearer $ARGOCD_TOKEN" -H "Content-Type: application/json" -d '{
|
||||
"name": "$YOUR_APP_NAME"
|
||||
}' "http://$YOUR_ARGOCD_URL/api/v1/applications/$YOUR_APP_NAME/sync"
|
||||
```
|
||||
|
||||
It is also possible to sync such an Applicaton using the UI, with `ApplyOutOfSyncOnly` option unchecked. However, currently, performing a sync without `ApplyOutOfSyncOnly` option is not possible using the CLI.
|
||||
|
||||
##### Other users
|
||||
|
||||
For most users, it is safe to upgrade to Argo CD 3.0 and use annotation-based tracking. Labels will be replaced with
|
||||
annotations on the next sync. Applications will not be marked as out-of-sync if labels are not present on the
|
||||
resources.
|
||||
@@ -261,6 +288,10 @@ resources.
|
||||
delete it. To avoid this edge case, it is recommended to perform a sync operation on your Applications, even if
|
||||
they are not out of sync, so that orphan resource detection will work as expected on the next sync.
|
||||
|
||||
After upgrading to version 3.0, the Argo CD tracking annotation will only appear on an Application’s resources when
|
||||
either a new Git commit is made or the Application is explicitly synced.
|
||||
|
||||
##### Users who rely on label-based for resources that are not managed by Argo CD
|
||||
Some users rely on label-based tracking to track resources that are not managed by Argo CD. They may set annotations
|
||||
to have Argo CD ignore the resource as extraneous or to disable pruning. If you are using label-based tracking to track
|
||||
resources that are not managed by Argo CD, you will need to construct tracking annotations instead of tracking labels
|
||||
@@ -464,3 +495,9 @@ resource.customizations.ignoreDifferences.apiextensions.k8s.io_CustomResourceDef
|
||||
```
|
||||
|
||||
More details for ignored resource updates in the [Diffing customization](../../user-guide/diffing.md) documentation.
|
||||
|
||||
### Sanitized project API response
|
||||
|
||||
Due to security reasons ([GHSA-786q-9hcg-v9ff](https://github.com/argoproj/argo-cd/security/advisories/GHSA-786q-9hcg-v9ff)),
|
||||
the project API response was sanitized to remove sensitive information. This includes
|
||||
credentials of project-scoped repositories and clusters.
|
||||
|
||||
@@ -1,25 +1,33 @@
|
||||
# v3.0 to 3.1
|
||||
|
||||
## No more KubeVersions variable modification
|
||||
|
||||
Until v3.0, Argo CD removed `+` identifier from `kubeVersions` in Helm, Kustomize and Plugins. For example, if Argo CD receive `kubeVersions` as vX.Y.Z+, we convert to vX.Y.Z internally. Starting with v3.1, the internal conversation is entirely removed.
|
||||
|
||||
### Detection
|
||||
|
||||
To detect if you are affected, check the `kubeVersions` you are using. If you use `kubeVersions` including `+` identifier, the application must be failed when you upgrade from v3.0 to v3.1.
|
||||
|
||||
### Remediation
|
||||
|
||||
The plus symbol was originally removed [because Helm did not support it](https://github.com/argoproj/argo-cd/issues/2303). Helm no longer enforces this restriction, so apps should work fine even if your kubeVersions include `+`.
|
||||
|
||||
However, since Argo CD now sends unmodified kubeVersions to Helm, the generated manifests may differ due to the changed kubeVersions. For apps which require extra caution, it may be advisable to disable auto-sync, upgrade, check any diffs, and then reenable auto-sync.
|
||||
|
||||
## Symlink protection in API `--staticassets` directory
|
||||
|
||||
The `--staticassets` directory in the API server (`/app/shared` by default) is now protected against out-of-bounds
|
||||
symlinks. This is to help protect against symlink attacks. If you have any symlinks in your `--staticassets` directory
|
||||
to a location outside the directory, they will return a 500 error starting with 3.1.
|
||||
|
||||
## v1 Actions API Deprecated
|
||||
|
||||
The `/api/v1/applications/{name}/resource/actions` endpoint is deprecated in favor of `/api/v1/applications/{name}/resource/actions/v2`.
|
||||
|
||||
This endpoint allows API users to run a custom resource action on a specific resource in an application.
|
||||
|
||||
The old endpoint accepted various parameters as query parameters. The POST body was the action name.
|
||||
|
||||
The new endpoint accepts all parameters as part of the POST body as a JSON object. The new endpoint also supports a new
|
||||
`resourceActionParameters` field to parameterize action runs.
|
||||
|
||||
The old endpoint will be removed in a future release, so users should migrate to the new endpoint as soon as possible.
|
||||
API clients will just need to change the endpoint URL and switch query string parameters to a JSON body.
|
||||
|
||||
If the old endpoint is used, the API will log a warning message:
|
||||
|
||||
> RunResourceAction was called. RunResourceAction is deprecated and will be removed in a future release. Use RunResourceActionV2 instead.
|
||||
|
||||
The CLI will fall back to the old endpoint if the new one is not available. If it falls back, it will log a warning message:
|
||||
|
||||
> RunResourceActionV2 is not supported by the server, falling back to RunResourceAction.
|
||||
|
||||
## OpenID Connect authorization code flow with PKCE is now handled by the server instead of the UI
|
||||
|
||||
Previously, when PKCE was enabled, the authorization code flow (the process which happens when you log in to Argo CD using OpenID Connect) was handled by the UI, whereas this flow was handled by the server if PKCE was not enabled. The server now always handles this flow, PKCE being enabled or not.
|
||||
@@ -37,3 +45,21 @@ If it returns `"enablePKCEAuthentication": true`, then PKCE is used.
|
||||
### Remediation
|
||||
|
||||
On your identity provider, ensure that the OIDC client used for Argo CD has the `/auth/callback` endpoint of your Argo CD URL (e.g. https://argocd.example.com/auth/callback) in the redirect URIs.
|
||||
|
||||
## Helm Upgraded to 3.18.4
|
||||
|
||||
Argo CD v3.1 upgrades the bundled Helm version to 3.18.4. There are no breaking changes in Helm 3.18 according to the
|
||||
[release notes](https://github.com/helm/helm/releases/tag/v3.18.0).
|
||||
|
||||
## Kustomize Upgraded to 5.7.0
|
||||
|
||||
Argo CD v3.1 upgrades the bundled Kustomize version to 5.7.0. There are no breaking changes in Kustomize 5.7 according
|
||||
to the [release notes](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv5.7.0).
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
## Sanitized project API response
|
||||
|
||||
Due to security reasons ([GHSA-786q-9hcg-v9ff](https://github.com/argoproj/argo-cd/security/advisories/GHSA-786q-9hcg-v9ff)),
|
||||
the project API response was sanitized to remove sensitive information. This includes
|
||||
credentials of project-scoped repositories and clusters.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[Custom tools](../operator-manual/config-management-plugins.md), [Helm](helm.md), [Jsonnet](jsonnet.md), and [Kustomize](kustomize.md) support the following build env vars:
|
||||
|
||||
| Variable | Description |
|
||||
|-------------------------------------|-------------------------------------------------------------------------|
|
||||
| ----------------------------------- | ----------------------------------------------------------------------- |
|
||||
| `ARGOCD_APP_NAME` | The name of the application. |
|
||||
| `ARGOCD_APP_NAMESPACE` | The destination namespace of the application. |
|
||||
| `ARGOCD_APP_PROJECT_NAME` | The name of the project the application belongs to. |
|
||||
@@ -13,7 +13,7 @@
|
||||
| `ARGOCD_APP_SOURCE_PATH` | The path of the app within the source repo. |
|
||||
| `ARGOCD_APP_SOURCE_REPO_URL` | The source repo URL. |
|
||||
| `ARGOCD_APP_SOURCE_TARGET_REVISION` | The target revision from the spec, e.g. `master`. |
|
||||
| `KUBE_VERSION` | The version of Kubernetes. |
|
||||
| `KUBE_VERSION` | The semantic version of Kubernetes without trailing metadata. |
|
||||
| `KUBE_API_VERSIONS` | The version of the Kubernetes API. |
|
||||
|
||||
In case you don't want a variable to be interpolated, `$` can be escaped via `$$`.
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
# Scale Resources in ArgoCD UI
|
||||
|
||||
This enables users to scale resources directly from the ArgoCD UI. Users will be able to increase or decrease the number of replicas (Pods) for Deployments and StatefulSets by using an input field. The feature aims to enhance user experience, especially for non-technical users, by eliminating the need to modify configuration files or use kubectl commands for scaling.
|
||||
# Scale Resources in Argo CD UI
|
||||
|
||||
This enables users to scale resources directly from the Argo CD UI. Users will be able to increase or decrease the number of replicas (Pods) for Deployments and StatefulSets by using an input field. The feature aims to enhance user experience, especially for non-technical users, by eliminating the need to modify configuration files or use kubectl commands for scaling.
|
||||
|
||||
## Example Usage
|
||||
1. User navigates to a Deployment or StatefulSet in any ArgoCD application.
|
||||
1. User navigates to a Deployment or StatefulSet in any Argo CD application.
|
||||
2. User clicks on the Actions dropdown and selects "Scale".
|
||||

|
||||
3. A modal pops up showing an input field `Enter input parameters for action: scale` with the current number of Pods.
|
||||
@@ -13,10 +12,9 @@ This enables users to scale resources directly from the ArgoCD UI. Users will be
|
||||
5. User presses OK, and the resource is scaled accordingly.
|
||||

|
||||
|
||||
|
||||
!!! note
|
||||
This feature will only apply to `Deployments`, and `StatefulSets`.
|
||||
|
||||
!!! note
|
||||
If you use HPA (Horizontal Pod Autoscaling) or enabled ArgoCD auto-sync, changing the replica count in scale actions would be overwritten.
|
||||
If you use HPA (Horizontal Pod Autoscaling) or enabled Argo CD auto-sync, changing the replica count in scale actions would be overwritten.
|
||||
Ensure that invalid values (e.g., `non-numeric` characters, `negative` numbers, or values beyond the `max integer limit`) cannot be entered.
|
||||
|
||||
@@ -188,7 +188,7 @@ git commit -m "Bump image to v1.2.3" \
|
||||
```
|
||||
|
||||
!!!note Newlines are not allowed
|
||||
The commit trailers must not contain newlines. The
|
||||
The commit trailers must not contain newlines.
|
||||
|
||||
So the full CI script might look something like this:
|
||||
|
||||
@@ -230,6 +230,12 @@ The commit metadata will appear in the hydrated commit's root hydrator.metadata
|
||||
|
||||
```json
|
||||
{
|
||||
"author": "CI <ci@example.com>",
|
||||
"subject": "chore: bump image to b82add2",
|
||||
"date": "2025-06-09T13:50:08-04:00",
|
||||
"body": "Signed-off-by: CI <ci@example.com>\n",
|
||||
"drySha": "6cb951525937865dced818bbdd78c89b2d2b3045",
|
||||
"repoURL": "https://git.example.com/owner/manifests-repo",
|
||||
"references": [
|
||||
{
|
||||
"commit": {
|
||||
@@ -248,6 +254,10 @@ The commit metadata will appear in the hydrated commit's root hydrator.metadata
|
||||
}
|
||||
```
|
||||
|
||||
The top-level "body" field contains the commit message of the DRY commit minus the subject line and any
|
||||
`Argocd-reference-commit-*` trailers that were used in `references`. Unrecognized or invalid trailers are preserved in
|
||||
the body.
|
||||
|
||||
Although `references` is an array, the source hydrator currently only supports a single related commit. If a trailer is
|
||||
specified more than once, the last one will be used.
|
||||
|
||||
|
||||
28
go.mod
28
go.mod
@@ -1,6 +1,6 @@
|
||||
module github.com/argoproj/argo-cd/v3
|
||||
|
||||
go 1.24.4
|
||||
go 1.24.6
|
||||
|
||||
require (
|
||||
code.gitea.io/sdk/gitea v0.21.0
|
||||
@@ -12,7 +12,7 @@ require (
|
||||
github.com/Masterminds/sprig/v3 v3.3.0
|
||||
github.com/TomOnTime/utfutil v1.0.0
|
||||
github.com/alicebob/miniredis/v2 v2.35.0
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20250617174952-093aef0dad58
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20250905160054-e48120133eec
|
||||
github.com/argoproj/notifications-engine v0.4.1-0.20250309174002-87bf0576a872
|
||||
github.com/argoproj/pkg v0.13.6
|
||||
github.com/argoproj/pkg/v2 v2.0.1
|
||||
@@ -29,12 +29,13 @@ require (
|
||||
github.com/dlclark/regexp2 v1.11.5
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
github.com/evanphx/json-patch v5.9.11+incompatible
|
||||
github.com/expr-lang/expr v1.17.5
|
||||
github.com/expr-lang/expr v1.17.7
|
||||
github.com/felixge/httpsnoop v1.0.4
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
github.com/gfleury/go-bitbucket-v1 v0.0.0-20240917142304-df385efaac68
|
||||
github.com/go-git/go-git/v5 v5.16.2
|
||||
github.com/go-jose/go-jose/v4 v4.1.0
|
||||
// DO NOT BUMP UNTIL go-git/go-git#1551 is fixed
|
||||
github.com/go-git/go-git/v5 v5.14.0
|
||||
github.com/go-jose/go-jose/v4 v4.1.2
|
||||
github.com/go-logr/logr v1.4.3
|
||||
github.com/go-openapi/loads v0.22.0
|
||||
github.com/go-openapi/runtime v0.28.0
|
||||
@@ -91,11 +92,11 @@ require (
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0
|
||||
go.opentelemetry.io/otel/sdk v1.36.0
|
||||
go.uber.org/automaxprocs v1.6.0
|
||||
golang.org/x/crypto v0.39.0
|
||||
golang.org/x/net v0.41.0
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/net v0.47.0
|
||||
golang.org/x/oauth2 v0.30.0
|
||||
golang.org/x/sync v0.15.0
|
||||
golang.org/x/term v0.32.0
|
||||
golang.org/x/sync v0.19.0
|
||||
golang.org/x/term v0.38.0
|
||||
golang.org/x/time v0.12.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237
|
||||
google.golang.org/grpc v1.73.0
|
||||
@@ -265,10 +266,11 @@ require (
|
||||
go.opentelemetry.io/otel/metric v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.36.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.6.0 // indirect
|
||||
golang.org/x/mod v0.25.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/text v0.26.0 // indirect
|
||||
golang.org/x/tools v0.33.0 // indirect
|
||||
golang.org/x/mod v0.30.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
golang.org/x/tools v0.39.0 // indirect
|
||||
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect
|
||||
gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
gomodules.xyz/notify v0.1.1 // indirect
|
||||
|
||||
52
go.sum
52
go.sum
@@ -113,8 +113,8 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE=
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20250617174952-093aef0dad58 h1:9ESamu44v3dR9j/I4/4Aa1Fx3QSIE8ElK1CR8Z285uk=
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20250617174952-093aef0dad58/go.mod h1:aIBEG3ohgaC1gh/sw2On6knkSnXkqRLDoBj234Dqczw=
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20250905160054-e48120133eec h1:rNAwbRQFvRIuW/e2bU+B10mlzghYXsnwZedYeA7Drz4=
|
||||
github.com/argoproj/gitops-engine v0.7.1-0.20250905160054-e48120133eec/go.mod h1:aIBEG3ohgaC1gh/sw2On6knkSnXkqRLDoBj234Dqczw=
|
||||
github.com/argoproj/notifications-engine v0.4.1-0.20250309174002-87bf0576a872 h1:ADGAdyN9ty0+RmTT/yn+xV9vwkqvLn9O1ccqeP0Zeas=
|
||||
github.com/argoproj/notifications-engine v0.4.1-0.20250309174002-87bf0576a872/go.mod h1:d1RazGXWvKRFv9//rg4MRRR7rbvbE7XLgTSMT5fITTE=
|
||||
github.com/argoproj/pkg v0.13.6 h1:36WPD9MNYECHcO1/R1pj6teYspiK7uMQLCgLGft2abM=
|
||||
@@ -257,8 +257,8 @@ github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjT
|
||||
github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=
|
||||
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4=
|
||||
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc=
|
||||
github.com/expr-lang/expr v1.17.5 h1:i1WrMvcdLF249nSNlpQZN1S6NXuW9WaOfF5tPi3aw3k=
|
||||
github.com/expr-lang/expr v1.17.5/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
|
||||
github.com/expr-lang/expr v1.17.7 h1:Q0xY/e/2aCIp8g9s/LGvMDCC5PxYlvHgDZRQ4y16JX8=
|
||||
github.com/expr-lang/expr v1.17.7/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
|
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
|
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
|
||||
@@ -301,13 +301,13 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN
|
||||
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||
github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
|
||||
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
||||
github.com/go-git/go-git/v5 v5.14.0 h1:/MD3lCrGjCen5WfEAzKg00MJJffKhC8gzS80ycmCi60=
|
||||
github.com/go-git/go-git/v5 v5.14.0/go.mod h1:Z5Xhoia5PcWA3NF8vRLURn9E5FRhSl7dGj9ItW3Wk5k=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-jose/go-jose/v4 v4.1.0 h1:cYSYxd3pw5zd2FSXk2vGdn9igQU2PS8MuxrCOCl0FdY=
|
||||
github.com/go-jose/go-jose/v4 v4.1.0/go.mod h1:GG/vqmYm3Von2nYiB2vGTXzdoNKE5tix5tuc6iAd+sw=
|
||||
github.com/go-jose/go-jose/v4 v4.1.2 h1:TK/7NqRQZfgAh+Td8AlsrvtPoUyiHh0LqVvokh+1vHI=
|
||||
github.com/go-jose/go-jose/v4 v4.1.2/go.mod h1:22cg9HWM1pOlnRiY+9cQYJ9XHmya1bYW8OeDM6Ku6Oo=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
@@ -977,8 +977,8 @@ golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/
|
||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
||||
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -1026,8 +1026,8 @@ golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
|
||||
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
|
||||
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -1095,8 +1095,8 @@ golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -1126,8 +1126,8 @@ golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
||||
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -1210,8 +1210,8 @@ golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
@@ -1239,8 +1239,8 @@ golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
|
||||
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
|
||||
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
|
||||
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
|
||||
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
|
||||
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
|
||||
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -1263,8 +1263,8 @@ golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -1335,8 +1335,12 @@ golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c
|
||||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
|
||||
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
|
||||
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
|
||||
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
||||
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
||||
golang.org/x/tools/go/expect v0.1.0-deprecated h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY=
|
||||
golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
|
||||
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=
|
||||
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Usage: ./add-helm-checksums.sh 3.9.4 # use the desired version
|
||||
# Usage: ./add-helm-checksums.sh <helm-version> # use the desired version e.g. 3.18.4
|
||||
|
||||
set -e
|
||||
|
||||
for arch in amd64 arm64 ppc64le s390x; do
|
||||
wget "https://get.helm.sh/helm-v$1-linux-$arch.tar.gz.sha256sum" -O "helm-v$1-linux-$arch.tar.gz.sha256"
|
||||
checksumfile="helm-v$1-linux-$arch.tar.gz.sha256"
|
||||
wget "https://get.helm.sh/helm-v$1-linux-$arch.tar.gz.sha256sum" -O "$checksumfile"
|
||||
outname="$(git rev-parse --show-toplevel)/hack/installers/checksums/helm-v$1-linux-$arch.tar.gz.sha256"
|
||||
mv $checksumfile $outname
|
||||
done
|
||||
|
||||
for arch in amd64 arm64; do
|
||||
wget "https://get.helm.sh/helm-v$1-darwin-$arch.tar.gz.sha256sum" -O "helm-v$1-darwin-$arch.tar.gz.sha256"
|
||||
checksumfile="helm-v$1-darwin-$arch.tar.gz.sha256"
|
||||
wget "https://get.helm.sh/helm-v$1-darwin-$arch.tar.gz.sha256sum" -O "$checksumfile"
|
||||
outname="$(git rev-parse --show-toplevel)/hack/installers/checksums/helm-v$1-darwin-$arch.tar.gz.sha256"
|
||||
mv $checksumfile $outname
|
||||
done
|
||||
@@ -0,0 +1 @@
|
||||
d186851d40b1999c5d75696bc0b754e4d29e860c8d0cf4c132ac1b1940c5cffc helm-v3.18.3-darwin-amd64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
3fe3e9739ab3c75d88bfe13e464a79a2a7a804fc692c3258fa6a9d185d53e377 helm-v3.18.3-darwin-arm64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
6ec85f306dd8fe9eb05c61ba4593182b2afcfefb52f21add3fe043ebbdc48e39 helm-v3.18.3-linux-amd64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
3382ebdc6d6e027371551a63fc6e0a3073a1aec1061e346692932da61cfd8d24 helm-v3.18.3-linux-arm64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
ca5ab0bb205488276095881f04b72bfed5c0ddb92f715940dde6a7ccae72818c helm-v3.18.3-linux-ppc64le.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
be261f040b59c04ad4f1ce6fc2f976e500167475cadb468bf78cb9772300fb5d helm-v3.18.3-linux-s390x.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
860a7238285b44b5dc7b3c4dad6194316885d7015d77c34e23177e0e9554af8f helm-v3.18.4-darwin-amd64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
041849741550b20710d7ad0956e805ebd960b483fe978864f8e7fdd03ca84ec8 helm-v3.18.4-darwin-arm64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
f8180838c23d7c7d797b208861fecb591d9ce1690d8704ed1e4cb8e2add966c1 helm-v3.18.4-linux-amd64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
c0a45e67eef0c7416a8a8c9e9d5d2d30d70e4f4d3f7bea5de28241fffa8f3b89 helm-v3.18.4-linux-arm64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
dbd74c59e7710f26e058596723abbf73662b553e01f40dfb08508ffffaeb7b81 helm-v3.18.4-linux-ppc64le.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
c8bafb34bcebd53494f0223239977e1ff7b487e714598a5843a0cb1788e20075 helm-v3.18.4-linux-s390x.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
277a7401f969ce3945e8f0ff8b0cce6f4353854db1ff89ba070001e3246e7f22 kustomize_5.7.0_darwin_amd64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
c0dac68dc7870e1f673ae4d8fb554df971e0b9b9f0affc4be4c0852f62d0796e kustomize_5.7.0_darwin_arm64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
0d98f06d6d2c2c0ff8923cc136a517af74aaa187f1b9f3e17ff370d0625ede84 kustomize_5.7.0_linux_amd64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
744bb1bc1854b6634dea9eaf6db2f401a734ed25d6837baa6f91157d79c27d5e kustomize_5.7.0_linux_arm64.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
752e750d5f349156ea228ae01cf57be22e6cc29f0f05748a1bca7fa870393561 kustomize_5.7.0_linux_ppc64le.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
64898beb154a111c1a98f8cff066fdfa866c4c73505e9a9b5fa6ec39f0292558 kustomize_5.7.0_linux_s390x.tar.gz
|
||||
@@ -6,20 +6,20 @@ SRCROOT="$( CDPATH='' cd -- "$(dirname "$0")/../.." && pwd -P )"
|
||||
# This script installs all our golang-based codegen utility CLIs necessary for codegen.
|
||||
# Some dependencies are vendored in go.mod (ones which are actually imported in our codebase).
|
||||
# Other dependencies are only used as a CLI and do not need vendoring in go.mod (doing so adds
|
||||
# unecessary dependencies to go.mod). We want to maintain a single source of truth for versioning
|
||||
# unnecessary dependencies to go.mod). We want to maintain a single source of truth for versioning
|
||||
# our binaries (either go.mod or go install <pkg>@<version>), so we use two techniques to install
|
||||
# our CLIs:
|
||||
# 1. For CLIs which are NOT vendored in go.mod, we can run `go install <pkg>@<version>` with an explicit version
|
||||
# 2. For packages which we *do* vendor in go.mod, we determine version from go.mod followed by `go install` with that version
|
||||
go_mod_install() {
|
||||
module=$(go list -f '{{.Module}}' $1 | awk '{print $1}')
|
||||
module_version=$(go list -m $module | awk '{print $NF}' | head -1)
|
||||
go install $1@$module_version
|
||||
module=$(go list -f '{{.Module}}' "$1" | awk '{print $1}')
|
||||
module_version=$(go list -m "$module" | awk '{print $NF}' | head -1)
|
||||
go install "$1@$module_version"
|
||||
}
|
||||
|
||||
# All binaries are compiled into the argo-cd/dist directory, which is added to the PATH during codegen
|
||||
export GOBIN="${SRCROOT}/dist"
|
||||
mkdir -p $GOBIN
|
||||
mkdir -p "$GOBIN"
|
||||
|
||||
# protoc-gen-go* is used to generate <service>.pb.go from .proto files
|
||||
# go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.0
|
||||
@@ -41,8 +41,9 @@ go_mod_install k8s.io/code-generator/cmd/defaulter-gen
|
||||
go_mod_install k8s.io/code-generator/cmd/informer-gen
|
||||
go_mod_install k8s.io/code-generator/cmd/lister-gen
|
||||
|
||||
# We still install openapi-gen from go.mod since upstream does not utilize release tags
|
||||
go_mod_install k8s.io/kube-openapi/cmd/openapi-gen
|
||||
# We still install openapi-gen from go.mod since upstream does not utilize release tags. Use go install in order for
|
||||
# replace directives to be respected.
|
||||
go install k8s.io/kube-openapi/cmd/openapi-gen
|
||||
|
||||
# controller-gen is run by ./hack/gen-crd-spec to generate the CRDs
|
||||
go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.18.0
|
||||
@@ -51,7 +52,7 @@ go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.18.0
|
||||
go install github.com/go-swagger/go-swagger/cmd/swagger@v0.28.0
|
||||
|
||||
# goimports is used to auto-format generated code
|
||||
go install golang.org/x/tools/cmd/goimports@v0.1.8
|
||||
go install golang.org/x/tools/cmd/goimports@v0.35.0
|
||||
|
||||
# mockery is used to generate mock
|
||||
go install github.com/vektra/mockery/v3@v3.3.6
|
||||
@@ -2,6 +2,6 @@
|
||||
set -eux -o pipefail
|
||||
|
||||
# renovate: datasource=go packageName=github.com/golangci/golangci-lint
|
||||
GOLANGCI_LINT_VERSION=2.1.6
|
||||
GOLANGCI_LINT_VERSION=2.8.0
|
||||
|
||||
GO111MODULE=on go install "github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v${GOLANGCI_LINT_VERSION}"
|
||||
GO111MODULE=on go install "github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v${GOLANGCI_LINT_VERSION}"
|
||||
@@ -11,7 +11,7 @@
|
||||
# Use ./hack/installers/checksums/add-helm-checksums.sh and
|
||||
# add-kustomize-checksums.sh to help download checksums.
|
||||
###############################################################################
|
||||
helm3_version=3.17.1
|
||||
kustomize5_version=5.6.0
|
||||
helm3_version=3.18.4
|
||||
kustomize5_version=5.7.0
|
||||
protoc_version=29.3
|
||||
oras_version=1.2.0
|
||||
|
||||
@@ -3,25 +3,22 @@
|
||||
out="| Argo CD version | Kubernetes versions |\n"
|
||||
out+="|-----------------|---------------------|\n"
|
||||
|
||||
argocd_minor_version=$(git rev-parse --abbrev-ref HEAD | sed 's/release-//')
|
||||
argocd_major_version_num=$(echo "$argocd_minor_version" | sed -E 's/\.[0-9]+//')
|
||||
argocd_minor_version_num=$(echo "$argocd_minor_version" | sed -E 's/[0-9]+\.//')
|
||||
argocd_current_version=$(git rev-parse --abbrev-ref HEAD | sed 's/release-//')
|
||||
argocd_major_version_num=$(echo "$argocd_current_version" | sed -E 's/\.[0-9]+//')
|
||||
argocd_minor_version_num=$(echo "$argocd_current_version" | sed -E 's/[0-9]+\.//')
|
||||
|
||||
minor_version_decrement=0
|
||||
for _ in {1..3}; do
|
||||
minor_version_num=$((argocd_minor_version_num - minor_version_decrement))
|
||||
minor_version="${argocd_major_version_num}.${minor_version_num}"
|
||||
git checkout "release-$minor_version" > /dev/null || exit 1
|
||||
argocd_version="${argocd_major_version_num}.${argocd_minor_version_num}"
|
||||
git checkout "release-$argocd_version" > /dev/null || exit 1
|
||||
|
||||
line=$(yq '.jobs["test-e2e"].strategy.matrix |
|
||||
# k3s-version was an array prior to 2.12. This checks for the old format first and then falls back to the new format.
|
||||
(.["k3s-version"] // (.k3s | map(.version))) |
|
||||
.[]' .github/workflows/ci-build.yaml | \
|
||||
jq --arg minor_version "$minor_version" --raw-input --slurp --raw-output \
|
||||
'split("\n")[:-1] | map(sub("\\.[0-9]+$"; "")) | join(", ") | "| \($minor_version) | \(.) |"')
|
||||
jq --arg argocd_version "$argocd_version" --raw-input --slurp --raw-output \
|
||||
'split("\n")[:-1] | map(sub("\\.[0-9]+$"; "")) | join(", ") | "| \($argocd_version) | \(.) |"')
|
||||
out+="$line\n"
|
||||
|
||||
minor_version_decrement=$((minor_version_decrement + 1))
|
||||
|
||||
# If we're at minor version 0, there's no further version back in this series. Instead, move to the latest version in
|
||||
# the previous major release series.
|
||||
@@ -29,13 +26,11 @@ for _ in {1..3}; do
|
||||
argocd_major_version_num=$((argocd_major_version_num - 1))
|
||||
# Get the latest minor version in the previous series.
|
||||
argocd_minor_version_num=$(git tag -l "v$argocd_major_version_num.*" | sort -V | tail -n 1 | sed -E 's/\.[0-9]+$//' | sed -E 's/^v[0-9]+\.//')
|
||||
|
||||
# Don't decrement the minor version, since we're switching to the previous major release series. We want the latest
|
||||
# minor version in that series.
|
||||
minor_version_decrement=0
|
||||
else
|
||||
argocd_minor_version_num=$((argocd_minor_version_num - 1))
|
||||
fi
|
||||
done
|
||||
|
||||
git checkout "release-$argocd_minor_version"
|
||||
git checkout "release-$argocd_current_version"
|
||||
|
||||
printf "$out" > docs/operator-manual/tested-kubernetes-versions.md
|
||||
|
||||
@@ -253,6 +253,12 @@ spec:
|
||||
name: argocd-cmd-params-cm
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: argocd-cmd-params-cm
|
||||
key: commit.server
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
|
||||
@@ -268,6 +268,12 @@ spec:
|
||||
name: argocd-cmd-params-cm
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: argocd-cmd-params-cm
|
||||
key: commit.server
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
|
||||
@@ -187,6 +187,12 @@ spec:
|
||||
name: argocd-cmd-params-cm
|
||||
key: applicationsetcontroller.requeue.after
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATIONSET_CONTROLLER_MAX_RESOURCES_STATUS_COUNT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: argocd-cmd-params-cm
|
||||
key: applicationsetcontroller.status.max.resources.count
|
||||
optional: true
|
||||
volumeMounts:
|
||||
- mountPath: /app/config/ssh
|
||||
name: ssh-known-hosts
|
||||
|
||||
@@ -12,4 +12,4 @@ resources:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v3.1.12
|
||||
|
||||
@@ -5,7 +5,7 @@ kind: Kustomization
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v3.1.12
|
||||
resources:
|
||||
- ./application-controller
|
||||
- ./dex
|
||||
|
||||
@@ -40,7 +40,7 @@ spec:
|
||||
serviceAccountName: argocd-redis
|
||||
containers:
|
||||
- name: redis
|
||||
image: redis:7.2.7-alpine
|
||||
image: redis:7.2.11-alpine
|
||||
imagePullPolicy: Always
|
||||
args:
|
||||
- "--save"
|
||||
|
||||
@@ -197,6 +197,24 @@ spec:
|
||||
name: argocd-cmd-params-cm
|
||||
key: reposerver.disable.helm.manifest.max.extracted.size
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_OCI_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.oci.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_DISABLE_OCI_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.disable.oci.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_OCI_LAYER_MEDIA_TYPES
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.oci.layer.media.types
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REVISION_CACHE_LOCK_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
|
||||
44
manifests/core-install-with-hydrator.yaml
generated
44
manifests/core-install-with-hydrator.yaml
generated
@@ -24699,7 +24699,13 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
- name: ARGOCD_APPLICATIONSET_CONTROLLER_MAX_RESOURCES_STATUS_COUNT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: applicationsetcontroller.status.max.resources.count
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -24825,7 +24831,7 @@ spec:
|
||||
key: log.format.timestamp
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -24937,7 +24943,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: Always
|
||||
name: redis
|
||||
ports:
|
||||
@@ -24953,7 +24959,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -25184,6 +25190,24 @@ spec:
|
||||
key: reposerver.disable.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_OCI_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.oci.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_DISABLE_OCI_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.disable.oci.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_OCI_LAYER_MEDIA_TYPES
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.oci.layer.media.types
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REVISION_CACHE_LOCK_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -25226,7 +25250,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25278,7 +25302,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -25612,9 +25636,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
42
manifests/core-install.yaml
generated
42
manifests/core-install.yaml
generated
@@ -24667,7 +24667,13 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
- name: ARGOCD_APPLICATIONSET_CONTROLLER_MAX_RESOURCES_STATUS_COUNT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: applicationsetcontroller.status.max.resources.count
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -24771,7 +24777,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: Always
|
||||
name: redis
|
||||
ports:
|
||||
@@ -24787,7 +24793,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -25018,6 +25024,24 @@ spec:
|
||||
key: reposerver.disable.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_OCI_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.oci.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_DISABLE_OCI_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.disable.oci.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_OCI_LAYER_MEDIA_TYPES
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.oci.layer.media.types
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REVISION_CACHE_LOCK_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -25060,7 +25084,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -25112,7 +25136,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -25446,9 +25470,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
|
||||
@@ -12,4 +12,4 @@ resources:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v3.1.12
|
||||
|
||||
@@ -12,7 +12,7 @@ patches:
|
||||
images:
|
||||
- name: quay.io/argoproj/argocd
|
||||
newName: quay.io/argoproj/argocd
|
||||
newTag: latest
|
||||
newTag: v3.1.12
|
||||
resources:
|
||||
- ../../base/application-controller
|
||||
- ../../base/applicationset-controller
|
||||
|
||||
@@ -1250,7 +1250,7 @@ spec:
|
||||
automountServiceAccountToken: false
|
||||
initContainers:
|
||||
- name: config-init
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
resources:
|
||||
{}
|
||||
@@ -1290,7 +1290,7 @@ spec:
|
||||
|
||||
containers:
|
||||
- name: redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- redis-server
|
||||
@@ -1364,7 +1364,7 @@ spec:
|
||||
- /bin/sh
|
||||
- /readonly-config/trigger-failover-if-master.sh
|
||||
- name: sentinel
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- redis-sentinel
|
||||
@@ -1437,7 +1437,7 @@ spec:
|
||||
- sleep 30; redis-cli -p 26379 sentinel reset argocd
|
||||
|
||||
- name: split-brain-fix
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- sh
|
||||
|
||||
@@ -27,7 +27,7 @@ redis-ha:
|
||||
serviceAccount:
|
||||
automountToken: true
|
||||
image:
|
||||
tag: 7.2.7-alpine
|
||||
tag: 7.2.11-alpine
|
||||
sentinel:
|
||||
bind: '0.0.0.0'
|
||||
lifecycle:
|
||||
|
||||
56
manifests/ha/install-with-hydrator.yaml
generated
56
manifests/ha/install-with-hydrator.yaml
generated
@@ -26065,7 +26065,13 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
- name: ARGOCD_APPLICATIONSET_CONTROLLER_MAX_RESOURCES_STATUS_COUNT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: applicationsetcontroller.status.max.resources.count
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -26191,7 +26197,7 @@ spec:
|
||||
key: log.format.timestamp
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -26342,7 +26348,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -26438,7 +26444,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -26562,7 +26568,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -26819,6 +26825,24 @@ spec:
|
||||
key: reposerver.disable.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_OCI_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.oci.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_DISABLE_OCI_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.disable.oci.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_OCI_LAYER_MEDIA_TYPES
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.oci.layer.media.types
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REVISION_CACHE_LOCK_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -26861,7 +26885,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -26913,7 +26937,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -27287,7 +27311,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -27657,9 +27681,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
@@ -27757,7 +27787,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle:
|
||||
preStop:
|
||||
@@ -27828,7 +27858,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle:
|
||||
postStart:
|
||||
@@ -27903,7 +27933,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: split-brain-fix
|
||||
resources: {}
|
||||
@@ -27938,7 +27968,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: config-init
|
||||
securityContext:
|
||||
|
||||
54
manifests/ha/install.yaml
generated
54
manifests/ha/install.yaml
generated
@@ -26035,7 +26035,13 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
- name: ARGOCD_APPLICATIONSET_CONTROLLER_MAX_RESOURCES_STATUS_COUNT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: applicationsetcontroller.status.max.resources.count
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -26178,7 +26184,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -26274,7 +26280,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -26398,7 +26404,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -26655,6 +26661,24 @@ spec:
|
||||
key: reposerver.disable.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_OCI_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.oci.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_DISABLE_OCI_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.disable.oci.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_OCI_LAYER_MEDIA_TYPES
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.oci.layer.media.types
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REVISION_CACHE_LOCK_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -26697,7 +26721,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -26749,7 +26773,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -27123,7 +27147,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -27493,9 +27517,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
@@ -27593,7 +27623,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle:
|
||||
preStop:
|
||||
@@ -27664,7 +27694,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle:
|
||||
postStart:
|
||||
@@ -27739,7 +27769,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: split-brain-fix
|
||||
resources: {}
|
||||
@@ -27774,7 +27804,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: config-init
|
||||
securityContext:
|
||||
|
||||
56
manifests/ha/namespace-install-with-hydrator.yaml
generated
56
manifests/ha/namespace-install-with-hydrator.yaml
generated
@@ -1868,7 +1868,13 @@ spec:
|
||||
key: applicationsetcontroller.requeue.after
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
- name: ARGOCD_APPLICATIONSET_CONTROLLER_MAX_RESOURCES_STATUS_COUNT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: applicationsetcontroller.status.max.resources.count
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
name: argocd-applicationset-controller
|
||||
ports:
|
||||
@@ -1994,7 +2000,7 @@ spec:
|
||||
key: log.format.timestamp
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -2145,7 +2151,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /shared/argocd-dex
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
name: copyutil
|
||||
securityContext:
|
||||
@@ -2241,7 +2247,7 @@ spec:
|
||||
key: notificationscontroller.repo.server.plaintext
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
@@ -2365,7 +2371,7 @@ spec:
|
||||
- argocd
|
||||
- admin
|
||||
- redis-initial-password
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: secret-init
|
||||
securityContext:
|
||||
@@ -2622,6 +2628,24 @@ spec:
|
||||
key: reposerver.disable.helm.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_OCI_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.oci.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_DISABLE_OCI_MANIFEST_MAX_EXTRACTED_SIZE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.disable.oci.manifest.max.extracted.size
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REPO_SERVER_OCI_LAYER_MEDIA_TYPES
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: reposerver.oci.layer.media.types
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_REVISION_CACHE_LOCK_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
@@ -2664,7 +2688,7 @@ spec:
|
||||
value: /helm-working-dir
|
||||
- name: HELM_DATA_HOME
|
||||
value: /helm-working-dir
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
@@ -2716,7 +2740,7 @@ spec:
|
||||
- -n
|
||||
- /usr/local/bin/argocd
|
||||
- /var/run/argocd/argocd-cmp-server
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
name: copyutil
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@@ -3090,7 +3114,7 @@ spec:
|
||||
key: server.sync.replace.allowed
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -3460,9 +3484,15 @@ spec:
|
||||
key: controller.cluster.cache.events.processing.interval
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: commit.server
|
||||
name: argocd-cmd-params-cm
|
||||
optional: true
|
||||
- name: KUBECACHEDIR
|
||||
value: /tmp/kubecache
|
||||
image: quay.io/argoproj/argocd:latest
|
||||
image: quay.io/argoproj/argocd:v3.1.12
|
||||
imagePullPolicy: Always
|
||||
name: argocd-application-controller
|
||||
ports:
|
||||
@@ -3560,7 +3590,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle:
|
||||
preStop:
|
||||
@@ -3631,7 +3661,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle:
|
||||
postStart:
|
||||
@@ -3706,7 +3736,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: split-brain-fix
|
||||
resources: {}
|
||||
@@ -3741,7 +3771,7 @@ spec:
|
||||
secretKeyRef:
|
||||
key: auth
|
||||
name: argocd-redis
|
||||
image: public.ecr.aws/docker/library/redis:7.2.7-alpine
|
||||
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: config-init
|
||||
securityContext:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user