Skip to content

Commit c7128eb

Browse files
NigelByrne1dirgim
authored andcommitted
bug(STONEINTG-1372): skip owner refs if component ArgoCD managed
Signed-off-by: nbyrne <[email protected]>
1 parent f50e3ee commit c7128eb

File tree

2 files changed

+201
-0
lines changed

2 files changed

+201
-0
lines changed

webhooks/component_webhook.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,14 @@ func (r *ComponentWebhook) Default(ctx context.Context, obj runtime.Object) erro
9090
Name: hasApplication.Name,
9191
UID: hasApplication.UID,
9292
}
93+
94+
if isArgoCDManaged(&curComp, &hasApplication) {
95+
componentlog.Info("component is managed by ArgoCD, skipping owner reference setting")
96+
return nil
97+
}
98+
9399
curComp.SetOwnerReferences(append(curComp.GetOwnerReferences(), ownerReference))
100+
94101
err = r.client.Update(ctx, &curComp)
95102
return err
96103
})
@@ -300,3 +307,43 @@ func (r *ComponentWebhook) validateBuildNudgesRefGraph(ctx context.Context, nudg
300307

301308
return nil
302309
}
310+
311+
// isArgoCDManaged checks if a component or its Application is managed by ArgoCD
312+
// by looking for ArgoCD tracking annotations or labels
313+
func isArgoCDManaged(component *appstudiov1alpha1.Component, application *appstudiov1alpha1.Application) bool {
314+
315+
// use a constant for the ArgoCD tracking ID key
316+
const argocdtrackingId = "argocd.argoproj.io/tracking-id"
317+
318+
// Check component annotations
319+
if component.Annotations != nil {
320+
if _, exists := component.Annotations[argocdtrackingId]; exists {
321+
return true
322+
}
323+
}
324+
325+
// Check component labels
326+
if component.Labels != nil {
327+
if _, exists := component.Labels[argocdtrackingId]; exists {
328+
return true
329+
}
330+
}
331+
332+
// Check Application annotations (to avoid race conditions)
333+
if application != nil {
334+
if application.Annotations != nil {
335+
if _, exists := application.Annotations[argocdtrackingId]; exists {
336+
return true
337+
}
338+
}
339+
340+
// Check Application labels
341+
if application.Labels != nil {
342+
if _, exists := application.Labels[argocdtrackingId]; exists {
343+
return true
344+
}
345+
}
346+
}
347+
348+
return false
349+
}

webhooks/component_webhook_unit_test.go

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,160 @@ func TestUpdateNudgedComponentStatus(t *testing.T) {
734734
}
735735
}
736736

737+
func TestIsArgoCDManaged(t *testing.T) {
738+
// reusable application for tests with no ArgoCD tracking
739+
normalApplication := &appstudiov1alpha1.Application{
740+
ObjectMeta: v1.ObjectMeta{
741+
Name: "application1",
742+
Namespace: "default",
743+
},
744+
}
745+
746+
t.Run("should return true when component has ArgoCD annotation", func(t *testing.T) {
747+
component := &appstudiov1alpha1.Component{
748+
ObjectMeta: v1.ObjectMeta{
749+
Name: "component1",
750+
Namespace: "default",
751+
Annotations: map[string]string{
752+
"argocd.argoproj.io/tracking-id": "123",
753+
},
754+
},
755+
}
756+
result := isArgoCDManaged(component, normalApplication)
757+
758+
if !result {
759+
t.Errorf("TestIsArgoCDManaged(): should return true when component has ArgoCD annotation, got false")
760+
}
761+
})
762+
763+
t.Run("should return true when component has ArgoCD label", func(t *testing.T) {
764+
component := &appstudiov1alpha1.Component{
765+
ObjectMeta: v1.ObjectMeta{
766+
Name: "component1",
767+
Namespace: "default",
768+
Labels: map[string]string{
769+
"argocd.argoproj.io/tracking-id": "123",
770+
},
771+
},
772+
}
773+
774+
result := isArgoCDManaged(component, normalApplication)
775+
776+
if !result {
777+
t.Errorf("TestIsArgoCDManaged(): should return true when component has ArgoCD label, got false")
778+
}
779+
})
780+
781+
t.Run("should return true when application has ArgoCD annotation", func(t *testing.T) {
782+
// Component without ArgoCD tracking
783+
component := &appstudiov1alpha1.Component{
784+
ObjectMeta: v1.ObjectMeta{
785+
Name: "component1",
786+
Namespace: "default",
787+
// Component has no ArgoCD tracking - looks normal
788+
},
789+
}
790+
791+
// Application HAS ArgoCD annotation
792+
application := &appstudiov1alpha1.Application{
793+
ObjectMeta: v1.ObjectMeta{
794+
Name: "application1",
795+
Namespace: "default",
796+
Annotations: map[string]string{
797+
"argocd.argoproj.io/tracking-id": "123",
798+
},
799+
},
800+
}
801+
802+
result := isArgoCDManaged(component, application)
803+
804+
if !result {
805+
t.Errorf("TestIsArgoCDManaged(): should return true when application has ArgoCD annotation, got false")
806+
}
807+
})
808+
809+
t.Run("should return true when application has ArgoCD label", func(t *testing.T) {
810+
component := &appstudiov1alpha1.Component{
811+
ObjectMeta: v1.ObjectMeta{
812+
Name: "component1",
813+
Namespace: "default",
814+
// Component has no ArgoCD tracking
815+
},
816+
}
817+
818+
// Application HAS ArgoCD label (not annotation)
819+
application := &appstudiov1alpha1.Application{
820+
ObjectMeta: v1.ObjectMeta{
821+
Name: "application1",
822+
Namespace: "default",
823+
Labels: map[string]string{
824+
"argocd.argoproj.io/tracking-id": "123",
825+
},
826+
},
827+
}
828+
829+
result := isArgoCDManaged(component, application)
830+
831+
if !result {
832+
t.Errorf("TestIsArgoCDManaged(): should return true when application has ArgoCD label, got false")
833+
}
834+
})
835+
836+
t.Run("should return false when component and application both have no ArgoCD tracking", func(t *testing.T) {
837+
component := &appstudiov1alpha1.Component{
838+
ObjectMeta: v1.ObjectMeta{
839+
Name: "component1",
840+
Namespace: "default",
841+
// No annotations, no labels - completely normal component
842+
},
843+
}
844+
845+
result := isArgoCDManaged(component, normalApplication)
846+
847+
if result {
848+
t.Errorf("TestIsArgoCDManaged(): should return false when neither has ArgoCD tracking, got true")
849+
}
850+
})
851+
852+
t.Run("should return false when component has no ArgoCD and application is nil", func(t *testing.T) {
853+
component := &appstudiov1alpha1.Component{
854+
ObjectMeta: v1.ObjectMeta{
855+
Name: "component1",
856+
Namespace: "default",
857+
// Component has no ArgoCD tracking
858+
},
859+
}
860+
861+
// Call with nil application - should not panic and should return false
862+
result := isArgoCDManaged(component, nil)
863+
864+
if result {
865+
t.Errorf("TestIsArgoCDManaged(): should return false when component has no ArgoCD and application is nil, got true")
866+
}
867+
})
868+
869+
t.Run("should return true when component has ArgoCD annotation even with nil application", func(t *testing.T) {
870+
component := &appstudiov1alpha1.Component{
871+
ObjectMeta: v1.ObjectMeta{
872+
Name: "component1",
873+
Namespace: "default",
874+
// Component HAS ArgoCD annotation
875+
Annotations: map[string]string{
876+
"argocd.argoproj.io/tracking-id": "123",
877+
},
878+
},
879+
}
880+
881+
// Even with nil application, should return true because component has annotation
882+
result := isArgoCDManaged(component, nil)
883+
884+
if !result {
885+
t.Errorf("TestIsArgoCDManaged(): should return true when component has ArgoCD annotation even with nil application, got false")
886+
}
887+
})
888+
889+
}
890+
737891
// setUpComponentsForFakeErrorClient creates a fake controller-runtime Kube client with components to test error scenarios
738892
func setUpComponentsForFakeErrorClient(t *testing.T) *FakeClient {
739893
fakeErrorClient := NewFakeErrorClient(t)

0 commit comments

Comments
 (0)