Compare commits

...

12 Commits

Author SHA1 Message Date
github-actions[bot]
206a6eeca5 Bump version to 2.14.21 on release-2.14 branch (#25161)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-11-04 09:56:45 -05:00
Jakub Ciolek
8b31544069 fix: make webhook payload handlers recover from panics (cherry-pick #24862 for 2.14) (#24926)
Signed-off-by: Jakub Ciolek <jakub@ciolek.dev>
2025-10-14 14:14:22 -04:00
Carlos R.F.
9b7bf3e16d chore(deps): bump redis from 7.0.14 to 7.2.11 to address vuln (release-2.14) (#24892)
Signed-off-by: Carlos Rodriguez-Fernandez <carlosrodrifernandez@gmail.com>
2025-10-09 17:08:18 -04:00
github-actions[bot]
879895af78 Bump version to 2.14.20 on release-2.14 branch (#24796)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: crenshaw-dev <350466+crenshaw-dev@users.noreply.github.com>
2025-09-30 11:32:00 -04:00
Ville Vesilehto
1f98e3f989 Merge commit from fork
Fixed a race condition in repository credentials handling by
implementing deep copying of secrets before modification.
This prevents concurrent map read/write panics when multiple
goroutines access the same secret.

The fix ensures thread-safe operations by always operating on
copies rather than shared objects.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
2025-09-30 10:45:59 -04:00
Michael Crenshaw
741f00e2e3 Merge commit from fork
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-09-30 10:45:32 -04:00
Michael Crenshaw
e889f0a7ff Merge commit from fork
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-09-30 10:07:24 -04:00
Michael Crenshaw
7b219ee97f Merge commit from fork
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-09-30 09:45:21 -04:00
argo-cd-cherry-pick-bot[bot]
4ab9cd45bf fix: allow for backwards compatibility of durations defined in days (cherry-pick #24769 for 2.14) (#24772)
Signed-off-by: lplazas <felipe.plazas10@gmail.com>
Co-authored-by: lplazas <luis.plazas@workato.com>
2025-09-29 09:08:15 -04:00
github-actions[bot]
ba5b938858 Bump version to 2.14.19 on release-2.14 branch (#24700)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: alexmt <426437+alexmt@users.noreply.github.com>
2025-09-22 15:14:10 -07:00
Alexander Matyushentsev
4a133ce41b fix: limit number of resources in appset status (#24690) (#24694)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2025-09-22 14:57:44 -07:00
Alexandre Gaudreault
376525eea2 ci(release): only set latest release in github when latest (#24525) (#24688)
Signed-off-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
2025-09-22 11:47:51 -04:00
35 changed files with 858 additions and 276 deletions

View File

@@ -486,7 +486,7 @@ jobs:
run: |
docker pull ghcr.io/dexidp/dex:v2.41.1
docker pull argoproj/argo-cd-ci-builder:v1.0.0
docker pull redis:7.0.15-alpine
docker pull redis:7.2.11-alpine
- name: Create target directory for binaries in the build-process
run: |
mkdir -p dist

View File

@@ -32,6 +32,42 @@ jobs:
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
@@ -140,7 +178,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:
@@ -218,6 +256,7 @@ jobs:
post-release:
needs:
- setup-variables
- argocd-image
- goreleaser
- generate-sbom
@@ -226,6 +265,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
@@ -239,27 +280,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 }}

View File

@@ -46,16 +46,17 @@ builds:
archives:
- id: argocd-archive
builds:
- argocd-cli
- argocd-cli
name_template: |-
{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}
format: binary
formats: [binary]
checksum:
name_template: 'cli_checksums.txt'
algorithm: sha256
release:
make_latest: '{{ .Env.GORELEASER_MAKE_LATEST }}'
prerelease: auto
draft: false
header: |
@@ -85,16 +86,14 @@ release:
If upgrading from a different minor version, be sure to read the [upgrading](https://argo-cd.readthedocs.io/en/stable/operator-manual/upgrading/overview/) documentation.
footer: |
**Full Changelog**: https://github.com/argoproj/argo-cd/compare/{{ .PreviousTag }}...{{ .Tag }}
<a href="https://argoproj.github.io/cd/"><img src="https://raw.githubusercontent.com/argoproj/argo-site/master/content/pages/cd/gitops-cd.png" width="25%" ></a>
snapshot: #### To be removed for PR
name_template: "2.6.0"
name_template: '2.6.0'
changelog:
use:
github
use: github
sort: asc
abbrev: 0
groups: # Regex use RE2 syntax as defined here: https://github.com/google/re2/wiki/Syntax.
@@ -117,7 +116,4 @@ changelog:
- '^test:'
- '^.*?Bump(\([[:word:]]+\))?.+$'
- '^.*?\[Bot\](\([[:word:]]+\))?.+$'
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json

View File

@@ -1 +1 @@
2.14.18
2.14.21

View File

@@ -91,6 +91,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
@@ -1314,6 +1315,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 {

View File

@@ -6097,10 +6097,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",
@@ -6271,6 +6272,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.HealthStatus{
Status: health.HealthStatusHealthy,
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "app2",
},
Status: v1alpha1.ApplicationStatus{
Sync: v1alpha1.SyncStatus{
Status: v1alpha1.SyncStatusCodeSynced,
},
Health: v1alpha1.HealthStatus{
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{}...)
@@ -6279,13 +6347,14 @@ func TestUpdateResourceStatus(t *testing.T) {
metrics := appsetmetrics.NewFakeAppsetMetrics(client)
r := ApplicationSetReconciler{
Client: client,
Scheme: scheme,
Recorder: record.NewFakeRecorder(1),
Generators: map[string]generators.Generator{},
ArgoDB: &dbmocks.ArgoDB{},
KubeClientset: kubeclientset,
Metrics: metrics,
Client: client,
Scheme: scheme,
Recorder: record.NewFakeRecorder(1),
Generators: map[string]generators.Generator{},
ArgoDB: &dbmocks.ArgoDB{},
KubeClientset: kubeclientset,
Metrics: metrics,
MaxResourcesStatusCount: cc.maxResourcesStatusCount,
}
err := r.updateResourcesStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps)

View File

@@ -25,10 +25,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/v2/util/guard"
)
const payloadQueueSize = 50000
const panicMsgAppSet = "panic while processing applicationset-controller webhook event"
type WebhookHandler struct {
sync.WaitGroup // for testing
namespace string
@@ -103,6 +107,7 @@ func NewWebhookHandler(namespace string, webhookParallelism int, argocdSettingsM
}
func (h *WebhookHandler) startWorkerPool(webhookParallelism int) {
compLog := log.WithField("component", "applicationset-webhook")
for i := 0; i < webhookParallelism; i++ {
h.Add(1)
go func() {
@@ -112,7 +117,7 @@ func (h *WebhookHandler) startWorkerPool(webhookParallelism int) {
if !ok {
return
}
h.HandleEvent(payload)
guard.RecoverAndLog(func() { h.HandleEvent(payload) }, compLog, panicMsgAppSet)
}
}()
}

View File

@@ -74,6 +74,7 @@ func NewCommand() *cobra.Command {
enableScmProviders bool
webhookParallelism int
tokenRefStrictMode bool
maxResourcesStatusCount int
)
scheme := runtime.NewScheme()
_ = clientgoscheme.AddToScheme(scheme)
@@ -227,6 +228,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)
@@ -270,6 +272,7 @@ func NewCommand() *cobra.Command {
command.Flags().StringSliceVar(&globalPreservedLabels, "preserved-labels", env.StringsFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_GLOBAL_PRESERVED_LABELS", []string{}, ","), "Sets global preserved field values for labels")
command.Flags().IntVar(&webhookParallelism, "webhook-parallelism-limit", env.ParseNumFromEnv("ARGOCD_APPLICATIONSET_CONTROLLER_WEBHOOK_PARALLELISM_LIMIT", 50, 1, 1000), "Number of webhook requests processed concurrently")
command.Flags().StringSliceVar(&metricsAplicationsetLabels, "metrics-applicationset-labels", []string{}, "List of Application labels that will be added to the argocd_applicationset_labels metric")
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
}

View File

@@ -272,6 +272,8 @@ data:
applicationsetcontroller.requeue.after: "3m"
# Enable strict mode for tokenRef in ApplicationSet resources. When enabled, the referenced secret must have a label `argocd.argoproj.io/secret-type` with value `scm-creds`.
applicationsetcontroller.enable.tokenref.strict.mode: "false"
# 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")

View File

@@ -175,6 +175,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

View File

@@ -12,4 +12,4 @@ resources:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.14.18
newTag: v2.14.21

View File

@@ -5,7 +5,7 @@ kind: Kustomization
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.14.18
newTag: v2.14.21
resources:
- ./application-controller
- ./dex

View File

@@ -40,7 +40,7 @@ spec:
serviceAccountName: argocd-redis
containers:
- name: redis
image: redis:7.0.15-alpine
image: redis:7.2.11-alpine
imagePullPolicy: Always
args:
- "--save"

View File

@@ -24165,7 +24165,13 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
- 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:v2.14.21
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -24285,7 +24291,7 @@ spec:
key: commitserver.log.level
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -24331,7 +24337,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -24419,7 +24425,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: redis:7.0.15-alpine
image: redis:7.2.11-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -24435,7 +24441,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -24696,7 +24702,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -24748,7 +24754,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -25078,7 +25084,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -24133,7 +24133,13 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
- 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:v2.14.21
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -24237,7 +24243,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: redis:7.0.15-alpine
image: redis:7.2.11-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -24253,7 +24259,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -24514,7 +24520,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -24566,7 +24572,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -24896,7 +24902,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -12,4 +12,4 @@ resources:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.14.18
newTag: v2.14.21

View File

@@ -12,7 +12,7 @@ patches:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.14.18
newTag: v2.14.21
resources:
- ../../base/application-controller
- ../../base/applicationset-controller

View File

@@ -1219,7 +1219,7 @@ spec:
automountServiceAccountToken: false
initContainers:
- name: config-init
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
resources:
{}
@@ -1258,7 +1258,7 @@ spec:
containers:
- name: redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
command:
- redis-server
@@ -1321,7 +1321,7 @@ spec:
- /bin/sh
- /readonly-config/trigger-failover-if-master.sh
- name: sentinel
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
command:
- redis-sentinel
@@ -1383,7 +1383,7 @@ spec:
- sleep 30; redis-cli -p 26379 sentinel reset argocd
- name: split-brain-fix
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
command:
- sh

View File

@@ -23,7 +23,7 @@ redis-ha:
metrics:
enabled: true
image:
tag: 7.0.15-alpine
tag: 7.2.11-alpine
containerSecurityContext: null
sentinel:
bind: '0.0.0.0'

View File

@@ -25506,7 +25506,13 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
- 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:v2.14.21
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -25626,7 +25632,7 @@ spec:
key: commitserver.log.level
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -25672,7 +25678,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -25793,7 +25799,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -25883,7 +25889,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -26004,7 +26010,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -26291,7 +26297,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -26343,7 +26349,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -26705,7 +26711,7 @@ spec:
key: hydrator.enabled
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -27071,7 +27077,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: argocd-application-controller
ports:
@@ -27169,7 +27175,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -27229,7 +27235,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
@@ -27293,7 +27299,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
name: split-brain-fix
resources: {}
@@ -27328,7 +27334,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
name: config-init
securityContext:

View File

@@ -25476,7 +25476,13 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
- 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:v2.14.21
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -25613,7 +25619,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -25703,7 +25709,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -25824,7 +25830,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -26111,7 +26117,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -26163,7 +26169,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -26525,7 +26531,7 @@ spec:
key: hydrator.enabled
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -26891,7 +26897,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: argocd-application-controller
ports:
@@ -26989,7 +26995,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -27049,7 +27055,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
@@ -27113,7 +27119,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
name: split-brain-fix
resources: {}
@@ -27148,7 +27154,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
name: config-init
securityContext:

View File

@@ -1736,7 +1736,13 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
- 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:v2.14.21
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -1856,7 +1862,7 @@ spec:
key: commitserver.log.level
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1902,7 +1908,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -2023,7 +2029,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -2113,7 +2119,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -2234,7 +2240,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -2521,7 +2527,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -2573,7 +2579,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -2935,7 +2941,7 @@ spec:
key: hydrator.enabled
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -3301,7 +3307,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: argocd-application-controller
ports:
@@ -3399,7 +3405,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -3459,7 +3465,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
@@ -3523,7 +3529,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
name: split-brain-fix
resources: {}
@@ -3558,7 +3564,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
name: config-init
securityContext:

View File

@@ -1706,7 +1706,13 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
- 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:v2.14.21
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -1843,7 +1849,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -1933,7 +1939,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -2054,7 +2060,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -2341,7 +2347,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -2393,7 +2399,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -2755,7 +2761,7 @@ spec:
key: hydrator.enabled
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -3121,7 +3127,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: argocd-application-controller
ports:
@@ -3219,7 +3225,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -3279,7 +3285,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
@@ -3343,7 +3349,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
name: split-brain-fix
resources: {}
@@ -3378,7 +3384,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: public.ecr.aws/docker/library/redis:7.0.15-alpine
image: public.ecr.aws/docker/library/redis:7.2.11-alpine
imagePullPolicy: IfNotPresent
name: config-init
securityContext:

View File

@@ -24625,7 +24625,13 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
- 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:v2.14.21
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -24745,7 +24751,7 @@ spec:
key: commitserver.log.level
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -24791,7 +24797,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -24912,7 +24918,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -25002,7 +25008,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -25088,7 +25094,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: redis:7.0.15-alpine
image: redis:7.2.11-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -25104,7 +25110,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -25365,7 +25371,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -25417,7 +25423,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -25777,7 +25783,7 @@ spec:
key: hydrator.enabled
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -26143,7 +26149,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: argocd-application-controller
ports:

24
manifests/install.yaml generated
View File

@@ -24593,7 +24593,13 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
- 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:v2.14.21
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -24730,7 +24736,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -24820,7 +24826,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -24906,7 +24912,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: redis:7.0.15-alpine
image: redis:7.2.11-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -24922,7 +24928,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -25183,7 +25189,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -25235,7 +25241,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -25595,7 +25601,7 @@ spec:
key: hydrator.enabled
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -25961,7 +25967,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -855,7 +855,13 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
- 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:v2.14.21
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -975,7 +981,7 @@ spec:
key: commitserver.log.level
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1021,7 +1027,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -1142,7 +1148,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -1232,7 +1238,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -1318,7 +1324,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: redis:7.0.15-alpine
image: redis:7.2.11-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -1334,7 +1340,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -1595,7 +1601,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1647,7 +1653,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -2007,7 +2013,7 @@ spec:
key: hydrator.enabled
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2373,7 +2379,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -823,7 +823,13 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
- 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:v2.14.21
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -960,7 +966,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -1050,7 +1056,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -1136,7 +1142,7 @@ spec:
secretKeyRef:
key: auth
name: argocd-redis
image: redis:7.0.15-alpine
image: redis:7.2.11-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -1152,7 +1158,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -1413,7 +1419,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1465,7 +1471,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -1825,7 +1831,7 @@ spec:
key: hydrator.enabled
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2191,7 +2197,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v2.14.18
image: quay.io/argoproj/argocd:v2.14.21
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -34,9 +34,9 @@ func (s *secretsRepositoryBackend) CreateRepository(ctx context.Context, reposit
},
}
s.repositoryToSecret(repository, repositorySecret)
updatedSecret := s.repositoryToSecret(repository, repositorySecret)
_, err := s.db.createSecret(ctx, repositorySecret)
_, err := s.db.createSecret(ctx, updatedSecret)
if err != nil {
if apierr.IsAlreadyExists(err) {
hasLabel, err := s.hasRepoTypeLabel(secName)
@@ -143,9 +143,9 @@ func (s *secretsRepositoryBackend) UpdateRepository(ctx context.Context, reposit
return nil, err
}
s.repositoryToSecret(repository, repositorySecret)
updatedSecret := s.repositoryToSecret(repository, repositorySecret)
_, err = s.db.kubeclientset.CoreV1().Secrets(s.db.ns).Update(ctx, repositorySecret, metav1.UpdateOptions{})
_, err = s.db.kubeclientset.CoreV1().Secrets(s.db.ns).Update(ctx, updatedSecret, metav1.UpdateOptions{})
if err != nil {
return nil, err
}
@@ -188,9 +188,9 @@ func (s *secretsRepositoryBackend) CreateRepoCreds(ctx context.Context, repoCred
},
}
repoCredsToSecret(repoCreds, repoCredsSecret)
updatedSecret := repoCredsToSecret(repoCreds, repoCredsSecret)
_, err := s.db.createSecret(ctx, repoCredsSecret)
_, err := s.db.createSecret(ctx, updatedSecret)
if err != nil {
if apierr.IsAlreadyExists(err) {
return nil, status.Errorf(codes.AlreadyExists, "repository credentials %q already exists", repoCreds.URL)
@@ -238,9 +238,9 @@ func (s *secretsRepositoryBackend) UpdateRepoCreds(ctx context.Context, repoCred
return nil, err
}
repoCredsToSecret(repoCreds, repoCredsSecret)
updatedSecret := repoCredsToSecret(repoCreds, repoCredsSecret)
repoCredsSecret, err = s.db.kubeclientset.CoreV1().Secrets(s.db.ns).Update(ctx, repoCredsSecret, metav1.UpdateOptions{})
repoCredsSecret, err = s.db.kubeclientset.CoreV1().Secrets(s.db.ns).Update(ctx, updatedSecret, metav1.UpdateOptions{})
if err != nil {
return nil, err
}
@@ -302,60 +302,62 @@ func (s *secretsRepositoryBackend) GetAllHelmRepoCreds(ctx context.Context) ([]*
}
func secretToRepository(secret *corev1.Secret) (*appsv1.Repository, error) {
secretCopy := secret.DeepCopy()
repository := &appsv1.Repository{
Name: string(secret.Data["name"]),
Repo: string(secret.Data["url"]),
Username: string(secret.Data["username"]),
Password: string(secret.Data["password"]),
SSHPrivateKey: string(secret.Data["sshPrivateKey"]),
TLSClientCertData: string(secret.Data["tlsClientCertData"]),
TLSClientCertKey: string(secret.Data["tlsClientCertKey"]),
Type: string(secret.Data["type"]),
GithubAppPrivateKey: string(secret.Data["githubAppPrivateKey"]),
GitHubAppEnterpriseBaseURL: string(secret.Data["githubAppEnterpriseBaseUrl"]),
Proxy: string(secret.Data["proxy"]),
NoProxy: string(secret.Data["noProxy"]),
Project: string(secret.Data["project"]),
GCPServiceAccountKey: string(secret.Data["gcpServiceAccountKey"]),
Name: string(secretCopy.Data["name"]),
Repo: string(secretCopy.Data["url"]),
Username: string(secretCopy.Data["username"]),
Password: string(secretCopy.Data["password"]),
SSHPrivateKey: string(secretCopy.Data["sshPrivateKey"]),
TLSClientCertData: string(secretCopy.Data["tlsClientCertData"]),
TLSClientCertKey: string(secretCopy.Data["tlsClientCertKey"]),
Type: string(secretCopy.Data["type"]),
GithubAppPrivateKey: string(secretCopy.Data["githubAppPrivateKey"]),
GitHubAppEnterpriseBaseURL: string(secretCopy.Data["githubAppEnterpriseBaseUrl"]),
Proxy: string(secretCopy.Data["proxy"]),
NoProxy: string(secretCopy.Data["noProxy"]),
Project: string(secretCopy.Data["project"]),
GCPServiceAccountKey: string(secretCopy.Data["gcpServiceAccountKey"]),
}
insecureIgnoreHostKey, err := boolOrFalse(secret, "insecureIgnoreHostKey")
insecureIgnoreHostKey, err := boolOrFalse(secretCopy, "insecureIgnoreHostKey")
if err != nil {
return repository, err
}
repository.InsecureIgnoreHostKey = insecureIgnoreHostKey
insecure, err := boolOrFalse(secret, "insecure")
insecure, err := boolOrFalse(secretCopy, "insecure")
if err != nil {
return repository, err
}
repository.Insecure = insecure
enableLfs, err := boolOrFalse(secret, "enableLfs")
enableLfs, err := boolOrFalse(secretCopy, "enableLfs")
if err != nil {
return repository, err
}
repository.EnableLFS = enableLfs
enableOCI, err := boolOrFalse(secret, "enableOCI")
enableOCI, err := boolOrFalse(secretCopy, "enableOCI")
if err != nil {
return repository, err
}
repository.EnableOCI = enableOCI
githubAppID, err := intOrZero(secret, "githubAppID")
githubAppID, err := intOrZero(secretCopy, "githubAppID")
if err != nil {
return repository, err
}
repository.GithubAppId = githubAppID
githubAppInstallationID, err := intOrZero(secret, "githubAppInstallationID")
githubAppInstallationID, err := intOrZero(secretCopy, "githubAppInstallationID")
if err != nil {
return repository, err
}
repository.GithubAppInstallationId = githubAppInstallationID
forceBasicAuth, err := boolOrFalse(secret, "forceHttpBasicAuth")
forceBasicAuth, err := boolOrFalse(secretCopy, "forceHttpBasicAuth")
if err != nil {
return repository, err
}
@@ -364,70 +366,76 @@ func secretToRepository(secret *corev1.Secret) (*appsv1.Repository, error) {
return repository, nil
}
func (s *secretsRepositoryBackend) repositoryToSecret(repository *appsv1.Repository, secret *corev1.Secret) {
if secret.Data == nil {
secret.Data = make(map[string][]byte)
func (s *secretsRepositoryBackend) repositoryToSecret(repository *appsv1.Repository, secret *corev1.Secret) *corev1.Secret {
secretCopy := secret.DeepCopy()
if secretCopy.Data == nil {
secretCopy.Data = make(map[string][]byte)
}
updateSecretString(secret, "name", repository.Name)
updateSecretString(secret, "project", repository.Project)
updateSecretString(secret, "url", repository.Repo)
updateSecretString(secret, "username", repository.Username)
updateSecretString(secret, "password", repository.Password)
updateSecretString(secret, "sshPrivateKey", repository.SSHPrivateKey)
updateSecretBool(secret, "enableOCI", repository.EnableOCI)
updateSecretString(secret, "tlsClientCertData", repository.TLSClientCertData)
updateSecretString(secret, "tlsClientCertKey", repository.TLSClientCertKey)
updateSecretString(secret, "type", repository.Type)
updateSecretString(secret, "githubAppPrivateKey", repository.GithubAppPrivateKey)
updateSecretInt(secret, "githubAppID", repository.GithubAppId)
updateSecretInt(secret, "githubAppInstallationID", repository.GithubAppInstallationId)
updateSecretString(secret, "githubAppEnterpriseBaseUrl", repository.GitHubAppEnterpriseBaseURL)
updateSecretBool(secret, "insecureIgnoreHostKey", repository.InsecureIgnoreHostKey)
updateSecretBool(secret, "insecure", repository.Insecure)
updateSecretBool(secret, "enableLfs", repository.EnableLFS)
updateSecretString(secret, "proxy", repository.Proxy)
updateSecretString(secret, "noProxy", repository.NoProxy)
updateSecretString(secret, "gcpServiceAccountKey", repository.GCPServiceAccountKey)
updateSecretBool(secret, "forceHttpBasicAuth", repository.ForceHttpBasicAuth)
addSecretMetadata(secret, s.getSecretType())
updateSecretString(secretCopy, "name", repository.Name)
updateSecretString(secretCopy, "project", repository.Project)
updateSecretString(secretCopy, "url", repository.Repo)
updateSecretString(secretCopy, "username", repository.Username)
updateSecretString(secretCopy, "password", repository.Password)
updateSecretString(secretCopy, "sshPrivateKey", repository.SSHPrivateKey)
updateSecretBool(secretCopy, "enableOCI", repository.EnableOCI)
updateSecretString(secretCopy, "tlsClientCertData", repository.TLSClientCertData)
updateSecretString(secretCopy, "tlsClientCertKey", repository.TLSClientCertKey)
updateSecretString(secretCopy, "type", repository.Type)
updateSecretString(secretCopy, "githubAppPrivateKey", repository.GithubAppPrivateKey)
updateSecretInt(secretCopy, "githubAppID", repository.GithubAppId)
updateSecretInt(secretCopy, "githubAppInstallationID", repository.GithubAppInstallationId)
updateSecretString(secretCopy, "githubAppEnterpriseBaseUrl", repository.GitHubAppEnterpriseBaseURL)
updateSecretBool(secretCopy, "insecureIgnoreHostKey", repository.InsecureIgnoreHostKey)
updateSecretBool(secretCopy, "insecure", repository.Insecure)
updateSecretBool(secretCopy, "enableLfs", repository.EnableLFS)
updateSecretString(secretCopy, "proxy", repository.Proxy)
updateSecretString(secretCopy, "noProxy", repository.NoProxy)
updateSecretString(secretCopy, "gcpServiceAccountKey", repository.GCPServiceAccountKey)
updateSecretBool(secretCopy, "forceHttpBasicAuth", repository.ForceHttpBasicAuth)
addSecretMetadata(secretCopy, s.getSecretType())
return secretCopy
}
func (s *secretsRepositoryBackend) secretToRepoCred(secret *corev1.Secret) (*appsv1.RepoCreds, error) {
secretCopy := secret.DeepCopy()
repository := &appsv1.RepoCreds{
URL: string(secret.Data["url"]),
Username: string(secret.Data["username"]),
Password: string(secret.Data["password"]),
SSHPrivateKey: string(secret.Data["sshPrivateKey"]),
TLSClientCertData: string(secret.Data["tlsClientCertData"]),
TLSClientCertKey: string(secret.Data["tlsClientCertKey"]),
Type: string(secret.Data["type"]),
GithubAppPrivateKey: string(secret.Data["githubAppPrivateKey"]),
GitHubAppEnterpriseBaseURL: string(secret.Data["githubAppEnterpriseBaseUrl"]),
GCPServiceAccountKey: string(secret.Data["gcpServiceAccountKey"]),
Proxy: string(secret.Data["proxy"]),
NoProxy: string(secret.Data["noProxy"]),
URL: string(secretCopy.Data["url"]),
Username: string(secretCopy.Data["username"]),
Password: string(secretCopy.Data["password"]),
SSHPrivateKey: string(secretCopy.Data["sshPrivateKey"]),
TLSClientCertData: string(secretCopy.Data["tlsClientCertData"]),
TLSClientCertKey: string(secretCopy.Data["tlsClientCertKey"]),
Type: string(secretCopy.Data["type"]),
GithubAppPrivateKey: string(secretCopy.Data["githubAppPrivateKey"]),
GitHubAppEnterpriseBaseURL: string(secretCopy.Data["githubAppEnterpriseBaseUrl"]),
GCPServiceAccountKey: string(secretCopy.Data["gcpServiceAccountKey"]),
Proxy: string(secretCopy.Data["proxy"]),
NoProxy: string(secretCopy.Data["noProxy"]),
}
enableOCI, err := boolOrFalse(secret, "enableOCI")
enableOCI, err := boolOrFalse(secretCopy, "enableOCI")
if err != nil {
return repository, err
}
repository.EnableOCI = enableOCI
githubAppID, err := intOrZero(secret, "githubAppID")
githubAppID, err := intOrZero(secretCopy, "githubAppID")
if err != nil {
return repository, err
}
repository.GithubAppId = githubAppID
githubAppInstallationID, err := intOrZero(secret, "githubAppInstallationID")
githubAppInstallationID, err := intOrZero(secretCopy, "githubAppInstallationID")
if err != nil {
return repository, err
}
repository.GithubAppInstallationId = githubAppInstallationID
forceBasicAuth, err := boolOrFalse(secret, "forceHttpBasicAuth")
forceBasicAuth, err := boolOrFalse(secretCopy, "forceHttpBasicAuth")
if err != nil {
return repository, err
}
@@ -436,28 +444,32 @@ func (s *secretsRepositoryBackend) secretToRepoCred(secret *corev1.Secret) (*app
return repository, nil
}
func repoCredsToSecret(repoCreds *appsv1.RepoCreds, secret *corev1.Secret) {
if secret.Data == nil {
secret.Data = make(map[string][]byte)
func repoCredsToSecret(repoCreds *appsv1.RepoCreds, secret *corev1.Secret) *corev1.Secret {
secretCopy := secret.DeepCopy()
if secretCopy.Data == nil {
secretCopy.Data = make(map[string][]byte)
}
updateSecretString(secret, "url", repoCreds.URL)
updateSecretString(secret, "username", repoCreds.Username)
updateSecretString(secret, "password", repoCreds.Password)
updateSecretString(secret, "sshPrivateKey", repoCreds.SSHPrivateKey)
updateSecretBool(secret, "enableOCI", repoCreds.EnableOCI)
updateSecretString(secret, "tlsClientCertData", repoCreds.TLSClientCertData)
updateSecretString(secret, "tlsClientCertKey", repoCreds.TLSClientCertKey)
updateSecretString(secret, "type", repoCreds.Type)
updateSecretString(secret, "githubAppPrivateKey", repoCreds.GithubAppPrivateKey)
updateSecretInt(secret, "githubAppID", repoCreds.GithubAppId)
updateSecretInt(secret, "githubAppInstallationID", repoCreds.GithubAppInstallationId)
updateSecretString(secret, "githubAppEnterpriseBaseUrl", repoCreds.GitHubAppEnterpriseBaseURL)
updateSecretString(secret, "gcpServiceAccountKey", repoCreds.GCPServiceAccountKey)
updateSecretString(secret, "proxy", repoCreds.Proxy)
updateSecretString(secret, "noProxy", repoCreds.NoProxy)
updateSecretBool(secret, "forceHttpBasicAuth", repoCreds.ForceHttpBasicAuth)
addSecretMetadata(secret, common.LabelValueSecretTypeRepoCreds)
updateSecretString(secretCopy, "url", repoCreds.URL)
updateSecretString(secretCopy, "username", repoCreds.Username)
updateSecretString(secretCopy, "password", repoCreds.Password)
updateSecretString(secretCopy, "sshPrivateKey", repoCreds.SSHPrivateKey)
updateSecretBool(secretCopy, "enableOCI", repoCreds.EnableOCI)
updateSecretString(secretCopy, "tlsClientCertData", repoCreds.TLSClientCertData)
updateSecretString(secretCopy, "tlsClientCertKey", repoCreds.TLSClientCertKey)
updateSecretString(secretCopy, "type", repoCreds.Type)
updateSecretString(secretCopy, "githubAppPrivateKey", repoCreds.GithubAppPrivateKey)
updateSecretInt(secretCopy, "githubAppID", repoCreds.GithubAppId)
updateSecretInt(secretCopy, "githubAppInstallationID", repoCreds.GithubAppInstallationId)
updateSecretString(secretCopy, "githubAppEnterpriseBaseUrl", repoCreds.GitHubAppEnterpriseBaseURL)
updateSecretString(secretCopy, "gcpServiceAccountKey", repoCreds.GCPServiceAccountKey)
updateSecretString(secretCopy, "proxy", repoCreds.Proxy)
updateSecretString(secretCopy, "noProxy", repoCreds.NoProxy)
updateSecretBool(secretCopy, "forceHttpBasicAuth", repoCreds.ForceHttpBasicAuth)
addSecretMetadata(secretCopy, common.LabelValueSecretTypeRepoCreds)
return secretCopy
}
func (s *secretsRepositoryBackend) getRepositorySecret(repoURL, project string, allowFallback bool) (*corev1.Secret, error) {

View File

@@ -2,7 +2,9 @@ package db
import (
"context"
"fmt"
"strconv"
"sync"
"testing"
"github.com/stretchr/testify/assert"
@@ -84,9 +86,9 @@ func TestSecretsRepositoryBackend_CreateRepository(t *testing.T) {
t.Parallel()
secret := &corev1.Secret{}
s := secretsRepositoryBackend{}
s.repositoryToSecret(repo, secret)
delete(secret.Labels, common.LabelKeySecretType)
f := setupWithK8sObjects(secret)
updatedSecret := s.repositoryToSecret(repo, secret)
delete(updatedSecret.Labels, common.LabelKeySecretType)
f := setupWithK8sObjects(updatedSecret)
f.clientSet.ReactionChain = nil
f.clientSet.AddReactor("create", "secrets", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
gr := schema.GroupResource{
@@ -121,8 +123,8 @@ func TestSecretsRepositoryBackend_CreateRepository(t *testing.T) {
},
}
s := secretsRepositoryBackend{}
s.repositoryToSecret(repo, secret)
f := setupWithK8sObjects(secret)
updatedSecret := s.repositoryToSecret(repo, secret)
f := setupWithK8sObjects(updatedSecret)
f.clientSet.ReactionChain = nil
f.clientSet.WatchReactionChain = nil
f.clientSet.AddReactor("create", "secrets", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
@@ -133,7 +135,7 @@ func TestSecretsRepositoryBackend_CreateRepository(t *testing.T) {
return true, nil, k8serrors.NewAlreadyExists(gr, "already exists")
})
watcher := watch.NewFakeWithChanSize(1, true)
watcher.Add(secret)
watcher.Add(updatedSecret)
f.clientSet.AddWatchReactor("secrets", func(action k8stesting.Action) (handled bool, ret watch.Interface, err error) {
return true, watcher, nil
})
@@ -944,7 +946,7 @@ func TestRepoCredsToSecret(t *testing.T) {
GithubAppInstallationId: 456,
GitHubAppEnterpriseBaseURL: "GitHubAppEnterpriseBaseURL",
}
repoCredsToSecret(creds, s)
s = repoCredsToSecret(creds, s)
assert.Equal(t, []byte(creds.URL), s.Data["url"])
assert.Equal(t, []byte(creds.Username), s.Data["username"])
assert.Equal(t, []byte(creds.Password), s.Data["password"])
@@ -960,3 +962,169 @@ func TestRepoCredsToSecret(t *testing.T) {
assert.Equal(t, map[string]string{common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD}, s.Annotations)
assert.Equal(t, map[string]string{common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds}, s.Labels)
}
func TestRaceConditionInRepoCredsOperations(t *testing.T) {
// Create a single shared secret that will be accessed concurrently
sharedSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: RepoURLToSecretName(repoSecretPrefix, "git@github.com:argoproj/argo-cd.git", ""),
Namespace: testNamespace,
Labels: map[string]string{
common.LabelKeySecretType: common.LabelValueSecretTypeRepoCreds,
},
},
Data: map[string][]byte{
"url": []byte("git@github.com:argoproj/argo-cd.git"),
"username": []byte("test-user"),
"password": []byte("test-pass"),
},
}
// Create test credentials that we'll use for conversion
repoCreds := &appsv1.RepoCreds{
URL: "git@github.com:argoproj/argo-cd.git",
Username: "test-user",
Password: "test-pass",
}
backend := &secretsRepositoryBackend{}
var wg sync.WaitGroup
concurrentOps := 50
errChan := make(chan error, concurrentOps*2) // Channel to collect errors
// Launch goroutines that perform concurrent operations
for i := 0; i < concurrentOps; i++ {
wg.Add(2)
// One goroutine converts from RepoCreds to Secret
go func() {
defer wg.Done()
defer func() {
if r := recover(); r != nil {
errChan <- fmt.Errorf("panic in repoCredsToSecret: %v", r)
}
}()
_ = repoCredsToSecret(repoCreds, sharedSecret)
}()
// Another goroutine converts from Secret to RepoCreds
go func() {
defer wg.Done()
defer func() {
if r := recover(); r != nil {
errChan <- fmt.Errorf("panic in secretToRepoCred: %v", r)
}
}()
creds, err := backend.secretToRepoCred(sharedSecret)
if err != nil {
errChan <- fmt.Errorf("error in secretToRepoCred: %w", err)
return
}
// Verify data integrity
if creds.URL != repoCreds.URL || creds.Username != repoCreds.Username || creds.Password != repoCreds.Password {
errChan <- fmt.Errorf("data mismatch in conversion: expected %v, got %v", repoCreds, creds)
}
}()
}
wg.Wait()
close(errChan)
// Check for any errors that occurred during concurrent operations
for err := range errChan {
t.Errorf("concurrent operation error: %v", err)
}
// Verify final state
finalCreds, err := backend.secretToRepoCred(sharedSecret)
require.NoError(t, err)
assert.Equal(t, repoCreds.URL, finalCreds.URL)
assert.Equal(t, repoCreds.Username, finalCreds.Username)
assert.Equal(t, repoCreds.Password, finalCreds.Password)
}
func TestRaceConditionInRepositoryOperations(t *testing.T) {
// Create a single shared secret that will be accessed concurrently
sharedSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: RepoURLToSecretName(repoSecretPrefix, "git@github.com:argoproj/argo-cd.git", ""),
Namespace: testNamespace,
Labels: map[string]string{
common.LabelKeySecretType: common.LabelValueSecretTypeRepository,
},
},
Data: map[string][]byte{
"url": []byte("git@github.com:argoproj/argo-cd.git"),
"name": []byte("test-repo"),
"username": []byte("test-user"),
"password": []byte("test-pass"),
},
}
// Create test repository that we'll use for conversion
repo := &appsv1.Repository{
Name: "test-repo",
Repo: "git@github.com:argoproj/argo-cd.git",
Username: "test-user",
Password: "test-pass",
}
backend := &secretsRepositoryBackend{}
var wg sync.WaitGroup
concurrentOps := 50
errChan := make(chan error, concurrentOps*2) // Channel to collect errors
// Launch goroutines that perform concurrent operations
for i := 0; i < concurrentOps; i++ {
wg.Add(2)
// One goroutine converts from Repository to Secret
go func() {
defer wg.Done()
defer func() {
if r := recover(); r != nil {
errChan <- fmt.Errorf("panic in repositoryToSecret: %v", r)
}
}()
_ = backend.repositoryToSecret(repo, sharedSecret)
}()
// Another goroutine converts from Secret to Repository
go func() {
defer wg.Done()
defer func() {
if r := recover(); r != nil {
errChan <- fmt.Errorf("panic in secretToRepository: %v", r)
}
}()
repository, err := secretToRepository(sharedSecret)
if err != nil {
errChan <- fmt.Errorf("error in secretToRepository: %w", err)
return
}
// Verify data integrity
if repository.Name != repo.Name || repository.Repo != repo.Repo ||
repository.Username != repo.Username || repository.Password != repo.Password {
errChan <- fmt.Errorf("data mismatch in conversion: expected %v, got %v", repo, repository)
}
}()
}
wg.Wait()
close(errChan)
// Check for any errors that occurred during concurrent operations
for err := range errChan {
t.Errorf("concurrent operation error: %v", err)
}
// Verify final state
finalRepo, err := secretToRepository(sharedSecret)
require.NoError(t, err)
assert.Equal(t, repo.Name, finalRepo.Name)
assert.Equal(t, repo.Repo, finalRepo.Repo)
assert.Equal(t, repo.Username, finalRepo.Username)
assert.Equal(t, repo.Password, finalRepo.Password)
}

11
util/env/env.go vendored
View File

@@ -7,6 +7,8 @@ import (
"strings"
"time"
timeutil "github.com/argoproj/pkg/time"
log "github.com/sirupsen/logrus"
)
@@ -133,8 +135,13 @@ func ParseDurationFromEnv(env string, defaultValue, min, max time.Duration) time
}
dur, err := time.ParseDuration(str)
if err != nil {
log.Warnf("Could not parse '%s' as a duration string from environment %s", str, env)
return defaultValue
// provides backwards compatibility for durations defined in days, see: https://github.com/argoproj/argo-cd/issues/24740
durPtr, err2 := timeutil.ParseDuration(str)
if err2 != nil {
log.Warnf("Could not parse '%s' as a duration from environment %s", str, env)
return defaultValue
}
dur = *durPtr
}
if dur < min {

84
util/env/env_test.go vendored
View File

@@ -142,6 +142,90 @@ func TestParseDurationFromEnv(t *testing.T) {
}
}
func TestParseDurationFromEnvEdgeCases(t *testing.T) {
envKey := "SOME_ENV_KEY"
def := 3 * time.Minute
minimum := 1 * time.Second
maximum := 2160 * time.Hour // 3 months
testCases := []struct {
name string
env string
expected time.Duration
}{{
name: "EnvNotSet",
expected: def,
}, {
name: "Durations defined as days are valid",
env: "12d",
expected: time.Hour * 24 * 12,
}, {
name: "Negative durations should fail parsing and use the default value",
env: "-1h",
expected: def,
}, {
name: "Negative day durations should fail parsing and use the default value",
env: "-12d",
expected: def,
}, {
name: "Scientific notation should fail parsing and use the default value",
env: "1e3s",
expected: def,
}, {
name: "Durations with a leading zero are considered valid and parsed as decimal notation",
env: "0755s",
expected: time.Second * 755,
}, {
name: "Durations with many leading zeroes are considered valid and parsed as decimal notation",
env: "000083m",
expected: time.Minute * 83,
}, {
name: "Decimal Durations should not fail parsing",
env: "30.5m",
expected: time.Minute*30 + time.Second*30,
}, {
name: "Decimal Day Durations should fail parsing and use the default value",
env: "30.5d",
expected: def,
}, {
name: "Fraction Durations should fail parsing and use the default value",
env: "1/2h",
expected: def,
}, {
name: "Durations without a time unit should fail parsing and use the default value",
env: "15",
expected: def,
}, {
name: "Durations with a trailing symbol should fail parsing and use the default value",
env: "+12d",
expected: def,
}, {
name: "Leading space Duration should fail parsing use the default value",
env: " 2h",
expected: def,
}, {
name: "Trailing space Duration should fail parsing use the default value",
env: "6m ",
expected: def,
}, {
name: "Empty Duration should fail parsing use the default value",
env: "",
expected: def,
}, {
name: "Whitespace Duration should fail parsing and use the default value",
env: " ",
expected: def,
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
t.Setenv(envKey, tc.env)
val := ParseDurationFromEnv(envKey, def, minimum, maximum)
assert.Equal(t, tc.expected, val)
})
}
}
func Test_ParseBoolFromEnv(t *testing.T) {
envKey := "SOMEKEY"

20
util/guard/guard.go Normal file
View File

@@ -0,0 +1,20 @@
package guard
import (
"runtime/debug"
)
// Minimal logger contract; avoids depending on any specific logging package.
type Logger interface{ Errorf(string, ...any) }
// Run executes fn and recovers a panic, logging a component-specific message.
func RecoverAndLog(fn func(), log Logger, msg string) {
defer func() {
if r := recover(); r != nil {
if log != nil {
log.Errorf("%s: %v %s", msg, r, debug.Stack())
}
}
}()
fn()
}

92
util/guard/guard_test.go Normal file
View File

@@ -0,0 +1,92 @@
package guard
import (
"fmt"
"strings"
"sync"
"testing"
)
type nop struct{}
func (nop) Errorf(string, ...any) {}
// recorder is a thread-safe logger that captures formatted messages.
type recorder struct {
mu sync.Mutex
calls int
msgs []string
}
func (r *recorder) Errorf(format string, args ...any) {
r.mu.Lock()
defer r.mu.Unlock()
r.calls++
r.msgs = append(r.msgs, fmt.Sprintf(format, args...))
}
func TestRun_Recovers(_ *testing.T) {
RecoverAndLog(func() { panic("boom") }, nop{}, "msg") // fails if panic escapes
}
func TestRun_AllowsNextCall(t *testing.T) {
ran := false
RecoverAndLog(func() { panic("boom") }, nop{}, "msg")
RecoverAndLog(func() { ran = true }, nop{}, "msg")
if !ran {
t.Fatal("expected second callback to run")
}
}
func TestRun_LogsMessageAndStack(t *testing.T) {
r := &recorder{}
RecoverAndLog(func() { panic("boom") }, r, "msg")
if r.calls != 1 {
t.Fatalf("expected 1 log call, got %d", r.calls)
}
got := strings.Join(r.msgs, "\n")
if !strings.Contains(got, "msg") {
t.Errorf("expected log to contain message %q; got %q", "msg", got)
}
if !strings.Contains(got, "boom") {
t.Errorf("expected log to contain panic value %q; got %q", "boom", got)
}
// Heuristic check that a stack trace was included.
if !strings.Contains(got, "guard.go") && !strings.Contains(got, "runtime/panic.go") && !strings.Contains(got, "goroutine") {
t.Errorf("expected log to contain a stack trace; got %q", got)
}
}
func TestRun_NilLoggerDoesNotPanic(_ *testing.T) {
var l Logger // nil
RecoverAndLog(func() { panic("boom") }, l, "ignored")
}
func TestRun_NoPanicDoesNotLog(t *testing.T) {
r := &recorder{}
ran := false
RecoverAndLog(func() { ran = true }, r, "msg")
if !ran {
t.Fatal("expected fn to run")
}
if r.calls != 0 {
t.Fatalf("expected 0 log calls, got %d", r.calls)
}
}
func TestRun_ConcurrentPanicsLogged(t *testing.T) {
r := &recorder{}
const n = 10
var wg sync.WaitGroup
wg.Add(n)
for i := 0; i < n; i++ {
go func(i int) {
defer wg.Done()
RecoverAndLog(func() { panic(fmt.Sprintf("boom-%d", i)) }, r, "msg")
}(i)
}
wg.Wait()
if r.calls != n {
t.Fatalf("expected %d log calls, got %d", n, r.calls)
}
}

View File

@@ -33,6 +33,7 @@ import (
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/argo-cd/v2/util/db"
"github.com/argoproj/argo-cd/v2/util/glob"
"github.com/argoproj/argo-cd/v2/util/guard"
"github.com/argoproj/argo-cd/v2/util/settings"
)
@@ -48,6 +49,8 @@ const usernameRegex = `[a-zA-Z0-9_\.][a-zA-Z0-9_\.-]{0,30}[a-zA-Z0-9_\.\$-]?`
const payloadQueueSize = 50000
const panicMsgServer = "panic while processing api-server webhook event"
var _ settingsSource = &settings.SettingsManager{}
type ArgoCDWebhookHandler struct {
@@ -121,6 +124,7 @@ func NewHandler(namespace string, applicationNamespaces []string, webhookParalle
}
func (a *ArgoCDWebhookHandler) startWorkerPool(webhookParallelism int) {
compLog := log.WithField("component", "api-server-webhook")
for i := 0; i < webhookParallelism; i++ {
a.Add(1)
go func() {
@@ -130,7 +134,7 @@ func (a *ArgoCDWebhookHandler) startWorkerPool(webhookParallelism int) {
if !ok {
return
}
a.HandleEvent(payload)
guard.RecoverAndLog(func() { a.HandleEvent(payload) }, compLog, panicMsgServer)
}
}()
}
@@ -148,10 +152,12 @@ func affectedRevisionInfo(payloadIf interface{}) (webURLs []string, revision str
case azuredevops.GitPushEvent:
// See: https://learn.microsoft.com/en-us/azure/devops/service-hooks/events?view=azure-devops#git.push
webURLs = append(webURLs, payload.Resource.Repository.RemoteURL)
revision = ParseRevision(payload.Resource.RefUpdates[0].Name)
change.shaAfter = ParseRevision(payload.Resource.RefUpdates[0].NewObjectID)
change.shaBefore = ParseRevision(payload.Resource.RefUpdates[0].OldObjectID)
touchedHead = payload.Resource.RefUpdates[0].Name == payload.Resource.Repository.DefaultBranch
if len(payload.Resource.RefUpdates) > 0 {
revision = ParseRevision(payload.Resource.RefUpdates[0].Name)
change.shaAfter = ParseRevision(payload.Resource.RefUpdates[0].NewObjectID)
change.shaBefore = ParseRevision(payload.Resource.RefUpdates[0].OldObjectID)
touchedHead = payload.Resource.RefUpdates[0].Name == payload.Resource.Repository.DefaultBranch
}
// unfortunately, Azure DevOps doesn't provide a list of changed files
case github.PushPayload:
// See: https://developer.github.com/v3/activity/events/types/#pushevent
@@ -210,13 +216,15 @@ func affectedRevisionInfo(payloadIf interface{}) (webURLs []string, revision str
// Webhook module does not parse the inner links
if payload.Repository.Links != nil {
for _, l := range payload.Repository.Links["clone"].([]interface{}) {
link := l.(map[string]interface{})
if link["name"] == "http" {
webURLs = append(webURLs, link["href"].(string))
}
if link["name"] == "ssh" {
webURLs = append(webURLs, link["href"].(string))
clone, ok := payload.Repository.Links["clone"].([]any)
if ok {
for _, l := range clone {
link := l.(map[string]any)
if link["name"] == "http" || link["name"] == "ssh" {
if href, ok := link["href"].(string); ok {
webURLs = append(webURLs, href)
}
}
}
}
}
@@ -235,11 +243,13 @@ func affectedRevisionInfo(payloadIf interface{}) (webURLs []string, revision str
// so we cannot update changedFiles for this type of payload
case gogsclient.PushPayload:
webURLs = append(webURLs, payload.Repo.HTMLURL)
revision = ParseRevision(payload.Ref)
change.shaAfter = ParseRevision(payload.After)
change.shaBefore = ParseRevision(payload.Before)
touchedHead = bool(payload.Repo.DefaultBranch == revision)
if payload.Repo != nil {
webURLs = append(webURLs, payload.Repo.HTMLURL)
touchedHead = payload.Repo.DefaultBranch == revision
}
for _, commit := range payload.Commits {
changedFiles = append(changedFiles, commit.Added...)
changedFiles = append(changedFiles, commit.Modified...)

View File

@@ -12,6 +12,8 @@ import (
"testing"
"time"
"github.com/go-playground/webhooks/v6/azuredevops"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
@@ -692,6 +694,26 @@ func Test_affectedRevisionInfo_appRevisionHasChanged(t *testing.T) {
{true, "refs/tags/no-slashes", bitbucketPushPayload("no-slashes"), "bitbucket push branch or tag name without slashes, targetRevision tag prefixed"},
{true, "refs/tags/no-slashes", bitbucketRefChangedPayload("no-slashes"), "bitbucket ref changed branch or tag name without slashes, targetRevision tag prefixed"},
{true, "refs/tags/no-slashes", gogsPushPayload("no-slashes"), "gogs push branch or tag name without slashes, targetRevision tag prefixed"},
// Tests fix for https://github.com/argoproj/argo-cd/security/advisories/GHSA-wp4p-9pxh-cgx2
{true, "test", gogsclient.PushPayload{Ref: "test", Repo: nil}, "gogs push branch with nil repo in payload"},
// Testing fix for https://github.com/argoproj/argo-cd/security/advisories/GHSA-gpx4-37g2-c8pv
{false, "test", azuredevops.GitPushEvent{Resource: azuredevops.Resource{RefUpdates: []azuredevops.RefUpdate{}}}, "Azure DevOps malformed push event with no ref updates"},
{true, "some-ref", bitbucketserver.RepositoryReferenceChangedPayload{
Changes: []bitbucketserver.RepositoryChange{
{Reference: bitbucketserver.RepositoryReference{ID: "refs/heads/some-ref"}},
},
Repository: bitbucketserver.Repository{Links: map[string]any{"clone": "boom"}}, // The string "boom" here is what previously caused a panic.
}, "bitbucket push branch or tag name, malformed link"}, // https://github.com/argoproj/argo-cd/security/advisories/GHSA-f9gq-prrc-hrhc
{true, "some-ref", bitbucketserver.RepositoryReferenceChangedPayload{
Changes: []bitbucketserver.RepositoryChange{
{Reference: bitbucketserver.RepositoryReference{ID: "refs/heads/some-ref"}},
},
Repository: bitbucketserver.Repository{Links: map[string]any{"clone": []any{map[string]any{"name": "http", "href": []string{}}}}}, // The href as an empty array is what previously caused a panic.
}, "bitbucket push branch or tag name, malformed href"},
}
for _, testCase := range tests {
testCopy := testCase