Skip to content

Commit 2bf840e

Browse files
authored
Merge pull request #264 from devtron-labs/fix-argocd-update-event
fix: skipped ArgoCD application update events for some valid cases
2 parents 1e3ca32 + b0c25c2 commit 2bf840e

2 files changed

Lines changed: 98 additions & 29 deletions

File tree

kubewatch/pkg/resource/application/handler.go

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,52 +53,36 @@ func (impl *InformerImpl) GetSharedInformer(clusterLabels *informerBean.ClusterL
5353

5454
_, err := acdInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
5555
AddFunc: func(obj interface{}) {
56-
impl.logger.Debug("app added")
57-
58-
if app, ok := obj.(*applicationBean.Application); ok {
59-
impl.logger.Debugf("new app detected: %s, status: %s", app.Name, app.Status.Health.Status)
60-
}
56+
impl.logger.Debugw("ARGO_CD_APPLICATION: new application object found")
6157
},
6258
UpdateFunc: func(old interface{}, new interface{}) {
63-
impl.logger.Debug("app update detected")
59+
impl.logger.Debugw("ARGO_CD_APPLICATION: application object update detected")
6460
statusTime := time.Now()
6561
if oldApp, ok := old.(*applicationBean.Application); ok {
6662
if newApp, ok := new.(*applicationBean.Application); ok {
67-
if newApp.Status.History != nil && len(newApp.Status.History) > 0 {
68-
if oldApp.Status.History == nil || len(oldApp.Status.History) == 0 {
69-
impl.logger.Debug("new deployment detected")
63+
// Check if the application has a new deployment history
64+
if isNewDeploymentHistoryFound(oldApp, newApp) {
65+
impl.logger.Debugw("ARGO_CD_APPLICATION: new deployment detected", "appName", newApp.Name, "status", newApp.Status.Health.Status)
66+
impl.sendAppUpdate(clusterLabels.ClusterId, newApp, statusTime)
67+
} else {
68+
if IsApplicationObjectUpdated(impl.logger, oldApp, newApp) {
7069
impl.sendAppUpdate(clusterLabels.ClusterId, newApp, statusTime)
70+
impl.logger.Debugw("ARGO_CD_APPLICATION: send update event for application object", "appName", oldApp.Name)
7171
} else {
72-
impl.logger.Debugf("old deployment detected for update: %s, status:%s", oldApp.Name, oldApp.Status.Health.Status)
73-
oldRevision := oldApp.Status.Sync.Revision
74-
newRevision := newApp.Status.Sync.Revision
75-
oldStatus := string(oldApp.Status.Health.Status)
76-
newStatus := string(newApp.Status.Health.Status)
77-
newSyncStatus := string(newApp.Status.Sync.Status)
78-
oldSyncStatus := string(oldApp.Status.Sync.Status)
79-
if (oldRevision != newRevision) || (oldStatus != newStatus) || (newSyncStatus != oldSyncStatus) {
80-
impl.sendAppUpdate(clusterLabels.ClusterId, newApp, statusTime)
81-
impl.logger.Debug("send update app:" + oldApp.Name + ", oldRevision: " + oldRevision + ", newRevision:" +
82-
newRevision + ", oldStatus: " + oldStatus + ", newStatus: " + newStatus +
83-
", newSyncStatus: " + newSyncStatus + ", oldSyncStatus: " + oldSyncStatus)
84-
} else {
85-
impl.logger.Debug("skip updating app:" + oldApp.Name + ", oldRevision: " + oldRevision + ", newRevision:" +
86-
newRevision + ", oldStatus: " + oldStatus + ", newStatus: " + newStatus +
87-
", newSyncStatus: " + newSyncStatus + ", oldSyncStatus: " + oldSyncStatus)
88-
}
72+
impl.logger.Debugw("ARGO_CD_APPLICATION: skip updating event for application object", "appName", oldApp.Name)
8973
}
9074
}
9175
} else {
92-
log.Println("app update detected, but skip updating, there is no new app")
76+
impl.logger.Errorw("ARGO_CD_APPLICATION: application object update detected, but could not cast to application object", "oldObj", old, "newObj", new)
9377
}
9478
} else {
95-
log.Println("app update detected, but skip updating, there is no old app")
79+
impl.logger.Errorw("ARGO_CD_APPLICATION: application object update detected, but could not cast to application object", "oldObj", old)
9680
}
9781
},
9882
DeleteFunc: func(obj interface{}) {
9983
if app, ok := obj.(*applicationBean.Application); ok {
10084
statusTime := time.Now()
101-
impl.logger.Debugf("app delete detected: %s, status:%s", app.Name, app.Status.Health.Status)
85+
impl.logger.Debugw("ARGO_CD_APPLICATION: application object delete detected", "appName", app.Name, "status", app.Status.Health.Status)
10286
impl.sendAppDelete(clusterLabels.ClusterId, app, statusTime)
10387
}
10488
},
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) 2024. Devtron Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package application
18+
19+
import (
20+
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
21+
synccommon "github.com/argoproj/gitops-engine/pkg/sync/common"
22+
"go.uber.org/zap"
23+
)
24+
25+
// isNewDeploymentHistoryFound checks
26+
// if a new deployment is found by
27+
// comparing the history of old and new application objects.
28+
func isNewDeploymentHistoryFound(oldAppObj, newAppObj *v1alpha1.Application) bool {
29+
if len(oldAppObj.Status.History) < len(newAppObj.Status.History) {
30+
return true
31+
} else if len(oldAppObj.Status.History) != 0 && len(oldAppObj.Status.History) == len(newAppObj.Status.History) {
32+
return oldAppObj.Status.History.LastRevisionHistory().ID < newAppObj.Status.History.LastRevisionHistory().ID
33+
}
34+
return false
35+
}
36+
37+
// getApplicationLastSyncedResourcesCount returns the count of resources that were last synced in the application.
38+
func getApplicationLastSyncedResourcesCount(appObj *v1alpha1.Application) int {
39+
if appObj.Status.OperationState == nil || appObj.Status.OperationState.SyncResult == nil {
40+
return 0
41+
}
42+
return len(appObj.Status.OperationState.SyncResult.Resources)
43+
}
44+
45+
func getApplicationOperationRevision(appObj *v1alpha1.Application) string {
46+
if appObj.Status.OperationState == nil || appObj.Status.OperationState.Operation.Sync == nil {
47+
return ""
48+
}
49+
return appObj.Status.OperationState.Operation.Sync.Revision
50+
}
51+
52+
func getApplicationOperationPhase(appObj *v1alpha1.Application) synccommon.OperationPhase {
53+
if appObj.Status.OperationState == nil {
54+
return ""
55+
}
56+
return appObj.Status.OperationState.Phase
57+
}
58+
59+
func IsApplicationObjectUpdated(logger *zap.SugaredLogger, oldAppObj, newAppObj *v1alpha1.Application) bool {
60+
// Check if the application sync revision has changed
61+
oldRevision := oldAppObj.Status.Sync.Revision
62+
newRevision := newAppObj.Status.Sync.Revision
63+
// Check if the operation revision has changed
64+
oldOperationRevision := getApplicationOperationRevision(oldAppObj)
65+
newOperationRevision := getApplicationOperationRevision(newAppObj)
66+
// Check if the health status has changed
67+
oldStatus := string(oldAppObj.Status.Health.Status)
68+
newStatus := string(newAppObj.Status.Health.Status)
69+
// Check if the operation phase has changed
70+
oldOperationPhase := getApplicationOperationPhase(oldAppObj)
71+
newOperationPhase := getApplicationOperationPhase(newAppObj)
72+
// Check if the last synced resources count has changed
73+
oldAppLastSyncedResourcesCount := getApplicationLastSyncedResourcesCount(oldAppObj)
74+
newAppLastSyncedResourcesCount := getApplicationLastSyncedResourcesCount(newAppObj)
75+
76+
logger.Debugw("ARGO_CD_APPLICATION: update event captured with", "oldRevision", oldRevision, "newRevision", newRevision,
77+
"oldOperationRevision", oldOperationRevision, "newOperationRevision", newOperationRevision,
78+
"oldStatus", oldStatus, "newStatus", newStatus,
79+
"oldOperationPhase", oldOperationPhase, "newOperationPhase", newOperationPhase,
80+
"oldAppLastSyncedResourcesCount", oldAppLastSyncedResourcesCount, "newAppLastSyncedResourcesCount", newAppLastSyncedResourcesCount)
81+
82+
return (oldRevision != newRevision) || (newOperationRevision != oldOperationRevision) ||
83+
(oldStatus != newStatus) || (oldOperationPhase != newOperationPhase) ||
84+
(oldAppLastSyncedResourcesCount != newAppLastSyncedResourcesCount)
85+
}

0 commit comments

Comments
 (0)