Compare commits

...

18 Commits

Author SHA1 Message Date
github-actions[bot]
5328bd58e6 Bump version to 3.0.4 on release-3.0 branch (#23185)
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-05-28 08:45:50 -06:00
Michael Crenshaw
040ed44b20 Merge commit from fork
Fix shadowed variable name

Signed-off-by: Ry0taK <49341894+Ry0taK@users.noreply.github.com>
Co-authored-by: Ry0taK <49341894+Ry0taK@users.noreply.github.com>
2025-05-28 08:20:49 -06:00
gcp-cherry-pick-bot[bot]
c27a9d3360 fix(commit-server): apply image override (cherry-pick #22916) (#22917)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-05-21 14:48:38 -04:00
github-actions[bot]
a14b0125fe Bump version to 3.0.3 on release-3.0 branch (#23087)
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-05-21 14:18:58 -04:00
Peter Jiang
866db14e30 chore: bump gitops-engine ssd fix (#23071)
Signed-off-by: Peter Jiang <peterjiang823@gmail.com>
2025-05-20 21:09:18 -04:00
gcp-cherry-pick-bot[bot]
af3d9266a8 fix: Account for batch event processing in e2e tests (cherry-pick #22356) (#23070)
Signed-off-by: Andrii Korotkov <andrii.korotkov@verkada.com>
Co-authored-by: Andrii Korotkov <137232734+andrii-korotkov-verkada@users.noreply.github.com>
2025-05-20 20:09:04 -04:00
Alexandre Gaudreault
ddd6df5d44 fix: infinite reconciliation loop when app is in error (#23067)
Signed-off-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
2025-05-20 16:12:00 -04:00
gcp-cherry-pick-bot[bot]
927ed3504e fix: remove default spec.preserveUnknownFields ignoreDifference for CRD (cherry-pick #22948) (#23044)
Signed-off-by: mikutas <23391543+mikutas@users.noreply.github.com>
Signed-off-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
Co-authored-by: Takumi Sue <23391543+mikutas@users.noreply.github.com>
Co-authored-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
2025-05-20 09:43:08 -04:00
gcp-cherry-pick-bot[bot]
b1cafa9d76 docs: fix jsonpath in 2.14-3.0 upgrade doc (cherry-pick #23045) (#23046)
Signed-off-by: Cyril Gaudin <cyril.gaudin@camunda.com>
Co-authored-by: Cyril Gaudin <cyril.gaudin@gmail.com>
2025-05-19 09:58:23 -07:00
github-actions[bot]
8a7c0f0c86 Bump version to 3.0.2 on release-3.0 branch (#23039)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: reggie-k <19544836+reggie-k@users.noreply.github.com>
2025-05-19 16:41:34 +03:00
Regina Voloshin
3fb34b99de fix(haproxy): setting maxconn in haproxy config cherry-pick (#15319) (#18283) (#23037)
Signed-off-by: Timothy Griffiths <griffiths.timothy@gmail.com>
Signed-off-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
Co-authored-by: Timothy Griffiths <griffiths.timothy@gmail.com>
Co-authored-by: Alexandre Gaudreault <alexandre_gaudreault@intuit.com>
2025-05-19 14:48:47 +02:00
Oleksandr Saulyak
90e9d1a5ad fix: settings request doesn't return default tracking method (#22965) (cherry-pick) (#23034)
Signed-off-by: oleksandr-codefresh <oleksandr.saulyak@octopus.com>
2025-05-19 11:07:32 +03:00
gcp-cherry-pick-bot[bot]
cca991a018 fix(test): broken e2e test (cherry-pick #22975) (#23017)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-05-16 10:00:08 -07:00
gcp-cherry-pick-bot[bot]
3d37cfac04 docs(server): no resource health when using the list api (cherry-pick #22954) (#22972)
Signed-off-by: rumstead <37445536+rumstead@users.noreply.github.com>
Co-authored-by: rumstead <37445536+rumstead@users.noreply.github.com>
2025-05-14 11:40:19 -04:00
github-actions[bot]
2bcef48772 Bump version to 3.0.1 on release-3.0 branch (#22968)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: reggie-k <19544836+reggie-k@users.noreply.github.com>
2025-05-14 17:59:45 +03:00
gcp-cherry-pick-bot[bot]
cb5d6f5ef7 fix(health): handle nil lastTransitionTime (#22897) (cherry-pick #22900) (#22908)
Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
2025-05-09 10:46:00 -04:00
gcp-cherry-pick-bot[bot]
2913d5fcb5 fix: Race condition in nativeGitClient.LsFiles (issue #21754) (cherry-pick #22878) (#22906)
Signed-off-by: Mathieu Agar <magar@mirakl.com>
Co-authored-by: Mathieu Agar <magar@mirakl.com>
Co-authored-by: rumstead <37445536+rumstead@users.noreply.github.com>
2025-05-08 08:01:31 -07:00
gcp-cherry-pick-bot[bot]
edd2358f79 fix(docs): upgrading 3.0 docs (cherry-pick #22891) (#22894)
Signed-off-by: Joerg Heyduk <joerg@heyduk.org>
Co-authored-by: jheyduk <jheyduk@users.noreply.github.com>
2025-05-07 09:06:07 -04:00
78 changed files with 589 additions and 252 deletions

View File

@@ -486,6 +486,7 @@ start-e2e-local: mod-vendor-local dep-ui-local cli-local
ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS=http://127.0.0.1:8341,http://127.0.0.1:8342,http://127.0.0.1:8343,http://127.0.0.1:8344 \
ARGOCD_E2E_TEST=true \
ARGOCD_HYDRATOR_ENABLED=true \
ARGOCD_CLUSTER_CACHE_EVENTS_PROCESSING_INTERVAL=1ms \
goreman -f $(ARGOCD_PROCFILE) start ${ARGOCD_START}
ls -lrt /tmp/coverage

View File

@@ -1 +1 @@
3.0.0
3.0.4

View File

@@ -1681,11 +1681,9 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
project, hasErrors := ctrl.refreshAppConditions(app)
ts.AddCheckpoint("refresh_app_conditions_ms")
now := metav1.Now()
if hasErrors {
app.Status.Sync.Status = appv1.SyncStatusCodeUnknown
app.Status.Health.Status = health.HealthStatusUnknown
app.Status.Health.LastTransitionTime = &now
patchMs = ctrl.persistAppStatus(origApp, &app.Status)
if err := ctrl.cache.SetAppResourcesTree(app.InstanceName(ctrl.namespace), &appv1.ApplicationTree{}); err != nil {
@@ -1782,6 +1780,7 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo
ts.AddCheckpoint("auto_sync_ms")
if app.Status.ReconciledAt == nil || comparisonLevel >= CompareWithLatest {
now := metav1.Now()
app.Status.ReconciledAt = &now
}
app.Status.Sync = *compareResult.syncStatus
@@ -2012,9 +2011,15 @@ func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, new
ctrl.logAppEvent(context.TODO(), orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: corev1.EventTypeNormal}, message)
}
if orig.Status.Health.Status != newStatus.Health.Status {
now := metav1.Now()
newStatus.Health.LastTransitionTime = &now
message := fmt.Sprintf("Updated health status: %s -> %s", orig.Status.Health.Status, newStatus.Health.Status)
ctrl.logAppEvent(context.TODO(), orig, argo.EventInfo{Reason: argo.EventReasonResourceUpdated, Type: corev1.EventTypeNormal}, message)
} else {
// make sure the last transition time is the same and populated if the health is the same
newStatus.Health.LastTransitionTime = orig.Status.Health.LastTransitionTime
}
var newAnnotations map[string]string
if orig.GetAnnotations() != nil {
newAnnotations = make(map[string]string)

View File

@@ -1826,7 +1826,7 @@ apps/Deployment:
hs = {}
hs.status = ""
hs.message = ""
if obj.metadata ~= nil then
if obj.metadata.labels ~= nil then
current_status = obj.metadata.labels["status"]

View File

@@ -242,6 +242,10 @@ func (c *liveStateCache) loadCacheSettings() (*cacheSettings, error) {
if err != nil {
return nil, err
}
trackingMethod, err := c.settingsMgr.GetTrackingMethod()
if err != nil {
return nil, err
}
installationID, err := c.settingsMgr.GetInstallationID()
if err != nil {
return nil, err
@@ -267,7 +271,7 @@ func (c *liveStateCache) loadCacheSettings() (*cacheSettings, error) {
ResourcesFilter: resourcesFilter,
}
return &cacheSettings{clusterSettings, appInstanceLabelKey, argo.GetTrackingMethod(c.settingsMgr), installationID, resourceUpdatesOverrides, ignoreResourceUpdatesEnabled}, nil
return &cacheSettings{clusterSettings, appInstanceLabelKey, appv1.TrackingMethod(trackingMethod), installationID, resourceUpdatesOverrides, ignoreResourceUpdatesEnabled}, nil
}
func asResourceNode(r *clustercache.Resource) appv1.ResourceNode {

View File

@@ -8,7 +8,6 @@ import (
"github.com/argoproj/gitops-engine/pkg/sync/ignore"
kubeutil "github.com/argoproj/gitops-engine/pkg/utils/kube"
log "github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"github.com/argoproj/argo-cd/v3/common"
@@ -22,7 +21,9 @@ func setApplicationHealth(resources []managedResource, statuses []appv1.Resource
var savedErr error
var errCount uint
appHealth := appv1.HealthStatus{Status: health.HealthStatusHealthy}
appHealth := app.Status.Health.DeepCopy()
appHealth.Status = health.HealthStatusHealthy
for i, res := range resources {
if res.Target != nil && hookutil.Skip(res.Target) {
continue
@@ -80,13 +81,6 @@ func setApplicationHealth(resources []managedResource, statuses []appv1.Resource
appHealth.Status = healthStatus.Status
}
}
// if the status didn't change, don't update the timestamp
if app.Status.Health.Status == appHealth.Status && app.Status.Health.LastTransitionTime != nil {
appHealth.LastTransitionTime = app.Status.Health.LastTransitionTime
} else {
now := metav1.Now()
appHealth.LastTransitionTime = &now
}
if persistResourceHealth {
app.Status.ResourceHealthSource = appv1.ResourceHealthLocationInline
} else {
@@ -95,5 +89,5 @@ func setApplicationHealth(resources []managedResource, statuses []appv1.Resource
if savedErr != nil && errCount > 1 {
savedErr = fmt.Errorf("see application-controller logs for %d other errors; most recent error was: %w", errCount-1, savedErr)
}
return &appHealth, savedErr
return appHealth, savedErr
}

View File

@@ -73,7 +73,6 @@ func TestSetApplicationHealth(t *testing.T) {
assert.NotNil(t, healthStatus.LastTransitionTime)
assert.Nil(t, resourceStatuses[0].Health.LastTransitionTime)
assert.Nil(t, resourceStatuses[1].Health.LastTransitionTime)
previousLastTransitionTime := healthStatus.LastTransitionTime
app.Status.Health = *healthStatus
// now mark the job as a hook and retry. it should ignore the hook and consider the app healthy
@@ -81,9 +80,8 @@ func TestSetApplicationHealth(t *testing.T) {
healthStatus, err = setApplicationHealth(resources, resourceStatuses, nil, app, true)
require.NoError(t, err)
assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status)
// change in health, timestamp should change
assert.NotEqual(t, *previousLastTransitionTime, *healthStatus.LastTransitionTime)
previousLastTransitionTime = healthStatus.LastTransitionTime
// timestamp should be the same in case health did not change
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
app.Status.Health = *healthStatus
// now we set the `argocd.argoproj.io/ignore-healthcheck: "true"` annotation on the job's target.
@@ -94,8 +92,7 @@ func TestSetApplicationHealth(t *testing.T) {
healthStatus, err = setApplicationHealth(resources, resourceStatuses, nil, app, true)
require.NoError(t, err)
assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status)
// no change in health, timestamp shouldn't change
assert.Equal(t, *previousLastTransitionTime, *healthStatus.LastTransitionTime)
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
}
func TestSetApplicationHealth_ResourceHealthNotPersisted(t *testing.T) {
@@ -125,7 +122,7 @@ func TestSetApplicationHealth_MissingResource(t *testing.T) {
healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true)
require.NoError(t, err)
assert.Equal(t, health.HealthStatusMissing, healthStatus.Status)
assert.False(t, healthStatus.LastTransitionTime.IsZero())
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
}
func TestSetApplicationHealth_HealthImproves(t *testing.T) {
@@ -157,7 +154,7 @@ func TestSetApplicationHealth_HealthImproves(t *testing.T) {
healthStatus, err := setApplicationHealth(resources, resourceStatuses, overrides, app, true)
require.NoError(t, err)
assert.Equal(t, tc.newStatus, healthStatus.Status)
assert.NotEqual(t, testTimestamp, *healthStatus.LastTransitionTime)
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
})
}
}
@@ -174,6 +171,7 @@ func TestSetApplicationHealth_MissingResourceNoBuiltHealthCheck(t *testing.T) {
healthStatus, err := setApplicationHealth(resources, resourceStatuses, lua.ResourceHealthOverrides{}, app, true)
require.NoError(t, err)
assert.Equal(t, health.HealthStatusHealthy, healthStatus.Status)
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
assert.Equal(t, health.HealthStatusMissing, resourceStatuses[0].Health.Status)
})
@@ -185,7 +183,7 @@ func TestSetApplicationHealth_MissingResourceNoBuiltHealthCheck(t *testing.T) {
}, app, true)
require.NoError(t, err)
assert.Equal(t, health.HealthStatusMissing, healthStatus.Status)
assert.False(t, healthStatus.LastTransitionTime.IsZero())
assert.Equal(t, app.Status.Health.LastTransitionTime, healthStatus.LastTransitionTime)
})
}

View File

@@ -163,6 +163,11 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
return nil, nil, false, fmt.Errorf("failed to get Helm settings: %w", err)
}
trackingMethod, err := m.settingsMgr.GetTrackingMethod()
if err != nil {
return nil, nil, false, fmt.Errorf("failed to get trackingMethod: %w", err)
}
installationID, err := m.settingsMgr.GetInstallationID()
if err != nil {
return nil, nil, false, fmt.Errorf("failed to get installation ID: %w", err)
@@ -249,7 +254,7 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
ApplicationSource: &source,
KubeVersion: serverVersion,
ApiVersions: apiVersions,
TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)),
TrackingMethod: trackingMethod,
RefSources: refSources,
HasMultipleSources: app.Spec.HasMultipleSources(),
InstallationID: installationID,
@@ -286,7 +291,7 @@ func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alp
ApiVersions: apiVersions,
VerifySignature: verifySignature,
HelmRepoCreds: permittedHelmCredentials,
TrackingMethod: string(argo.GetTrackingMethod(m.settingsMgr)),
TrackingMethod: trackingMethod,
EnabledSourceTypes: enabledSourceTypes,
HelmOptions: helmOptions,
HasMultipleSources: app.Spec.HasMultipleSources(),
@@ -435,24 +440,28 @@ func normalizeClusterScopeTracking(targetObjs []*unstructured.Unstructured, info
// getComparisonSettings will return the system level settings related to the
// diff/normalization process.
func (m *appStateManager) getComparisonSettings() (string, map[string]v1alpha1.ResourceOverride, *settings.ResourcesFilter, string, error) {
func (m *appStateManager) getComparisonSettings() (string, map[string]v1alpha1.ResourceOverride, *settings.ResourcesFilter, string, string, error) {
resourceOverrides, err := m.settingsMgr.GetResourceOverrides()
if err != nil {
return "", nil, nil, "", err
return "", nil, nil, "", "", err
}
appLabelKey, err := m.settingsMgr.GetAppInstanceLabelKey()
if err != nil {
return "", nil, nil, "", err
return "", nil, nil, "", "", err
}
resFilter, err := m.settingsMgr.GetResourcesFilter()
if err != nil {
return "", nil, nil, "", err
return "", nil, nil, "", "", err
}
installationID, err := m.settingsMgr.GetInstallationID()
if err != nil {
return "", nil, nil, "", err
return "", nil, nil, "", "", err
}
return appLabelKey, resourceOverrides, resFilter, installationID, nil
trackingMethod, err := m.settingsMgr.GetTrackingMethod()
if err != nil {
return "", nil, nil, "", "", err
}
return appLabelKey, resourceOverrides, resFilter, installationID, trackingMethod, nil
}
// verifyGnuPGSignature verifies the result of a GnuPG operation for a given git
@@ -503,13 +512,12 @@ func isManagedNamespace(ns *unstructured.Unstructured, app *v1alpha1.Application
// revision and overrides in the app spec.
func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1alpha1.AppProject, revisions []string, sources []v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localManifests []string, hasMultipleSources bool, rollback bool) (*comparisonResult, error) {
ts := stats.NewTimingStats()
appLabelKey, resourceOverrides, resFilter, installationID, err := m.getComparisonSettings()
appLabelKey, resourceOverrides, resFilter, installationID, trackingMethod, err := m.getComparisonSettings()
ts.AddCheckpoint("settings_ms")
// return unknown comparison result if basic comparison settings cannot be loaded
if err != nil {
now := metav1.Now()
if hasMultipleSources {
return &comparisonResult{
syncStatus: &v1alpha1.SyncStatus{
@@ -517,7 +525,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
Status: v1alpha1.SyncStatusCodeUnknown,
Revisions: revisions,
},
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown, LastTransitionTime: &now},
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown},
}, nil
}
return &comparisonResult{
@@ -526,7 +534,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
Status: v1alpha1.SyncStatusCodeUnknown,
Revision: revisions[0],
},
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown, LastTransitionTime: &now},
healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown},
}, nil
}
@@ -615,10 +623,8 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
infoProvider = &resourceInfoProviderStub{}
}
trackingMethod := argo.GetTrackingMethod(m.settingsMgr)
err = normalizeClusterScopeTracking(targetObjs, infoProvider, func(u *unstructured.Unstructured) error {
return m.resourceTracking.SetAppInstance(u, appLabelKey, app.InstanceName(m.namespace), app.Spec.Destination.Namespace, trackingMethod, installationID)
return m.resourceTracking.SetAppInstance(u, appLabelKey, app.InstanceName(m.namespace), app.Spec.Destination.Namespace, v1alpha1.TrackingMethod(trackingMethod), installationID)
})
if err != nil {
msg := "Failed to normalize cluster-scoped resource tracking: " + err.Error()
@@ -685,7 +691,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
for _, liveObj := range liveObjByKey {
if liveObj != nil {
appInstanceName := m.resourceTracking.GetAppName(liveObj, appLabelKey, trackingMethod, installationID)
appInstanceName := m.resourceTracking.GetAppName(liveObj, appLabelKey, v1alpha1.TrackingMethod(trackingMethod), installationID)
if appInstanceName != "" && appInstanceName != app.InstanceName(m.namespace) {
fqInstanceName := strings.ReplaceAll(appInstanceName, "_", "/")
conditions = append(conditions, v1alpha1.ApplicationCondition{
@@ -824,7 +830,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1
}
gvk := obj.GroupVersionKind()
isSelfReferencedObj := m.isSelfReferencedObj(liveObj, targetObj, app.GetName(), trackingMethod, installationID)
isSelfReferencedObj := m.isSelfReferencedObj(liveObj, targetObj, app.GetName(), v1alpha1.TrackingMethod(trackingMethod), installationID)
resState := v1alpha1.ResourceStatus{
Namespace: obj.GetNamespace(),
@@ -1148,7 +1154,7 @@ func (m *appStateManager) isSelfReferencedObj(live, config *unstructured.Unstruc
// If tracking method doesn't contain required metadata for this check,
// we are not able to determine and just assume the object to be managed.
if trackingMethod == argo.TrackingMethodLabel {
if trackingMethod == v1alpha1.TrackingMethodLabel {
return true
}

View File

@@ -31,7 +31,6 @@ import (
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v3/reposerver/apiclient"
"github.com/argoproj/argo-cd/v3/test"
"github.com/argoproj/argo-cd/v3/util/argo"
)
// TestCompareAppStateEmpty tests comparison when both git and live have no objects
@@ -719,7 +718,7 @@ func TestSetHealth(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status)
assert.False(t, compRes.healthStatus.LastTransitionTime.IsZero())
assert.Equal(t, app.Status.Health.LastTransitionTime, compRes.healthStatus.LastTransitionTime)
}
func TestPreserveStatusTimestamp(t *testing.T) {
@@ -794,7 +793,7 @@ func TestSetHealthSelfReferencedApp(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status)
assert.False(t, compRes.healthStatus.LastTransitionTime.IsZero())
assert.Equal(t, app.Status.Health.LastTransitionTime, compRes.healthStatus.LastTransitionTime)
}
func TestSetManagedResourcesWithOrphanedResources(t *testing.T) {
@@ -870,7 +869,7 @@ func TestReturnUnknownComparisonStateOnSettingLoadError(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, health.HealthStatusUnknown, compRes.healthStatus.Status)
assert.False(t, compRes.healthStatus.LastTransitionTime.IsZero())
assert.Equal(t, app.Status.Health.LastTransitionTime, compRes.healthStatus.LastTransitionTime)
assert.Equal(t, v1alpha1.SyncStatusCodeUnknown, compRes.syncStatus.Status)
}
@@ -1415,8 +1414,8 @@ func TestIsLiveResourceManaged(t *testing.T) {
configObj := managedObj.DeepCopy()
// then
assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, argo.TrackingMethodLabel, ""))
assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, argo.TrackingMethodAnnotation, ""))
assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, v1alpha1.TrackingMethodLabel, ""))
assert.True(t, manager.isSelfReferencedObj(managedObj, configObj, appName, v1alpha1.TrackingMethodAnnotation, ""))
})
t.Run("will return true if tracked with label", func(t *testing.T) {
// given
@@ -1424,43 +1423,43 @@ func TestIsLiveResourceManaged(t *testing.T) {
configObj := managedObjWithLabel.DeepCopy()
// then
assert.True(t, manager.isSelfReferencedObj(managedObjWithLabel, configObj, appName, argo.TrackingMethodLabel, ""))
assert.True(t, manager.isSelfReferencedObj(managedObjWithLabel, configObj, appName, v1alpha1.TrackingMethodLabel, ""))
})
t.Run("will handle if trackingId has wrong resource name and config is nil", func(t *testing.T) {
// given
t.Parallel()
// then
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, argo.TrackingMethodLabel, ""))
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, argo.TrackingMethodAnnotation, ""))
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, v1alpha1.TrackingMethodLabel, ""))
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongName, nil, appName, v1alpha1.TrackingMethodAnnotation, ""))
})
t.Run("will handle if trackingId has wrong resource group and config is nil", func(t *testing.T) {
// given
t.Parallel()
// then
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, argo.TrackingMethodLabel, ""))
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, argo.TrackingMethodAnnotation, ""))
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, v1alpha1.TrackingMethodLabel, ""))
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongGroup, nil, appName, v1alpha1.TrackingMethodAnnotation, ""))
})
t.Run("will handle if trackingId has wrong kind and config is nil", func(t *testing.T) {
// given
t.Parallel()
// then
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, argo.TrackingMethodLabel, ""))
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, argo.TrackingMethodAnnotation, ""))
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, v1alpha1.TrackingMethodLabel, ""))
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongKind, nil, appName, v1alpha1.TrackingMethodAnnotation, ""))
})
t.Run("will handle if trackingId has wrong namespace and config is nil", func(t *testing.T) {
// given
t.Parallel()
// then
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, argo.TrackingMethodLabel, ""))
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, argo.TrackingMethodAnnotationAndLabel, ""))
assert.True(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, v1alpha1.TrackingMethodLabel, ""))
assert.False(t, manager.isSelfReferencedObj(unmanagedObjWrongNamespace, nil, appName, v1alpha1.TrackingMethodAnnotationAndLabel, ""))
})
t.Run("will return true if live is nil", func(t *testing.T) {
t.Parallel()
assert.True(t, manager.isSelfReferencedObj(nil, nil, appName, argo.TrackingMethodAnnotation, ""))
assert.True(t, manager.isSelfReferencedObj(nil, nil, appName, v1alpha1.TrackingMethodAnnotation, ""))
})
t.Run("will handle upgrade in desired state APIGroup", func(t *testing.T) {
@@ -1470,7 +1469,7 @@ func TestIsLiveResourceManaged(t *testing.T) {
delete(config.GetAnnotations(), common.AnnotationKeyAppInstance)
// then
assert.True(t, manager.isSelfReferencedObj(managedWrongAPIGroup, config, appName, argo.TrackingMethodAnnotation, ""))
assert.True(t, manager.isSelfReferencedObj(managedWrongAPIGroup, config, appName, v1alpha1.TrackingMethodAnnotation, ""))
})
}

View File

@@ -309,7 +309,11 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
log.Errorf("Could not get installation ID: %v", err)
return
}
trackingMethod := argo.GetTrackingMethod(m.settingsMgr)
trackingMethod, err := m.settingsMgr.GetTrackingMethod()
if err != nil {
log.Errorf("Could not get trackingMethod: %v", err)
return
}
impersonationEnabled, err := m.settingsMgr.IsImpersonationEnabled()
if err != nil {
@@ -360,7 +364,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha
return (len(syncOp.Resources) == 0 ||
isPostDeleteHook(target) ||
argo.ContainsSyncResource(key.Name, key.Namespace, schema.GroupVersionKind{Kind: key.Kind, Group: key.Group}, syncOp.Resources)) &&
m.isSelfReferencedObj(live, target, app.GetName(), trackingMethod, installationID)
m.isSelfReferencedObj(live, target, app.GetName(), v1alpha1.TrackingMethod(trackingMethod), installationID)
}),
sync.WithManifestValidation(!syncOp.SyncOptions.HasOption(common.SyncOptionsDisableValidation)),
sync.WithSyncWaveHook(delayBetweenSyncWaves),

View File

@@ -135,7 +135,7 @@ been deprecated for some time and is no longer available in Argo CD 3.0.
To check whether you have any repositories configured in argocd-cm, run the following command:
```shell
kubectl get cm argocd-cm -o=jsonpath="[{.data.repositories}, {.data['repository.credentials']}, {.data['helm.repositories']}]"
kubectl get cm argocd-cm -o=jsonpath="[{.data.repositories}, {.data['repository\.credentials']}, {.data['helm\.repositories']}]"
```
If you have no repositories configured in argocd-cm, the output will be `[, , ]`, and you are not impacted by this
@@ -319,7 +319,7 @@ Example of a status field in the Application CR persisting health:
status:
health:
status: Healthy
lastTransitionTime: "2025-01-01T00:00:00Z"
lastTransitionTime: '2025-01-01T00:00:00Z'
resources:
- group: apps
health:
@@ -339,7 +339,7 @@ Example of a status field in the Application CR _not_ persisting health:
status:
health:
status: Healthy
lastTransitionTime: "2025-01-01T00:00:00Z"
lastTransitionTime: '2025-01-01T00:00:00Z'
resourceHealthSource: appTree
resources:
- group: apps
@@ -373,6 +373,9 @@ kubectl get applications.argoproj.io <my app> -n argocd -o jsonpath='{.status.re
Any tools or CLI commands parsing the `.status.resources[].health` need to be updated to use the argocd cli/API to get the health status.
!!! note
The application list API (argocd app list) no longer returns the individual health status of resources.
```sh
argocd app get <my app> -o json
```
@@ -434,4 +437,30 @@ data:
ignoreResourceStatusField: crd
```
More details for ignored resource updates in the [Diffing customization](../../user-guide/diffing.md) documentation.
### Removing default ignores of `preserveUnknownFields` for CRD
The `spec.preserveUnknownFields` has been deprecated in favor of `x-kubernetes-preserve-unknown-fields: true` in the CRD v1.
This means that CRD deployed with Argo CD containing `spec.preserveUnknownFields: false` will be out of sync. To address this problem,
the `preserveUnknownFields` field can be removed from the CRD spec.
Until this is completed, if you want your Application not to be out of sync, you can add the following configuration to the Application manifest.
```yaml
spec:
ignoreDifferences:
- group: apiextensions.k8s.io
kind: CustomResourceDefinition
jsonPointers:
- /spec/preserveUnknownFields
```
You can also configure it globally in the `argocd-cm` ConfigMap.
```yaml
resource.customizations.ignoreDifferences.apiextensions.k8s.io_CustomResourceDefinition: |
jsonPointers:
- /spec/preserveUnknownFields
```
More details for ignored resource updates in the [Diffing customization](../../user-guide/diffing.md) documentation.

4
go.mod
View File

@@ -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.34.0
github.com/argoproj/gitops-engine v0.7.1-0.20250314164314-7258614f5041
github.com/argoproj/gitops-engine v0.7.1-0.20250520182409-89c110b5952e
github.com/argoproj/notifications-engine v0.4.1-0.20250309174002-87bf0576a872
github.com/argoproj/pkg v0.13.7-0.20250305113207-cbc37dc61de5
github.com/aws/aws-sdk-go v1.55.6
@@ -90,7 +90,7 @@ require (
go.uber.org/automaxprocs v1.6.0
golang.org/x/crypto v0.36.0
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f
golang.org/x/net v0.37.0
golang.org/x/net v0.38.0
golang.org/x/oauth2 v0.28.0
golang.org/x/sync v0.12.0
golang.org/x/term v0.30.0

8
go.sum
View File

@@ -114,8 +114,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.20250314164314-7258614f5041 h1:2QuxuGZ7ZLokBqmwr02MHhI2N3ffShms/IxSbvaFtVM=
github.com/argoproj/gitops-engine v0.7.1-0.20250314164314-7258614f5041/go.mod h1:4KL2HCRSGA/yLM8nOCcv+NbFsYohxmT9Lb47kWFhWYw=
github.com/argoproj/gitops-engine v0.7.1-0.20250520182409-89c110b5952e h1:65x5+7Vz3HPjFoj7+mFyCckgHrAhPwy4rnDp/AveD18=
github.com/argoproj/gitops-engine v0.7.1-0.20250520182409-89c110b5952e/go.mod h1:duVhxDW7M7M7+19IBCVth2REOS11gmqzTWwj4u8N7aQ=
github.com/argoproj/notifications-engine v0.4.1-0.20250309174002-87bf0576a872 h1:ADGAdyN9ty0+RmTT/yn+xV9vwkqvLn9O1ccqeP0Zeas=
github.com/argoproj/notifications-engine v0.4.1-0.20250309174002-87bf0576a872/go.mod h1:d1RazGXWvKRFv9//rg4MRRR7rbvbE7XLgTSMT5fITTE=
github.com/argoproj/pkg v0.13.7-0.20250305113207-cbc37dc61de5 h1:YBoLSjpoaJXaXAldVvBRKJuOPvIXz9UOv6S96gMJM/Q=
@@ -979,8 +979,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
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=

View File

@@ -35,6 +35,10 @@ cd ${SRCROOT}/manifests/base && $KUSTOMIZE edit set image quay.io/argoproj/argoc
cd ${SRCROOT}/manifests/ha/base && $KUSTOMIZE edit set image quay.io/argoproj/argocd=${IMAGE_NAMESPACE}/argocd:${IMAGE_TAG}
cd ${SRCROOT}/manifests/core-install && $KUSTOMIZE edit set image quay.io/argoproj/argocd=${IMAGE_NAMESPACE}/argocd:${IMAGE_TAG}
# Because commit-server is added as a resource outside the base, we have to explicitly set the image override here.
# If/when commit-server is added to the base, this can be removed.
cd ${SRCROOT}/manifests/base/commit-server && $KUSTOMIZE edit set image quay.io/argoproj/argocd=${IMAGE_NAMESPACE}/argocd:${IMAGE_TAG}
echo "${AUTOGENMSG}" > "${SRCROOT}/manifests/install.yaml"
$KUSTOMIZE build "${SRCROOT}/manifests/cluster-install" >> "${SRCROOT}/manifests/install.yaml"

View File

@@ -6,3 +6,10 @@ resources:
- argocd-commit-server-deployment.yaml
- argocd-commit-server-service.yaml
- argocd-commit-server-network-policy.yaml
# Because commit-server is added as a resource outside the base, we have to explicitly set the image override here.
# If/when commit-server is added to the base, this can be removed.
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v3.0.4

View File

@@ -5,7 +5,7 @@ kind: Kustomization
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v3.0.0
newTag: v3.0.4
resources:
- ./application-controller
- ./dex

View File

@@ -24609,7 +24609,7 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -24735,7 +24735,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.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -24781,7 +24781,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.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -24885,7 +24885,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -25158,7 +25158,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -25210,7 +25210,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -25540,7 +25540,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -24577,7 +24577,7 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -24697,7 +24697,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -24970,7 +24970,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -25022,7 +25022,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -25352,7 +25352,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
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: v3.0.0
newTag: v3.0.4

View File

@@ -12,7 +12,7 @@ patches:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v3.0.0
newTag: v3.0.4
resources:
- ../../base/application-controller
- ../../base/applicationset-controller

View File

@@ -701,6 +701,10 @@ data:
stats enable
stats uri /stats
stats refresh 10s
# Additional configuration
global
maxconn 4096
haproxy_init.sh: |
HAPROXY_CONF=/data/haproxy.cfg
cp /readonly/haproxy.cfg "$HAPROXY_CONF"
@@ -1092,7 +1096,7 @@ spec:
prometheus.io/port: "9101"
prometheus.io/scrape: "true"
prometheus.io/path: "/metrics"
checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54
checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953
spec:
# Needed when using unmodified rbac-setup.yml

View File

@@ -21,6 +21,9 @@ redis-ha:
checkInterval: 3s
metrics:
enabled: true
extraConfig: |
global
maxconn 4096
serviceAccount:
automountToken: true
image:

View File

@@ -25039,7 +25039,8 @@ data:
1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge
2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend
stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n"
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n#
Additional configuration\nglobal\n maxconn 4096\n"
haproxy_init.sh: |
HAPROXY_CONF=/data/haproxy.cfg
cp /readonly/haproxy.cfg "$HAPROXY_CONF"
@@ -25974,7 +25975,7 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -26100,7 +26101,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.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -26146,7 +26147,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.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -26273,7 +26274,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -26369,7 +26370,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -26429,7 +26430,7 @@ spec:
template:
metadata:
annotations:
checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54
checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953
prometheus.io/path: /metrics
prometheus.io/port: "9101"
prometheus.io/scrape: "true"
@@ -26493,7 +26494,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -26792,7 +26793,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -26844,7 +26845,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -27218,7 +27219,7 @@ spec:
key: server.sync.replace.allowed
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -27584,7 +27585,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -25030,7 +25030,8 @@ data:
1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge
2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend
stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n"
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n#
Additional configuration\nglobal\n maxconn 4096\n"
haproxy_init.sh: |
HAPROXY_CONF=/data/haproxy.cfg
cp /readonly/haproxy.cfg "$HAPROXY_CONF"
@@ -25944,7 +25945,7 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -26087,7 +26088,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -26183,7 +26184,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -26243,7 +26244,7 @@ spec:
template:
metadata:
annotations:
checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54
checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953
prometheus.io/path: /metrics
prometheus.io/port: "9101"
prometheus.io/scrape: "true"
@@ -26307,7 +26308,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -26606,7 +26607,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -26658,7 +26659,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -27032,7 +27033,7 @@ spec:
key: server.sync.replace.allowed
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -27398,7 +27399,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -926,7 +926,8 @@ data:
1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge
2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend
stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n"
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n#
Additional configuration\nglobal\n maxconn 4096\n"
haproxy_init.sh: |
HAPROXY_CONF=/data/haproxy.cfg
cp /readonly/haproxy.cfg "$HAPROXY_CONF"
@@ -1861,7 +1862,7 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -1987,7 +1988,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.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -2033,7 +2034,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.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -2160,7 +2161,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -2256,7 +2257,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -2316,7 +2317,7 @@ spec:
template:
metadata:
annotations:
checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54
checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953
prometheus.io/path: /metrics
prometheus.io/port: "9101"
prometheus.io/scrape: "true"
@@ -2380,7 +2381,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -2679,7 +2680,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -2731,7 +2732,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -3105,7 +3106,7 @@ spec:
key: server.sync.replace.allowed
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -3471,7 +3472,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -917,7 +917,8 @@ data:
1\n use-server R2 if { srv_is_up(R2) } { nbsrv(check_if_redis_is_master_2) ge
2 }\n server R2 argocd-redis-ha-announce-2:6379 check inter 3s fall 1 rise 1\nfrontend
stats\n mode http\n bind :9101 \n http-request use-service prometheus-exporter
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n"
if { path /metrics }\n stats enable\n stats uri /stats\n stats refresh 10s\n#
Additional configuration\nglobal\n maxconn 4096\n"
haproxy_init.sh: |
HAPROXY_CONF=/data/haproxy.cfg
cp /readonly/haproxy.cfg "$HAPROXY_CONF"
@@ -1831,7 +1832,7 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -1974,7 +1975,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -2070,7 +2071,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -2130,7 +2131,7 @@ spec:
template:
metadata:
annotations:
checksum/config: e34e8124c38bcfd2f16e75620bbde30158686692b13bc449eecc44c51b207d54
checksum/config: cd6508bdf9819601c454d0cc491fb77a209e3a88761d92514d105b6681829953
prometheus.io/path: /metrics
prometheus.io/port: "9101"
prometheus.io/scrape: "true"
@@ -2194,7 +2195,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -2493,7 +2494,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -2545,7 +2546,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -2919,7 +2920,7 @@ spec:
key: server.sync.replace.allowed
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -3285,7 +3286,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -25069,7 +25069,7 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -25195,7 +25195,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.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -25241,7 +25241,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.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -25368,7 +25368,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -25464,7 +25464,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -25566,7 +25566,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -25839,7 +25839,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -25891,7 +25891,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -26263,7 +26263,7 @@ spec:
key: server.sync.replace.allowed
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -26629,7 +26629,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

16
manifests/install.yaml generated
View File

@@ -25037,7 +25037,7 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -25180,7 +25180,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -25276,7 +25276,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -25378,7 +25378,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -25651,7 +25651,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -25703,7 +25703,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -26075,7 +26075,7 @@ spec:
key: server.sync.replace.allowed
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -26441,7 +26441,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -956,7 +956,7 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -1082,7 +1082,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.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1128,7 +1128,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.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -1255,7 +1255,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -1351,7 +1351,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -1453,7 +1453,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -1726,7 +1726,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1778,7 +1778,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -2150,7 +2150,7 @@ spec:
key: server.sync.replace.allowed
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2516,7 +2516,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -924,7 +924,7 @@ spec:
key: applicationsetcontroller.requeue.after
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-applicationset-controller
ports:
@@ -1067,7 +1067,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: copyutil
securityContext:
@@ -1163,7 +1163,7 @@ spec:
key: notificationscontroller.repo.server.plaintext
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
tcpSocket:
@@ -1265,7 +1265,7 @@ spec:
- argocd
- admin
- redis-initial-password
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: IfNotPresent
name: secret-init
securityContext:
@@ -1538,7 +1538,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1590,7 +1590,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
name: copyutil
securityContext:
allowPrivilegeEscalation: false
@@ -1962,7 +1962,7 @@ spec:
key: server.sync.replace.allowed
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -2328,7 +2328,7 @@ spec:
optional: true
- name: KUBECACHEDIR
value: /tmp/kubecache
image: quay.io/argoproj/argocd:v3.0.0
image: quay.io/argoproj/argocd:v3.0.4
imagePullPolicy: Always
name: argocd-application-controller
ports:

View File

@@ -130,6 +130,7 @@ nav:
- operator-manual/server-commands/additional-configuration-method.md
- Upgrading:
- operator-manual/upgrading/overview.md
- operator-manual/upgrading/2.14-3.0.md
- operator-manual/upgrading/2.13-2.14.md
- operator-manual/upgrading/2.12-2.13.md
- operator-manual/upgrading/2.11-2.12.md

View File

@@ -102,6 +102,12 @@ func (id IgnoreDifferences) Equals(other IgnoreDifferences) bool {
type TrackingMethod string
const (
TrackingMethodAnnotation TrackingMethod = "annotation"
TrackingMethodLabel TrackingMethod = "label"
TrackingMethodAnnotationAndLabel TrackingMethod = "annotation+label"
)
// ResourceIgnoreDifferences contains resource filter and list of json paths which should be ignored during comparison with live state.
type ResourceIgnoreDifferences struct {
Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"`

View File

@@ -18,7 +18,6 @@ import (
appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v3/reposerver/apiclient"
"github.com/argoproj/argo-cd/v3/util/argo"
cacheutil "github.com/argoproj/argo-cd/v3/util/cache"
"github.com/argoproj/argo-cd/v3/util/env"
"github.com/argoproj/argo-cd/v3/util/hash"
@@ -305,7 +304,7 @@ func manifestCacheKey(revision string, appSrc *appv1.ApplicationSource, srcRefs
func trackingKey(appLabelKey string, trackingMethod string) string {
trackingKey := appLabelKey
if text.FirstNonEmpty(trackingMethod, string(argo.TrackingMethodLabel)) != string(argo.TrackingMethodLabel) {
if text.FirstNonEmpty(trackingMethod, string(appv1.TrackingMethodLabel)) != string(appv1.TrackingMethodLabel) {
trackingKey = trackingMethod + ":" + trackingKey
}
return trackingKey
@@ -399,7 +398,7 @@ func (c *Cache) DeleteManifests(revision string, appSrc *appv1.ApplicationSource
func appDetailsCacheKey(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, trackingMethod appv1.TrackingMethod, refSourceCommitSHAs ResolvedRevisions) string {
if trackingMethod == "" {
trackingMethod = argo.TrackingMethodLabel
trackingMethod = appv1.TrackingMethodLabel
}
return fmt.Sprintf("appdetails|%s|%d|%s", revision, appSourceKey(appSrc, srcRefs, refSourceCommitSHAs), trackingMethod)
}

View File

@@ -7,8 +7,18 @@ if obj.status == nil or obj.status.conditions == nil then
end
-- Sort conditions by lastTransitionTime, from old to new.
-- Ensure that conditions with nil lastTransitionTime are always sorted after those with non-nil values.
table.sort(obj.status.conditions, function(a, b)
return a.lastTransitionTime < b.lastTransitionTime
-- Nil values are considered "less than" non-nil values.
-- This means that conditions with nil lastTransitionTime will be sorted to the end.
if a.lastTransitionTime == nil then
return false
elseif b.lastTransitionTime == nil then
return true
else
-- If both have non-nil lastTransitionTime, compare them normally.
return a.lastTransitionTime < b.lastTransitionTime
end
end)
for _, condition in ipairs(obj.status.conditions) do

View File

@@ -14,4 +14,8 @@ tests:
- healthStatus:
status: Degraded
message: "Has Errors: Waiting for foo/keycloak-1 due to CrashLoopBackOff: back-off 10s"
inputPath: testdata/degraded.yaml
inputPath: testdata/degraded.yaml
- healthStatus:
status: Healthy
message: ""
inputPath: testdata/nil_last_transition_time.yaml

View File

@@ -0,0 +1,13 @@
apiVersion: k8s.keycloak.org/v1alpha1
kind: Keycloak
metadata:
name: keycloak-23
namespace: keycloak
status:
conditions:
- type: Ready
status: "True"
lastTransitionTime: "2025-05-06T12:00:00Z" # Non-nil lastTransitionTime
- type: HasErrors
status: "False"
lastTransitionTime: null # Nil lastTransitionTime

View File

@@ -528,6 +528,10 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan
if err != nil {
return fmt.Errorf("error getting installation ID: %w", err)
}
trackingMethod, err := s.settingsMgr.GetTrackingMethod()
if err != nil {
return fmt.Errorf("error getting trackingMethod from settings: %w", err)
}
manifestInfo, err := client.GenerateManifest(ctx, &apiclient.ManifestRequest{
Repo: repo,
@@ -542,7 +546,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan
ApiVersions: argo.APIResourcesToStrings(apiResources, true),
HelmRepoCreds: helmCreds,
HelmOptions: helmOptions,
TrackingMethod: string(argo.GetTrackingMethod(s.settingsMgr)),
TrackingMethod: trackingMethod,
EnabledSourceTypes: enableGenerateManifests,
ProjectName: proj.Name,
ProjectSourceRepos: proj.Spec.SourceRepos,
@@ -613,6 +617,11 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get
return fmt.Errorf("error getting app instance label key from settings: %w", err)
}
trackingMethod, err := s.settingsMgr.GetTrackingMethod()
if err != nil {
return fmt.Errorf("error getting trackingMethod from settings: %w", err)
}
config, err := s.getApplicationClusterConfig(ctx, a)
if err != nil {
return fmt.Errorf("error getting application cluster config: %w", err)
@@ -662,7 +671,7 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get
ApiVersions: argo.APIResourcesToStrings(apiResources, true),
HelmRepoCreds: helmCreds,
HelmOptions: helmOptions,
TrackingMethod: string(argo.GetTrackingMethod(s.settingsMgr)),
TrackingMethod: trackingMethod,
EnabledSourceTypes: enableGenerateManifests,
ProjectName: proj.Name,
ProjectSourceRepos: proj.Spec.SourceRepos,
@@ -777,6 +786,10 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*v1a
if err != nil {
return fmt.Errorf("error getting kustomize settings: %w", err)
}
trackingMethod, err := s.settingsMgr.GetTrackingMethod()
if err != nil {
return fmt.Errorf("error getting trackingMethod from settings: %w", err)
}
kustomizeOptions, err := kustomizeSettings.GetOptions(a.Spec.GetSource())
if err != nil {
return fmt.Errorf("error getting kustomize settings options: %w", err)
@@ -788,7 +801,7 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*v1a
KustomizeOptions: kustomizeOptions,
Repos: helmRepos,
NoCache: true,
TrackingMethod: string(argo.GetTrackingMethod(s.settingsMgr)),
TrackingMethod: trackingMethod,
EnabledSourceTypes: enabledSourceTypes,
HelmOptions: helmOptions,
})

View File

@@ -1009,7 +1009,7 @@ func TestDuplicatedClusterResourcesAnnotationTracking(t *testing.T) {
// (i.e. resources where metadata.namespace is set). Before the bugfix, this test would fail with a diff in the
// tracking annotation.
Given(t).
SetTrackingMethod(string(argo.TrackingMethodAnnotation)).
SetTrackingMethod(string(TrackingMethodAnnotation)).
Path("duplicated-resources").
When().
CreateApp().
@@ -2600,7 +2600,7 @@ func TestSwitchTrackingMethod(t *testing.T) {
ctx := Given(t)
ctx.
SetTrackingMethod(string(argo.TrackingMethodAnnotation)).
SetTrackingMethod(string(TrackingMethodAnnotation)).
Path("deployment").
When().
CreateApp().
@@ -2637,7 +2637,7 @@ func TestSwitchTrackingMethod(t *testing.T) {
Expect(SyncStatusIs(SyncStatusCodeSynced)).
Expect(HealthIs(health.HealthStatusHealthy)).
When().
SetTrackingMethod(string(argo.TrackingMethodLabel)).
SetTrackingMethod(string(TrackingMethodLabel)).
Sync().
Then().
Expect(OperationPhaseIs(OperationSucceeded)).
@@ -2692,7 +2692,7 @@ func TestSwitchTrackingMethod(t *testing.T) {
func TestSwitchTrackingLabel(t *testing.T) {
ctx := Given(t)
require.NoError(t, fixture.SetTrackingMethod(string(argo.TrackingMethodLabel)))
require.NoError(t, fixture.SetTrackingMethod(string(TrackingMethodLabel)))
ctx.
Path("deployment").
When().
@@ -2786,7 +2786,7 @@ func TestSwitchTrackingLabel(t *testing.T) {
func TestAnnotationTrackingExtraResources(t *testing.T) {
ctx := Given(t)
require.NoError(t, fixture.SetTrackingMethod(string(argo.TrackingMethodAnnotation)))
require.NoError(t, fixture.SetTrackingMethod(string(TrackingMethodAnnotation)))
ctx.
Path("deployment").
When().
@@ -2952,7 +2952,7 @@ data:
func TestInstallationID(t *testing.T) {
ctx := Given(t)
ctx.
SetTrackingMethod(string(argo.TrackingMethodAnnotation)).
SetTrackingMethod(string(TrackingMethodAnnotation)).
And(func() {
_, err := fixture.KubeClientset.CoreV1().ConfigMaps(fixture.DeploymentNamespace()).Create(
t.Context(), &corev1.ConfigMap{
@@ -3029,3 +3029,46 @@ func TestDeletionConfirmation(t *testing.T) {
When().ConfirmDeletion().
Then().Expect(DoesNotExist())
}
func TestLastTransitionTimeUnchangedError(t *testing.T) {
// Ensure that, if the health status hasn't changed, the lastTransitionTime is not updated.
ctx := Given(t)
ctx.
Path(guestbookPath).
When().
And(func() {
// Manually create an application with an outdated reconciledAt field
manifest := fmt.Sprintf(`
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: %s
spec:
project: default
source:
repoURL: %s
path: guestbook
targetRevision: HEAD
destination:
server: https://non-existent-cluster
namespace: default
status:
reconciledAt: "2023-01-01T00:00:00Z"
health:
status: Unknown
lastTransitionTime: "2023-01-01T00:00:00Z"
`, ctx.AppName(), fixture.RepoURL(fixture.RepoURLTypeFile))
_, err := fixture.RunWithStdin(manifest, "", "kubectl", "apply", "-n", fixture.ArgoCDNamespace, "-f", "-")
require.NoError(t, err)
}).
Refresh(RefreshTypeNormal).
Then().
And(func(app *Application) {
// Verify the health status is still Unknown
assert.Equal(t, health.HealthStatusUnknown, app.Status.Health.Status)
// Verify the lastTransitionTime has not been updated
assert.Equal(t, "2023-01-01T00:00:00Z", app.Status.Health.LastTransitionTime.UTC().Format(time.RFC3339))
})
}

View File

@@ -65,7 +65,7 @@ func TestMultiSourceAppWithHelmExternalValueFiles(t *testing.T) {
RepoURL: RepoURL(RepoURLTypeFile),
Ref: "values",
}, {
RepoURL: "https://github.com/argoproj/argocd-example-apps.git",
RepoURL: RepoURL(RepoURLTypeFile),
TargetRevision: "HEAD",
Path: "helm-guestbook",
Helm: &ApplicationSourceHelm{
@@ -107,9 +107,13 @@ func TestMultiSourceAppWithHelmExternalValueFiles(t *testing.T) {
for _, r := range app.Status.Resources {
statusByName[r.Name] = r.Status
}
// check if the app has 3 resources, guestbook and 2 pods
assert.Len(t, statusByName, 1)
assert.Equal(t, SyncStatusCodeSynced, statusByName["helm-guestbook"])
assert.Equal(t, SyncStatusCodeSynced, statusByName["guestbook-ui"])
// Confirm that the deployment has 3 replicas.
output, err := Run("", "kubectl", "get", "deployment", "guestbook-ui", "-n", DeploymentNamespace(), "-o", "jsonpath={.spec.replicas}")
require.NoError(t, err)
assert.Equal(t, "3", output, "Expected 3 replicas for the helm-guestbook deployment")
})
}

View File

@@ -11,7 +11,6 @@ import (
. "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
. "github.com/argoproj/argo-cd/v3/test/e2e/fixture"
. "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app"
"github.com/argoproj/argo-cd/v3/util/argo"
)
func TestClusterRoleBinding(t *testing.T) {
@@ -30,7 +29,7 @@ func TestClusterRoleBinding(t *testing.T) {
assert.Empty(t, diffOutput)
}).
When().
SetTrackingMethod(string(argo.TrackingMethodAnnotation)).
SetTrackingMethod(string(TrackingMethodAnnotation)).
Sync().
Then().
Expect(OperationPhaseIs(OperationSucceeded)).

View File

@@ -18,7 +18,6 @@ import (
"k8s.io/client-go/tools/clientcmd"
"github.com/argoproj/argo-cd/v3/common"
"github.com/argoproj/argo-cd/v3/util/argo"
"github.com/argoproj/argo-cd/v3/util/clusterauth"
"github.com/argoproj/gitops-engine/pkg/health"
@@ -54,7 +53,7 @@ func TestDeployment(t *testing.T) {
func TestDeploymentWithAnnotationTrackingMode(t *testing.T) {
ctx := Given(t)
require.NoError(t, SetTrackingMethod(string(argo.TrackingMethodAnnotation)))
require.NoError(t, SetTrackingMethod(string(TrackingMethodAnnotation)))
ctx.
Path("deployment").
When().
@@ -77,7 +76,7 @@ func TestDeploymentWithAnnotationTrackingMode(t *testing.T) {
func TestDeploymentWithLabelTrackingMode(t *testing.T) {
ctx := Given(t)
require.NoError(t, SetTrackingMethod(string(argo.TrackingMethodLabel)))
require.NoError(t, SetTrackingMethod(string(TrackingMethodLabel)))
ctx.
Path("deployment").
When().

View File

@@ -1,6 +1,8 @@
package project
import (
"time"
"github.com/stretchr/testify/require"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
@@ -81,5 +83,6 @@ func (a *Actions) runCli(args ...string) {
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}

View File

@@ -3,6 +3,7 @@ package project
import (
"context"
"errors"
"time"
"github.com/stretchr/testify/require"
@@ -64,5 +65,6 @@ func (c *Consequences) Given() *Context {
}
func (c *Consequences) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return c.actions
}

View File

@@ -2,6 +2,7 @@ package project
import (
"testing"
"time"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
"github.com/argoproj/argo-cd/v3/util/env"
@@ -45,5 +46,6 @@ func (c *Context) And(block func()) *Context {
}
func (c *Context) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return &Actions{context: c}
}

View File

@@ -1,6 +1,8 @@
package admin
import (
"time"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
)
@@ -63,5 +65,6 @@ func (a *Actions) runCliWithStdin(stdin string, args ...string) {
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}

View File

@@ -1,6 +1,9 @@
package admin
import (
"time"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
. "github.com/argoproj/argo-cd/v3/test/e2e/fixture/admin/utils"
)
@@ -33,5 +36,6 @@ func (c *Consequences) Given() *Context {
}
func (c *Consequences) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return c.actions
}

View File

@@ -2,6 +2,7 @@ package admin
import (
"testing"
"time"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
"github.com/argoproj/argo-cd/v3/util/env"
@@ -39,5 +40,6 @@ func (c *Context) And(block func()) *Context {
}
func (c *Context) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return &Actions{context: c}
}

View File

@@ -6,6 +6,7 @@ import (
"os"
"slices"
"strconv"
"time"
rbacv1 "k8s.io/api/rbac/v1"
@@ -492,6 +493,7 @@ func (a *Actions) And(block func()) *Actions {
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a, 15}
}

View File

@@ -101,6 +101,7 @@ func (c *Consequences) Given() *Context {
}
func (c *Consequences) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return c.actions
}

View File

@@ -11,7 +11,6 @@ import (
"github.com/argoproj/argo-cd/v3/test/e2e/fixture/certs"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture/gpgkeys"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture/repos"
"github.com/argoproj/argo-cd/v3/util/argo"
"github.com/argoproj/argo-cd/v3/util/env"
"github.com/argoproj/argo-cd/v3/util/settings"
)
@@ -88,7 +87,7 @@ func GivenWithSameState(t *testing.T) *Context {
timeout: timeout,
project: "default",
prune: true,
trackingMethod: argo.TrackingMethodLabel,
trackingMethod: v1alpha1.TrackingMethodLabel,
}
}
@@ -349,6 +348,7 @@ func (c *Context) And(block func()) *Context {
}
func (c *Context) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return &Actions{context: c}
}

View File

@@ -61,6 +61,7 @@ func (a *Actions) And(block func()) *Actions {
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}

View File

@@ -71,6 +71,7 @@ func (c *Consequences) Given() *Context {
}
func (c *Consequences) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return c.actions
}

View File

@@ -29,6 +29,7 @@ func Given(t *testing.T) *Context {
}
func (c *Context) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return &Actions{context: c}
}

View File

@@ -5,6 +5,7 @@ import (
"errors"
"log"
"strings"
"time"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
@@ -131,6 +132,7 @@ func (a *Actions) DeleteByServer() *Actions {
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}

View File

@@ -3,6 +3,7 @@ package cluster
import (
"context"
"errors"
"time"
clusterpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster"
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
@@ -54,5 +55,6 @@ func (c *Consequences) Given() *Context {
}
func (c *Consequences) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return c.actions
}

View File

@@ -2,6 +2,7 @@ package cluster
import (
"testing"
"time"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
"github.com/argoproj/argo-cd/v3/util/env"
@@ -59,6 +60,7 @@ func (c *Context) And(block func()) *Context {
}
func (c *Context) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return &Actions{context: c}
}

View File

@@ -66,6 +66,9 @@ const (
PluginSockFilePath = "/app/config/plugin"
E2ETestPrefix = "e2e-test-"
// Account for batch events processing (set to 1ms in e2e tests)
WhenThenSleepInterval = 5 * time.Millisecond
)
const (

View File

@@ -1,6 +1,8 @@
package notification
import (
"time"
"github.com/stretchr/testify/require"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
@@ -24,6 +26,7 @@ func (a *Actions) SetParamInNotificationConfigMap(key, value string) *Actions {
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}

View File

@@ -2,6 +2,7 @@ package notification
import (
"context"
"time"
"github.com/argoproj/argo-cd/v3/pkg/apiclient/notification"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
@@ -53,6 +54,7 @@ func (c *Consequences) listTemplates() (*notification.TemplateList, error) {
}
func (c *Consequences) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return c.actions
}

View File

@@ -2,6 +2,7 @@ package notification
import (
"testing"
"time"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
)
@@ -23,5 +24,6 @@ func (c *Context) And(block func()) *Context {
}
func (c *Context) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return &Actions{context: c}
}

View File

@@ -3,6 +3,7 @@ package project
import (
"context"
"strings"
"time"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -112,6 +113,7 @@ func (a *Actions) And(block func()) *Actions {
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}

View File

@@ -2,6 +2,7 @@ package project
import (
"context"
"time"
"github.com/argoproj/argo-cd/v3/pkg/apiclient/project"
@@ -43,5 +44,6 @@ func (c *Consequences) Given() *Context {
}
func (c *Consequences) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return c.actions
}

View File

@@ -2,6 +2,7 @@ package project
import (
"testing"
"time"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
"github.com/argoproj/argo-cd/v3/util/env"
@@ -68,5 +69,6 @@ func (c *Context) And(block func()) *Context {
}
func (c *Context) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return &Actions{context: c}
}

View File

@@ -2,6 +2,7 @@ package repos
import (
"log"
"time"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
)
@@ -77,6 +78,7 @@ func (a *Actions) Project(project string) *Actions {
func (a *Actions) Then() *Consequences {
a.context.t.Helper()
time.Sleep(fixture.WhenThenSleepInterval)
return &Consequences{a.context, a}
}

View File

@@ -3,6 +3,7 @@ package repos
import (
"context"
"errors"
"time"
repositorypkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/repository"
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
@@ -54,5 +55,6 @@ func (c *Consequences) Given() *Context {
}
func (c *Consequences) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return c.actions
}

View File

@@ -2,6 +2,7 @@ package repos
import (
"testing"
"time"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
"github.com/argoproj/argo-cd/v3/util/env"
@@ -54,6 +55,7 @@ func (c *Context) And(block func()) *Context {
}
func (c *Context) When() *Actions {
time.Sleep(fixture.WhenThenSleepInterval)
return &Actions{context: c}
}

View File

@@ -0,0 +1,3 @@
apiVersion: v2
version: 1.0.0
name: helm-guestbook

View File

@@ -0,0 +1,23 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: guestbook-ui
labels:
test: "true"
spec:
replicas: {{ .Values.replicas }}
revisionHistoryLimit: 3
selector:
matchLabels:
app: guestbook-ui
template:
metadata:
labels:
app: guestbook-ui
spec:
containers:
- image: quay.io/argoprojlabs/argocd-e2e-container:0.2
imagePullPolicy: IfNotPresent
name: guestbook-ui
ports:
- containerPort: 80

View File

@@ -0,0 +1,10 @@
apiVersion: v1
kind: Service
metadata:
name: guestbook-ui
spec:
ports:
- port: 80
targetPort: 80
selector:
app: guestbook-ui

View File

@@ -0,0 +1 @@
replicas: 1

View File

@@ -1,5 +1,6 @@
import {GitUrl} from 'git-url-parse';
import {isSHA} from './revision';
import {isValidURL} from '../../shared/utils';
const GitUrlParse = require('git-url-parse');
@@ -19,7 +20,11 @@ export function repoUrl(url: string): string {
return null;
}
return `${protocol(parsed.protocol)}://${parsed.resource}/${parsed.owner}/${parsed.name}`;
const parsedUrl = `${protocol(parsed.protocol)}://${parsed.resource}/${parsed.owner}/${parsed.name}`;
if (!isValidURL(parsedUrl)) {
return null;
}
return parsedUrl;
} catch {
return null;
}

View File

@@ -773,6 +773,15 @@ func verifyGenerateManifests(
continue
}
trackingMethod, err := settingsMgr.GetTrackingMethod()
if err != nil {
conditions = append(conditions, argoappv1.ApplicationCondition{
Type: argoappv1.ApplicationConditionInvalidSpecError,
Message: fmt.Sprintf("Error getting trackingMethod: %v", err),
})
continue
}
verifySignature := false
if len(proj.Spec.SignatureKeys) > 0 && gpg.IsGPGEnabled() {
verifySignature = true
@@ -798,7 +807,7 @@ func verifyGenerateManifests(
ApiVersions: apiVersions,
HelmOptions: helmOptions,
HelmRepoCreds: repositoryCredentials,
TrackingMethod: string(GetTrackingMethod(settingsMgr)),
TrackingMethod: trackingMethod,
EnabledSourceTypes: enableGenerateManifests,
NoRevisionCache: true,
HasMultipleSources: app.Spec.HasMultipleSources(),

View File

@@ -12,13 +12,6 @@ import (
"github.com/argoproj/argo-cd/v3/common"
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v3/util/kube"
"github.com/argoproj/argo-cd/v3/util/settings"
)
const (
TrackingMethodAnnotation v1alpha1.TrackingMethod = "annotation"
TrackingMethodLabel v1alpha1.TrackingMethod = "label"
TrackingMethodAnnotationAndLabel v1alpha1.TrackingMethod = "annotation+label"
)
var (
@@ -52,17 +45,8 @@ func NewResourceTracking() ResourceTracking {
return &resourceTracking{}
}
// GetTrackingMethod retrieve tracking method from settings
func GetTrackingMethod(settingsMgr *settings.SettingsManager) v1alpha1.TrackingMethod {
tm, err := settingsMgr.GetTrackingMethod()
if err != nil || tm == "" {
return TrackingMethodAnnotation
}
return v1alpha1.TrackingMethod(tm)
}
func IsOldTrackingMethod(trackingMethod string) bool {
return trackingMethod == "" || trackingMethod == string(TrackingMethodLabel)
return trackingMethod == "" || trackingMethod == string(v1alpha1.TrackingMethodLabel)
}
func (rt *resourceTracking) getAppInstanceValue(un *unstructured.Unstructured, installationID string) *AppInstanceValue {
@@ -90,15 +74,15 @@ func (rt *resourceTracking) GetAppName(un *unstructured.Unstructured, key string
return ""
}
switch trackingMethod {
case TrackingMethodLabel:
case v1alpha1.TrackingMethodLabel:
label, err := kube.GetAppInstanceLabel(un, key)
if err != nil {
return ""
}
return label
case TrackingMethodAnnotationAndLabel:
case v1alpha1.TrackingMethodAnnotationAndLabel:
return retrieveAppInstanceValue()
case TrackingMethodAnnotation:
case v1alpha1.TrackingMethodAnnotation:
return retrieveAppInstanceValue()
default:
return retrieveAppInstanceValue()
@@ -110,7 +94,7 @@ func (rt *resourceTracking) GetAppName(un *unstructured.Unstructured, key string
// not be parsed, it returns nil.
func (rt *resourceTracking) GetAppInstance(un *unstructured.Unstructured, trackingMethod v1alpha1.TrackingMethod, instanceID string) *AppInstanceValue {
switch trackingMethod {
case TrackingMethodAnnotation, TrackingMethodAnnotationAndLabel:
case v1alpha1.TrackingMethodAnnotation, v1alpha1.TrackingMethodAnnotationAndLabel:
return rt.getAppInstanceValue(un, instanceID)
default:
return nil
@@ -152,15 +136,15 @@ func (rt *resourceTracking) SetAppInstance(un *unstructured.Unstructured, key, v
return kube.SetAppInstanceAnnotation(un, common.AnnotationKeyAppInstance, rt.BuildAppInstanceValue(appInstanceValue))
}
switch trackingMethod {
case TrackingMethodLabel:
case v1alpha1.TrackingMethodLabel:
err := kube.SetAppInstanceLabel(un, key, val)
if err != nil {
return fmt.Errorf("failed to set app instance label: %w", err)
}
return nil
case TrackingMethodAnnotation:
case v1alpha1.TrackingMethodAnnotation:
return setAppInstanceAnnotation()
case TrackingMethodAnnotationAndLabel:
case v1alpha1.TrackingMethodAnnotationAndLabel:
err := setAppInstanceAnnotation()
if err != nil {
return err

View File

@@ -12,6 +12,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/argoproj/argo-cd/v3/common"
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
)
func TestSetAppInstanceLabel(t *testing.T) {
@@ -24,9 +25,9 @@ func TestSetAppInstanceLabel(t *testing.T) {
resourceTracking := NewResourceTracking()
err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel, "")
err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app", "", v1alpha1.TrackingMethodLabel, "")
require.NoError(t, err)
app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodLabel, "")
app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, v1alpha1.TrackingMethodLabel, "")
assert.Equal(t, "my-app", app)
}
@@ -40,10 +41,10 @@ func TestSetAppInstanceAnnotation(t *testing.T) {
resourceTracking := NewResourceTracking()
err = resourceTracking.SetAppInstance(&obj, common.AnnotationKeyAppInstance, "my-app", "", TrackingMethodAnnotation, "")
err = resourceTracking.SetAppInstance(&obj, common.AnnotationKeyAppInstance, "my-app", "", v1alpha1.TrackingMethodAnnotation, "")
require.NoError(t, err)
app := resourceTracking.GetAppName(&obj, common.AnnotationKeyAppInstance, TrackingMethodAnnotation, "")
app := resourceTracking.GetAppName(&obj, common.AnnotationKeyAppInstance, v1alpha1.TrackingMethodAnnotation, "")
assert.Equal(t, "my-app", app)
}
@@ -56,10 +57,10 @@ func TestSetAppInstanceAnnotationAndLabel(t *testing.T) {
resourceTracking := NewResourceTracking()
err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodAnnotationAndLabel, "")
err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app", "", v1alpha1.TrackingMethodAnnotationAndLabel, "")
require.NoError(t, err)
app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotationAndLabel, "")
app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, v1alpha1.TrackingMethodAnnotationAndLabel, "")
assert.Equal(t, "my-app", app)
}
@@ -72,11 +73,11 @@ func TestSetAppInstanceAnnotationAndLabelLongName(t *testing.T) {
resourceTracking := NewResourceTracking()
err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app-with-an-extremely-long-name-that-is-over-sixty-three-characters", "", TrackingMethodAnnotationAndLabel, "")
err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "my-app-with-an-extremely-long-name-that-is-over-sixty-three-characters", "", v1alpha1.TrackingMethodAnnotationAndLabel, "")
require.NoError(t, err)
// the annotation should still work, so the name from GetAppName should not be truncated
app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotationAndLabel, "")
app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, v1alpha1.TrackingMethodAnnotationAndLabel, "")
assert.Equal(t, "my-app-with-an-extremely-long-name-that-is-over-sixty-three-characters", app)
// the label should be truncated to 63 characters
@@ -92,11 +93,11 @@ func TestSetAppInstanceAnnotationAndLabelLongNameBadEnding(t *testing.T) {
resourceTracking := NewResourceTracking()
err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "the-very-suspicious-name-with-precisely-sixty-three-characters-with-hyphen", "", TrackingMethodAnnotationAndLabel, "")
err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "the-very-suspicious-name-with-precisely-sixty-three-characters-with-hyphen", "", v1alpha1.TrackingMethodAnnotationAndLabel, "")
require.NoError(t, err)
// the annotation should still work, so the name from GetAppName should not be truncated
app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotationAndLabel, "")
app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, v1alpha1.TrackingMethodAnnotationAndLabel, "")
assert.Equal(t, "the-very-suspicious-name-with-precisely-sixty-three-characters-with-hyphen", app)
// the label should be truncated to 63 characters, AND the hyphen should be removed
@@ -112,7 +113,7 @@ func TestSetAppInstanceAnnotationAndLabelOutOfBounds(t *testing.T) {
resourceTracking := NewResourceTracking()
err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "----------------------------------------------------------------", "", TrackingMethodAnnotationAndLabel, "")
err = resourceTracking.SetAppInstance(&obj, common.LabelKeyAppInstance, "----------------------------------------------------------------", "", v1alpha1.TrackingMethodAnnotationAndLabel, "")
// this should error because it can't truncate to a valid value
assert.EqualError(t, err, "failed to set app instance label: unable to truncate label to not end with a special character")
}
@@ -127,7 +128,7 @@ func TestSetAppInstanceAnnotationNotFound(t *testing.T) {
resourceTracking := NewResourceTracking()
app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, TrackingMethodAnnotation, "")
app := resourceTracking.GetAppName(&obj, common.LabelKeyAppInstance, v1alpha1.TrackingMethodAnnotation, "")
assert.Equal(t, "", app)
}
@@ -186,15 +187,15 @@ func TestResourceIdNormalizer_Normalize(t *testing.T) {
// live object is a resource that has old style tracking label
liveObj := sampleResource(t)
err := rt.SetAppInstance(liveObj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel, "")
err := rt.SetAppInstance(liveObj, common.LabelKeyAppInstance, "my-app", "", v1alpha1.TrackingMethodLabel, "")
require.NoError(t, err)
// config object is a resource that has new style tracking annotation
configObj := sampleResource(t)
err = rt.SetAppInstance(configObj, common.AnnotationKeyAppInstance, "my-app2", "", TrackingMethodAnnotation, "")
err = rt.SetAppInstance(configObj, common.AnnotationKeyAppInstance, "my-app2", "", v1alpha1.TrackingMethodAnnotation, "")
require.NoError(t, err)
_ = rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(TrackingMethodAnnotation))
_ = rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(v1alpha1.TrackingMethodAnnotation))
// the normalization should affect add the new style annotation and drop old tracking label from live object
annotation, err := kube.GetAppInstanceAnnotation(configObj, common.AnnotationKeyAppInstance)
@@ -243,7 +244,7 @@ func TestResourceIdNormalizer_NormalizeCRD(t *testing.T) {
},
}
require.NoError(t, rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(TrackingMethodAnnotation)))
require.NoError(t, rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(v1alpha1.TrackingMethodAnnotation)))
// the normalization should not apply any changes to the live object
require.NotContains(t, liveObj.GetAnnotations(), common.AnnotationKeyAppInstance)
}
@@ -253,17 +254,17 @@ func TestResourceIdNormalizer_Normalize_ConfigHasOldLabel(t *testing.T) {
// live object is a resource that has old style tracking label
liveObj := sampleResource(t)
err := rt.SetAppInstance(liveObj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel, "")
err := rt.SetAppInstance(liveObj, common.LabelKeyAppInstance, "my-app", "", v1alpha1.TrackingMethodLabel, "")
require.NoError(t, err)
// config object is a resource that has new style tracking annotation
configObj := sampleResource(t)
err = rt.SetAppInstance(configObj, common.AnnotationKeyAppInstance, "my-app2", "", TrackingMethodAnnotation, "")
err = rt.SetAppInstance(configObj, common.AnnotationKeyAppInstance, "my-app2", "", v1alpha1.TrackingMethodAnnotation, "")
require.NoError(t, err)
err = rt.SetAppInstance(configObj, common.LabelKeyAppInstance, "my-app", "", TrackingMethodLabel, "")
err = rt.SetAppInstance(configObj, common.LabelKeyAppInstance, "my-app", "", v1alpha1.TrackingMethodLabel, "")
require.NoError(t, err)
_ = rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(TrackingMethodAnnotation))
_ = rt.Normalize(configObj, liveObj, common.LabelKeyAppInstance, string(v1alpha1.TrackingMethodAnnotation))
// the normalization should affect add the new style annotation and drop old tracking label from live object
annotation, err := kube.GetAppInstanceAnnotation(configObj, common.AnnotationKeyAppInstance)
@@ -274,5 +275,5 @@ func TestResourceIdNormalizer_Normalize_ConfigHasOldLabel(t *testing.T) {
}
func TestIsOldTrackingMethod(t *testing.T) {
assert.True(t, IsOldTrackingMethod(string(TrackingMethodLabel)))
assert.True(t, IsOldTrackingMethod(string(v1alpha1.TrackingMethodLabel)))
}

View File

@@ -424,11 +424,14 @@ func (m *nativeGitClient) Fetch(revision string) error {
func (m *nativeGitClient) LsFiles(path string, enableNewGitFileGlobbing bool) ([]string, error) {
if enableNewGitFileGlobbing {
// This is the new way with safer globbing
err := os.Chdir(m.root)
// evaluating the root path for symlinks
realRoot, err := filepath.EvalSymlinks(m.root)
if err != nil {
return nil, err
}
allFiles, err := doublestar.FilepathGlob(path)
// searching for the pattern inside the root path
allFiles, err := doublestar.FilepathGlob(filepath.Join(realRoot, path))
if err != nil {
return nil, err
}
@@ -442,10 +445,16 @@ func (m *nativeGitClient) LsFiles(path string, enableNewGitFileGlobbing bool) ([
if err != nil {
return nil, err
}
if strings.HasPrefix(absPath, m.root) {
files = append(files, file)
if strings.HasPrefix(absPath, realRoot) {
// removing the repository root prefix from the file path
relativeFile, err := filepath.Rel(realRoot, file)
if err != nil {
return nil, err
}
files = append(files, relativeFile)
} else {
log.Warnf("Absolute path for %s is outside of repository, removing it", file)
log.Warnf("Absolute path for %s is outside of repository, ignoring it", file)
}
}
return files, nil

View File

@@ -9,6 +9,7 @@ import (
"path"
"path/filepath"
"strings"
"sync"
"testing"
"time"
@@ -979,6 +980,65 @@ func Test_nativeGitClient_runCredentialedCmd(t *testing.T) {
}
}
func Test_LsFiles_RaceCondition(t *testing.T) {
// Create two temporary directories and initialize them as git repositories
tempDir1 := t.TempDir()
tempDir2 := t.TempDir()
client1, err := NewClient("file://"+tempDir1, NopCreds{}, true, false, "", "")
require.NoError(t, err)
client2, err := NewClient("file://"+tempDir2, NopCreds{}, true, false, "", "")
require.NoError(t, err)
err = client1.Init()
require.NoError(t, err)
err = client2.Init()
require.NoError(t, err)
// Add different files to each repository
file1 := filepath.Join(client1.Root(), "file1.txt")
err = os.WriteFile(file1, []byte("content1"), 0o644)
require.NoError(t, err)
err = runCmd(client1.Root(), "git", "add", "file1.txt")
require.NoError(t, err)
err = runCmd(client1.Root(), "git", "commit", "-m", "Add file1")
require.NoError(t, err)
file2 := filepath.Join(client2.Root(), "file2.txt")
err = os.WriteFile(file2, []byte("content2"), 0o644)
require.NoError(t, err)
err = runCmd(client2.Root(), "git", "add", "file2.txt")
require.NoError(t, err)
err = runCmd(client2.Root(), "git", "commit", "-m", "Add file2")
require.NoError(t, err)
// Assert that LsFiles returns the correct files when called sequentially
files1, err := client1.LsFiles("*", true)
require.NoError(t, err)
require.Contains(t, files1, "file1.txt")
files2, err := client2.LsFiles("*", true)
require.NoError(t, err)
require.Contains(t, files2, "file2.txt")
// Define a function to call LsFiles multiple times in parallel
var wg sync.WaitGroup
callLsFiles := func(client Client, expectedFile string) {
defer wg.Done()
for i := 0; i < 100; i++ {
files, err := client.LsFiles("*", true)
require.NoError(t, err)
require.Contains(t, files, expectedFile)
}
}
// Call LsFiles in parallel for both clients
wg.Add(2)
go callLsFiles(client1, "file1.txt")
go callLsFiles(client2, "file2.txt")
wg.Wait()
}
type mockCreds struct {
environ []string
environErr bool

View File

@@ -827,7 +827,11 @@ func (mgr *SettingsManager) GetTrackingMethod() (string, error) {
if err != nil {
return "", err
}
return argoCDCM.Data[settingsResourceTrackingMethodKey], nil
tm := argoCDCM.Data[settingsResourceTrackingMethodKey]
if tm == "" {
return string(v1alpha1.TrackingMethodAnnotation), nil
}
return tm, nil
}
func (mgr *SettingsManager) GetInstallationID() (string, error) {
@@ -983,7 +987,6 @@ func (mgr *SettingsManager) GetResourceOverrides() (map[string]v1alpha1.Resource
}
crdGK := "apiextensions.k8s.io/CustomResourceDefinition"
crdPrsvUnkn := "/spec/preserveUnknownFields"
switch diffOptions.IgnoreResourceStatusField {
case "", IgnoreResourceStatusInAll:
@@ -991,7 +994,6 @@ func (mgr *SettingsManager) GetResourceOverrides() (map[string]v1alpha1.Resource
log.Info("Ignore status for all objects")
case IgnoreResourceStatusInCRD:
addStatusOverrideToGK(resourceOverrides, crdGK)
addIgnoreDiffItemOverrideToGK(resourceOverrides, crdGK, crdPrsvUnkn)
case IgnoreResourceStatusInNone, "off", "false":
// Yaml 'off' non-string value can be converted to 'false'
// Support these cases because compareoptions is a yaml string in the config

View File

@@ -210,12 +210,39 @@ func TestInClusterServerAddressEnabledByDefault(t *testing.T) {
}
func TestGetAppInstanceLabelKey(t *testing.T) {
_, settingsManager := fixtures(map[string]string{
"application.instanceLabelKey": "testLabel",
t.Run("should get custom instanceLabelKey", func(t *testing.T) {
_, settingsManager := fixtures(map[string]string{
"application.instanceLabelKey": "testLabel",
})
label, err := settingsManager.GetAppInstanceLabelKey()
require.NoError(t, err)
assert.Equal(t, "testLabel", label)
})
t.Run("should get default instanceLabelKey if custom not defined", func(t *testing.T) {
_, settingsManager := fixtures(map[string]string{})
label, err := settingsManager.GetAppInstanceLabelKey()
require.NoError(t, err)
assert.Equal(t, common.LabelKeyAppInstance, label)
})
}
func TestGetTrackingMethod(t *testing.T) {
t.Run("should get custom trackingMethod", func(t *testing.T) {
_, settingsManager := fixtures(map[string]string{
"application.resourceTrackingMethod": string(v1alpha1.TrackingMethodLabel),
})
label, err := settingsManager.GetTrackingMethod()
require.NoError(t, err)
assert.Equal(t, string(v1alpha1.TrackingMethodLabel), label)
})
t.Run("should get default trackingMethod if custom not defined", func(t *testing.T) {
_, settingsManager := fixtures(map[string]string{})
label, err := settingsManager.GetTrackingMethod()
require.NoError(t, err)
assert.Equal(t, string(v1alpha1.TrackingMethodAnnotation), label)
})
label, err := settingsManager.GetAppInstanceLabelKey()
require.NoError(t, err)
assert.Equal(t, "testLabel", label)
}
func TestApplicationFineGrainedRBACInheritanceDisabledDefault(t *testing.T) {
@@ -330,7 +357,7 @@ func TestGetResourceOverrides(t *testing.T) {
crdOverrides := overrides[crdGK]
assert.NotNil(t, crdOverrides)
assert.Equal(t, v1alpha1.ResourceOverride{IgnoreDifferences: v1alpha1.OverrideIgnoreDiff{
JSONPointers: []string{"/webhooks/0/clientConfig/caBundle", "/status", "/spec/preserveUnknownFields"},
JSONPointers: []string{"/webhooks/0/clientConfig/caBundle", "/status"},
JQPathExpressions: []string{".webhooks[0].clientConfig.caBundle"},
}}, crdOverrides)