Skip to content

Commit 93f8f94

Browse files
author
Casey Morton
committed
Initial development to be compatible with multiple application sources
Signed-off-by: Casey Morton <[email protected]>
1 parent 650e04a commit 93f8f94

File tree

7 files changed

+282
-254
lines changed

7 files changed

+282
-254
lines changed

pkg/argocd/argocd.go

+76-43
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,6 @@ func FilterApplicationsForUpdate(apps []v1alpha1.Application, patterns []string,
184184
continue
185185
}
186186

187-
// Check for valid application type
188-
if !IsValidApplicationType(&app) {
189-
logCtx.Warnf("skipping app '%s' of type '%s' because it's not of supported source type", app.GetName(), app.Status.SourceType)
190-
continue
191-
}
192-
193187
// Check if application name matches requested patterns
194188
if !nameMatchesPattern(app.GetName(), patterns) {
195189
logCtx.Debugf("Skipping app '%s' because it does not match requested patterns", app.GetName())
@@ -201,13 +195,20 @@ func FilterApplicationsForUpdate(apps []v1alpha1.Application, patterns []string,
201195
logCtx.Debugf("Skipping app '%s' because it does not carry requested label", app.GetName())
202196
continue
203197
}
198+
for sourceIndex, _ := range getApplicationTypes(&app) {
199+
// Check for valid application type
200+
if !IsValidApplicationTypeForSource(&app, sourceIndex) {
201+
logCtx.Infof("skipping app '%s' of type '%s' because it's not of supported source type", app.GetName(), GetSourceTypes(app.Status)[sourceIndex])
202+
continue
203+
}
204204

205-
logCtx.Tracef("processing app '%s' of type '%v'", app.GetName(), app.Status.SourceType)
206-
imageList := parseImageList(annotations)
207-
appImages := ApplicationImages{}
208-
appImages.Application = app
209-
appImages.Images = *imageList
210-
appsForUpdate[app.GetName()] = appImages
205+
logCtx.Tracef("processing app '%s' of type '%v'", app.GetName(), app.Status.SourceType)
206+
imageList := parseImageList(annotations)
207+
appImages := ApplicationImages{}
208+
appImages.Application = app
209+
appImages.Images = *imageList
210+
appsForUpdate[app.GetName()] = appImages
211+
}
211212
}
212213

213214
return appsForUpdate, nil
@@ -378,10 +379,10 @@ func mergeHelmParams(src []v1alpha1.HelmParameter, merge []v1alpha1.HelmParamete
378379
return retParams
379380
}
380381

381-
// SetHelmImage sets image parameters for a Helm application
382-
func SetHelmImage(app *v1alpha1.Application, newImage *image.ContainerImage) error {
383-
if appType := getApplicationType(app); appType != ApplicationTypeHelm {
384-
return fmt.Errorf("cannot set Helm params on non-Helm application")
382+
// SetHelmImageWithIndex sets image parameters for a Helm application and a specific sourceIndex
383+
func SetHelmImageWithIndex(app *v1alpha1.Application, sourceIndex int, newImage *image.ContainerImage) bool {
384+
if appType := getApplicationTypes(app)[sourceIndex]; appType != ApplicationTypeHelm {
385+
return false
385386
}
386387

387388
appName := app.GetName()
@@ -425,23 +426,24 @@ func SetHelmImage(app *v1alpha1.Application, newImage *image.ContainerImage) err
425426
}
426427
}
427428

428-
if app.Spec.GetSources()[0].Helm == nil {
429-
app.Spec.GetSources()[0].Helm = &v1alpha1.ApplicationSourceHelm{}
429+
if app.Spec.GetSources()[sourceIndex].Helm == nil {
430+
app.Spec.GetSources()[sourceIndex].Helm = &v1alpha1.ApplicationSourceHelm{}
430431
}
431432

432-
if app.Spec.GetSources()[0].Helm.Parameters == nil {
433-
app.Spec.GetSources()[0].Helm.Parameters = make([]v1alpha1.HelmParameter, 0)
433+
if app.Spec.GetSources()[sourceIndex].Helm.Parameters == nil {
434+
app.Spec.GetSources()[sourceIndex].Helm.Parameters = make([]v1alpha1.HelmParameter, 0)
434435
}
435436

436-
app.Spec.GetSources()[0].Helm.Parameters = mergeHelmParams(app.Spec.GetSources()[0].Helm.Parameters, mergeParams)
437+
app.Spec.GetSources()[sourceIndex].Helm.Parameters = mergeHelmParams(app.Spec.GetSources()[sourceIndex].Helm.Parameters, mergeParams)
437438

438-
return nil
439+
return true
439440
}
440441

441-
// SetKustomizeImage sets a Kustomize image for given application
442-
func SetKustomizeImage(app *v1alpha1.Application, newImage *image.ContainerImage) error {
443-
if appType := getApplicationType(app); appType != ApplicationTypeKustomize {
444-
return fmt.Errorf("cannot set Kustomize image on non-Kustomize application")
442+
// SetKustomizeImageWithIndex sets a Kustomize image for given application
443+
// returns whether that specific source was updated
444+
func SetKustomizeImageWithIndex(app *v1alpha1.Application, sourceIndex int, newImage *image.ContainerImage) bool {
445+
if appType := getApplicationTypes(app)[sourceIndex]; appType != ApplicationTypeKustomize {
446+
return false
445447
}
446448

447449
var ksImageParam string
@@ -454,7 +456,7 @@ func SetKustomizeImage(app *v1alpha1.Application, newImage *image.ContainerImage
454456

455457
log.WithContext().AddField("application", app.GetName()).Tracef("Setting Kustomize parameter %s", ksImageParam)
456458

457-
var source = app.Spec.GetSources()[0]
459+
var source = app.Spec.GetSources()[sourceIndex]
458460
if source.Kustomize == nil {
459461
source.Kustomize = &v1alpha1.ApplicationSourceKustomize{}
460462
}
@@ -473,12 +475,12 @@ func SetKustomizeImage(app *v1alpha1.Application, newImage *image.ContainerImage
473475
source.Kustomize.MergeImage(v1alpha1.KustomizeImage(ksImageParam))
474476

475477
if app.Spec.HasMultipleSources() {
476-
app.Spec.Sources[0] = source
478+
app.Spec.Sources[sourceIndex] = source
477479
} else {
478480
app.Spec.Source = &source
479481
}
480482

481-
return nil
483+
return true
482484
}
483485

484486
// GetImagesFromApplication returns the list of known images for the given application
@@ -503,33 +505,50 @@ func GetImagesFromApplication(app *v1alpha1.Application) image.ContainerImageLis
503505
return images
504506
}
505507

506-
// GetApplicationTypeByName first retrieves application with given appName and
507-
// returns its application type
508-
func GetApplicationTypeByName(client ArgoCD, appName string) (ApplicationType, error) {
508+
// GetApplicationTypesByName first retrieves application with given appName and
509+
// returns its application types
510+
func GetApplicationTypesByName(client ArgoCD, appName string) ([]ApplicationType, error) {
509511
app, err := client.GetApplication(context.TODO(), appName)
510512
if err != nil {
511-
return ApplicationTypeUnsupported, err
513+
retval := []ApplicationType{ApplicationTypeUnsupported}
514+
return retval, err
512515
}
513-
return getApplicationType(app), nil
516+
return getApplicationTypes(app), nil
514517
}
515518

516-
// GetApplicationType returns the type of the ArgoCD application
517-
func GetApplicationType(app *v1alpha1.Application) ApplicationType {
518-
return getApplicationType(app)
519+
// GetApplicationTypeForSource returns the type of the ArgoCD application source
520+
func GetApplicationTypeForSource(app *v1alpha1.Application, sourceIndex int) ApplicationType {
521+
return getApplicationTypes(app)[sourceIndex]
519522
}
520523

521-
// IsValidApplicationType returns true if we can update the application
522-
func IsValidApplicationType(app *v1alpha1.Application) bool {
523-
return getApplicationType(app) != ApplicationTypeUnsupported
524+
// IsValidApplicationTypeForSource returns true if we can update the application source
525+
func IsValidApplicationTypeForSource(app *v1alpha1.Application, sourceIndex int) bool {
526+
return getApplicationTypes(app)[sourceIndex] != ApplicationTypeUnsupported
524527
}
525528

526529
// getApplicationType returns the type of the application
527-
func getApplicationType(app *v1alpha1.Application) ApplicationType {
528-
sourceType := app.Status.SourceType
530+
// writebacktargetannotation with the kustomization prefix forces all sources to be handled as kustomization
531+
func getApplicationTypes(app *v1alpha1.Application) []ApplicationType {
532+
kustomizationWriteBack := false
533+
retval := make([]ApplicationType, 0)
534+
529535
if st, set := app.Annotations[common.WriteBackTargetAnnotation]; set &&
530536
strings.HasPrefix(st, common.KustomizationPrefix) {
531-
sourceType = v1alpha1.ApplicationSourceTypeKustomize
537+
kustomizationWriteBack = true
532538
}
539+
540+
for _, sourceType := range GetSourceTypes(app.Status) {
541+
if kustomizationWriteBack {
542+
retval = append(retval, ApplicationTypeKustomize)
543+
} else {
544+
retval = append(retval, getApplicationTypeForSourceType(sourceType))
545+
}
546+
}
547+
548+
return retval
549+
}
550+
551+
func getApplicationTypeForSourceType(sourceType v1alpha1.ApplicationSourceType) ApplicationType {
533552
if sourceType == v1alpha1.ApplicationSourceTypeKustomize {
534553
return ApplicationTypeKustomize
535554
} else if sourceType == v1alpha1.ApplicationSourceTypeHelm {
@@ -552,3 +571,17 @@ func (a ApplicationType) String() string {
552571
return "Unknown"
553572
}
554573
}
574+
575+
func HasMultipleSourceTypes(status v1alpha1.ApplicationStatus) bool {
576+
return status.SourceTypes != nil && len(status.SourceTypes) > 0
577+
}
578+
579+
func GetSourceTypes(status v1alpha1.ApplicationStatus) []v1alpha1.ApplicationSourceType {
580+
if HasMultipleSourceTypes(status) {
581+
return status.SourceTypes
582+
}
583+
if &status.SourceType != nil {
584+
return []v1alpha1.ApplicationSourceType{status.SourceType}
585+
}
586+
return []v1alpha1.ApplicationSourceType{}
587+
}

pkg/argocd/argocd_test.go

+21-76
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func Test_GetImagesFromApplication(t *testing.T) {
7979
})
8080
}
8181

82-
func Test_GetApplicationType(t *testing.T) {
82+
func Test_GetApplicationTypeForSource(t *testing.T) {
8383
t.Run("Get application of type Helm", func(t *testing.T) {
8484
application := &v1alpha1.Application{
8585
ObjectMeta: v1.ObjectMeta{
@@ -94,7 +94,7 @@ func Test_GetApplicationType(t *testing.T) {
9494
},
9595
},
9696
}
97-
appType := GetApplicationType(application)
97+
appType := GetApplicationTypeForSource(application, 0)
9898
assert.Equal(t, ApplicationTypeHelm, appType)
9999
assert.Equal(t, "Helm", appType.String())
100100
})
@@ -113,7 +113,7 @@ func Test_GetApplicationType(t *testing.T) {
113113
},
114114
},
115115
}
116-
appType := GetApplicationType(application)
116+
appType := GetApplicationTypeForSource(application, 0)
117117
assert.Equal(t, ApplicationTypeKustomize, appType)
118118
assert.Equal(t, "Kustomize", appType.String())
119119
})
@@ -132,7 +132,7 @@ func Test_GetApplicationType(t *testing.T) {
132132
},
133133
},
134134
}
135-
appType := GetApplicationType(application)
135+
appType := GetApplicationTypeForSource(application, 0)
136136
assert.Equal(t, ApplicationTypeUnsupported, appType)
137137
assert.Equal(t, "Unsupported", appType.String())
138138
})
@@ -154,7 +154,7 @@ func Test_GetApplicationType(t *testing.T) {
154154
},
155155
},
156156
}
157-
appType := GetApplicationType(application)
157+
appType := GetApplicationTypeForSource(application, 0)
158158
assert.Equal(t, ApplicationTypeKustomize, appType)
159159
})
160160

@@ -466,8 +466,8 @@ func Test_SetKustomizeImage(t *testing.T) {
466466
},
467467
}
468468
img := image.NewFromIdentifier("jannfis/foobar:1.0.1")
469-
err := SetKustomizeImage(app, img)
470-
require.NoError(t, err)
469+
updated := SetKustomizeImageWithIndex(app, 0, img)
470+
assert.True(t, updated)
471471
require.NotNil(t, app.Spec.GetSources()[0].Kustomize)
472472
assert.Len(t, app.Spec.GetSources()[0].Kustomize.Images, 1)
473473
assert.Equal(t, v1alpha1.KustomizeImage("jannfis/foobar:1.0.1"), app.Spec.GetSources()[0].Kustomize.Images[0])
@@ -492,8 +492,8 @@ func Test_SetKustomizeImage(t *testing.T) {
492492
},
493493
}
494494
img := image.NewFromIdentifier("jannfis/foobar:1.0.1")
495-
err := SetKustomizeImage(app, img)
496-
require.NoError(t, err)
495+
updated := SetKustomizeImageWithIndex(app, 0, img)
496+
assert.True(t, updated)
497497
require.NotNil(t, app.Spec.GetSources()[0].Kustomize)
498498
assert.Len(t, app.Spec.GetSources()[0].Kustomize.Images, 1)
499499
assert.Equal(t, v1alpha1.KustomizeImage("jannfis/foobar:1.0.1"), app.Spec.GetSources()[0].Kustomize.Images[0])
@@ -524,8 +524,8 @@ func Test_SetKustomizeImage(t *testing.T) {
524524
},
525525
}
526526
img := image.NewFromIdentifier("jannfis/foobar:1.0.1")
527-
err := SetKustomizeImage(app, img)
528-
require.Error(t, err)
527+
updated := SetKustomizeImageWithIndex(app, 0, img)
528+
assert.False(t, updated)
529529
})
530530

531531
t.Run("Test set Kustomize image parameters with alias name on Kustomize app with param already set", func(t *testing.T) {
@@ -556,8 +556,8 @@ func Test_SetKustomizeImage(t *testing.T) {
556556
},
557557
}
558558
img := image.NewFromIdentifier("foobar=jannfis/foobar:1.0.1")
559-
err := SetKustomizeImage(app, img)
560-
require.NoError(t, err)
559+
updated := SetKustomizeImageWithIndex(app, 0, img)
560+
assert.True(t, updated)
561561
require.NotNil(t, app.Spec.GetSources()[0].Kustomize)
562562
assert.Len(t, app.Spec.GetSources()[0].Kustomize.Images, 1)
563563
assert.Equal(t, v1alpha1.KustomizeImage("foobar=jannfis/foobar:1.0.1"), app.Spec.GetSources()[0].Kustomize.Images[0])
@@ -604,8 +604,8 @@ func Test_SetHelmImage(t *testing.T) {
604604

605605
img := image.NewFromIdentifier("foobar=jannfis/foobar:1.0.1")
606606

607-
err := SetHelmImage(app, img)
608-
require.NoError(t, err)
607+
updated := SetHelmImageWithIndex(app, 0, img)
608+
assert.True(t, updated)
609609
require.NotNil(t, app.Spec.GetSources()[0].Helm)
610610
assert.Len(t, app.Spec.GetSources()[0].Helm.Parameters, 2)
611611

@@ -647,63 +647,8 @@ func Test_SetHelmImage(t *testing.T) {
647647

648648
img := image.NewFromIdentifier("foobar=jannfis/foobar:1.0.1")
649649

650-
err := SetHelmImage(app, img)
651-
require.NoError(t, err)
652-
require.NotNil(t, app.Spec.GetSources()[0].Helm)
653-
assert.Len(t, app.Spec.GetSources()[0].Helm.Parameters, 2)
654-
655-
// Find correct parameter
656-
var tagParam v1alpha1.HelmParameter
657-
for _, p := range app.Spec.GetSources()[0].Helm.Parameters {
658-
if p.Name == "image.tag" {
659-
tagParam = p
660-
break
661-
}
662-
}
663-
assert.Equal(t, "1.0.1", tagParam.Value)
664-
})
665-
666-
t.Run("Test set Helm image parameters on Helm app with multiple sources but existing parameters", func(t *testing.T) {
667-
app := &v1alpha1.Application{
668-
ObjectMeta: v1.ObjectMeta{
669-
Name: "test-app",
670-
Namespace: "testns",
671-
Annotations: map[string]string{
672-
fmt.Sprintf(common.HelmParamImageNameAnnotation, "foobar"): "image.name",
673-
fmt.Sprintf(common.HelmParamImageTagAnnotation, "foobar"): "image.tag",
674-
fmt.Sprintf(common.HelmParamImageNameAnnotation, "baz"): "image.name",
675-
fmt.Sprintf(common.HelmParamImageTagAnnotation, "baz"): "image.tag",
676-
},
677-
},
678-
Spec: v1alpha1.ApplicationSpec{
679-
Sources: v1alpha1.ApplicationSources{
680-
v1alpha1.ApplicationSource{
681-
Helm: &v1alpha1.ApplicationSourceHelm{},
682-
},
683-
v1alpha1.ApplicationSource{
684-
Helm: &v1alpha1.ApplicationSourceHelm{},
685-
},
686-
},
687-
},
688-
Status: v1alpha1.ApplicationStatus{
689-
SourceTypes: []v1alpha1.ApplicationSourceType{
690-
v1alpha1.ApplicationSourceTypeHelm,
691-
v1alpha1.ApplicationSourceTypeHelm,
692-
},
693-
SourceType: v1alpha1.ApplicationSourceTypeHelm,
694-
Summary: v1alpha1.ApplicationSummary{
695-
Images: []string{
696-
"jannfis/foobar:1.0.0",
697-
"cjm/baz:2.0.0",
698-
},
699-
},
700-
},
701-
}
702-
703-
img := image.NewFromIdentifier("foobar=jannfis/foobar:1.0.1")
704-
705-
err := SetHelmImage(app, img)
706-
require.NoError(t, err)
650+
updated := SetHelmImageWithIndex(app, 0, img)
651+
assert.True(t, updated)
707652
require.NotNil(t, app.Spec.GetSources()[0].Helm)
708653
assert.Len(t, app.Spec.GetSources()[0].Helm.Parameters, 2)
709654

@@ -756,8 +701,8 @@ func Test_SetHelmImage(t *testing.T) {
756701

757702
img := image.NewFromIdentifier("foobar=jannfis/foobar:1.0.1")
758703

759-
err := SetHelmImage(app, img)
760-
require.NoError(t, err)
704+
updated := SetHelmImageWithIndex(app, 0, img)
705+
assert.True(t, updated)
761706
require.NotNil(t, app.Spec.GetSources()[0].Helm)
762707
assert.Len(t, app.Spec.GetSources()[0].Helm.Parameters, 4)
763708

@@ -797,8 +742,8 @@ func Test_SetHelmImage(t *testing.T) {
797742

798743
img := image.NewFromIdentifier("foobar=jannfis/foobar:1.0.1")
799744

800-
err := SetHelmImage(app, img)
801-
require.Error(t, err)
745+
updated := SetHelmImageWithIndex(app, 0, img)
746+
assert.False(t, updated)
802747
})
803748

804749
}

0 commit comments

Comments
 (0)