Skip to content

Commit 80d2731

Browse files
sribiere-jellysmackchengfangMangaaljannfis
authored
feat: Support other namespaces than argocd in AIU (argoproj-labs#763)
Signed-off-by: Sebastien RIBIERE <[email protected]> Signed-off-by: Cheng Fang <[email protected]> Signed-off-by: Mangaal <[email protected]> Signed-off-by: jannfis <[email protected]> Co-authored-by: Cheng Fang <[email protected]> Co-authored-by: Mangaal <[email protected]> Co-authored-by: Jann Fischer <[email protected]>
1 parent 5edb9d0 commit 80d2731

File tree

5 files changed

+132
-21
lines changed

5 files changed

+132
-21
lines changed

pkg/argocd/argocd.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,41 +176,41 @@ func FilterApplicationsForUpdate(apps []v1alpha1.Application, patterns []string,
176176
var appsForUpdate = make(map[string]ApplicationImages)
177177

178178
for _, app := range apps {
179-
logCtx := log.WithContext().AddField("application", app.GetName())
180-
179+
logCtx := log.WithContext().AddField("application", app.GetName()).AddField("namespace", app.GetNamespace())
180+
appNSName := fmt.Sprintf("%s/%s", app.GetNamespace(), app.GetName())
181181
sourceType := getApplicationSourceType(&app)
182182

183183
// Check whether application has our annotation set
184184
annotations := app.GetAnnotations()
185185
if _, ok := annotations[common.ImageUpdaterAnnotation]; !ok {
186-
logCtx.Tracef("skipping app '%s' of type '%s' because required annotation is missing", app.GetName(), sourceType)
186+
logCtx.Tracef("skipping app '%s' of type '%s' because required annotation is missing", appNSName, sourceType)
187187
continue
188188
}
189189

190190
// Check for valid application type
191191
if !IsValidApplicationType(&app) {
192-
logCtx.Warnf("skipping app '%s' of type '%s' because it's not of supported source type", app.GetName(), sourceType)
192+
logCtx.Warnf("skipping app '%s' of type '%s' because it's not of supported source type", appNSName, sourceType)
193193
continue
194194
}
195195

196196
// Check if application name matches requested patterns
197197
if !nameMatchesPattern(app.GetName(), patterns) {
198-
logCtx.Debugf("Skipping app '%s' because it does not match requested patterns", app.GetName())
198+
logCtx.Debugf("Skipping app '%s' because it does not match requested patterns", appNSName)
199199
continue
200200
}
201201

202202
// Check if application carries requested label
203203
if !matchAppLabels(app.GetName(), app.GetLabels(), appLabel) {
204-
logCtx.Debugf("Skipping app '%s' because it does not carry requested label", app.GetName())
204+
logCtx.Debugf("Skipping app '%s' because it does not carry requested label", appNSName)
205205
continue
206206
}
207207

208-
logCtx.Tracef("processing app '%s' of type '%v'", app.GetName(), sourceType)
208+
logCtx.Tracef("processing app '%s' of type '%v'", appNSName, sourceType)
209209
imageList := parseImageList(annotations)
210210
appImages := ApplicationImages{}
211211
appImages.Application = app
212212
appImages.Images = *imageList
213-
appsForUpdate[app.GetName()] = appImages
213+
appsForUpdate[appNSName] = appImages
214214
}
215215

216216
return appsForUpdate, nil
@@ -385,6 +385,7 @@ func SetHelmImage(app *v1alpha1.Application, newImage *image.ContainerImage) err
385385
}
386386

387387
appName := app.GetName()
388+
appNamespace := app.GetNamespace()
388389

389390
var hpImageName, hpImageTag, hpImageSpec string
390391

@@ -404,6 +405,7 @@ func SetHelmImage(app *v1alpha1.Application, newImage *image.ContainerImage) err
404405
log.WithContext().
405406
AddField("application", appName).
406407
AddField("image", newImage.GetFullNameWithoutTag()).
408+
AddField("namespace", appNamespace).
407409
Debugf("target parameters: image-spec=%s image-name=%s, image-tag=%s", hpImageSpec, hpImageName, hpImageTag)
408410

409411
mergeParams := make([]v1alpha1.HelmParameter, 0)

pkg/argocd/argocd_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,8 @@ func Test_FilterApplicationsForUpdate(t *testing.T) {
494494
filtered, err := FilterApplicationsForUpdate(applicationList, []string{}, "")
495495
require.NoError(t, err)
496496
require.Len(t, filtered, 1)
497-
require.Contains(t, filtered, "app1")
498-
assert.Len(t, filtered["app1"].Images, 2)
497+
require.Contains(t, filtered, "argocd/app1")
498+
assert.Len(t, filtered["argocd/app1"].Images, 2)
499499
})
500500

501501
t.Run("Filter for applications with patterns", func(t *testing.T) {
@@ -546,9 +546,9 @@ func Test_FilterApplicationsForUpdate(t *testing.T) {
546546
filtered, err := FilterApplicationsForUpdate(applicationList, []string{"app*"}, "")
547547
require.NoError(t, err)
548548
require.Len(t, filtered, 2)
549-
require.Contains(t, filtered, "app1")
550-
require.Contains(t, filtered, "app2")
551-
assert.Len(t, filtered["app1"].Images, 2)
549+
require.Contains(t, filtered, "argocd/app1")
550+
require.Contains(t, filtered, "argocd/app2")
551+
assert.Len(t, filtered["argocd/app1"].Images, 2)
552552
})
553553

554554
t.Run("Filter for applications with label", func(t *testing.T) {
@@ -588,8 +588,8 @@ func Test_FilterApplicationsForUpdate(t *testing.T) {
588588
filtered, err := FilterApplicationsForUpdate(applicationList, []string{}, "custom.label/name=xyz")
589589
require.NoError(t, err)
590590
require.Len(t, filtered, 1)
591-
require.Contains(t, filtered, "app1")
592-
assert.Len(t, filtered["app1"].Images, 2)
591+
require.Contains(t, filtered, "argocd/app1")
592+
assert.Len(t, filtered["argocd/app1"].Images, 2)
593593
})
594594

595595
}

pkg/argocd/update.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ func getWriteBackConfig(app *v1alpha1.Application, kubeClient *kube.KubernetesCl
584584
// Default write-back is to use Argo CD API
585585
wbc.Method = WriteBackApplication
586586
wbc.ArgoClient = argoClient
587-
wbc.Target = parseDefaultTarget(app.Name, getApplicationSource(app).Path)
587+
wbc.Target = parseDefaultTarget(app.GetNamespace(), app.Name, getApplicationSource(app).Path, kubeClient)
588588

589589
// If we have no update method, just return our default
590590
method, ok := app.Annotations[common.WriteBackMethodAnnotation]
@@ -621,10 +621,14 @@ func getWriteBackConfig(app *v1alpha1.Application, kubeClient *kube.KubernetesCl
621621
return wbc, nil
622622
}
623623

624-
func parseDefaultTarget(appName string, path string) string {
625-
defaultTargetFile := fmt.Sprintf(common.DefaultTargetFilePattern, appName)
626-
627-
return filepath.Join(path, defaultTargetFile)
624+
func parseDefaultTarget(appNamespace string, appName string, path string, kubeClient *kube.KubernetesClient) string {
625+
if (appNamespace == kubeClient.Namespace) || (appNamespace == "") {
626+
defaultTargetFile := fmt.Sprintf(common.DefaultTargetFilePatternWithoutNamespace, appName)
627+
return filepath.Join(path, defaultTargetFile)
628+
} else {
629+
defaultTargetFile := fmt.Sprintf(common.DefaultTargetFilePattern, appNamespace, appName)
630+
return filepath.Join(path, defaultTargetFile)
631+
}
628632
}
629633

630634
func parseKustomizeBase(target string, sourcePath string) (kustomizeBase string) {

pkg/argocd/update_test.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2724,6 +2724,110 @@ helm:
27242724
`, string(override))
27252725
})
27262726

2727+
t.Run("Good commit to helm override with argocd namespace", func(t *testing.T) {
2728+
kubeClient.Namespace = "argocd"
2729+
app := app.DeepCopy()
2730+
app.Status.SourceType = "Helm"
2731+
app.ObjectMeta.Namespace = "argocd"
2732+
app.Spec.Source.Helm = &v1alpha1.ApplicationSourceHelm{Parameters: []v1alpha1.HelmParameter{
2733+
{Name: "bar", Value: "bar", ForceString: true},
2734+
{Name: "baz", Value: "baz", ForceString: true},
2735+
}}
2736+
gitMock, dir, cleanup := mockGit(t)
2737+
defer cleanup()
2738+
of := filepath.Join(dir, ".argocd-source-testapp.yaml")
2739+
assert.NoError(t, os.WriteFile(of, []byte(`
2740+
helm:
2741+
parameters:
2742+
- name: foo
2743+
value: foo
2744+
forcestring: true
2745+
`), os.ModePerm))
2746+
2747+
gitMock.On("Checkout", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
2748+
args.Assert(t, "mydefaultbranch", false)
2749+
}).Return(nil)
2750+
gitMock.On("Add", mock.Anything).Return(nil)
2751+
gitMock.On("Commit", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
2752+
gitMock.On("Push", mock.Anything, mock.Anything, mock.Anything).Return(nil)
2753+
gitMock.On("SymRefToBranch", mock.Anything).Return("mydefaultbranch", nil)
2754+
wbc, err := getWriteBackConfig(app, &kubeClient, &argoClient)
2755+
require.NoError(t, err)
2756+
wbc.GitClient = gitMock
2757+
app.Spec.Source.TargetRevision = "HEAD"
2758+
wbc.GitBranch = ""
2759+
2760+
err = commitChanges(app, wbc, nil)
2761+
assert.NoError(t, err)
2762+
override, err := os.ReadFile(of)
2763+
assert.NoError(t, err)
2764+
assert.YAMLEq(t, `
2765+
helm:
2766+
parameters:
2767+
- name: foo
2768+
value: foo
2769+
forcestring: true
2770+
- name: bar
2771+
value: bar
2772+
forcestring: true
2773+
- name: baz
2774+
value: baz
2775+
forcestring: true
2776+
`, string(override))
2777+
})
2778+
2779+
t.Run("Good commit to helm override with another namespace", func(t *testing.T) {
2780+
kubeClient.Namespace = "argocd"
2781+
app := app.DeepCopy()
2782+
app.Status.SourceType = "Helm"
2783+
app.ObjectMeta.Namespace = "testNS"
2784+
app.Spec.Source.Helm = &v1alpha1.ApplicationSourceHelm{Parameters: []v1alpha1.HelmParameter{
2785+
{Name: "bar", Value: "bar", ForceString: true},
2786+
{Name: "baz", Value: "baz", ForceString: true},
2787+
}}
2788+
gitMock, dir, cleanup := mockGit(t)
2789+
defer cleanup()
2790+
of := filepath.Join(dir, ".argocd-source-testNS_testapp.yaml")
2791+
assert.NoError(t, os.WriteFile(of, []byte(`
2792+
helm:
2793+
parameters:
2794+
- name: foo
2795+
value: foo
2796+
forcestring: true
2797+
`), os.ModePerm))
2798+
2799+
gitMock.On("Checkout", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
2800+
args.Assert(t, "mydefaultbranch", false)
2801+
}).Return(nil)
2802+
gitMock.On("Add", mock.Anything).Return(nil)
2803+
gitMock.On("Commit", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
2804+
gitMock.On("Push", mock.Anything, mock.Anything, mock.Anything).Return(nil)
2805+
gitMock.On("SymRefToBranch", mock.Anything).Return("mydefaultbranch", nil)
2806+
wbc, err := getWriteBackConfig(app, &kubeClient, &argoClient)
2807+
require.NoError(t, err)
2808+
wbc.GitClient = gitMock
2809+
app.Spec.Source.TargetRevision = "HEAD"
2810+
wbc.GitBranch = ""
2811+
2812+
err = commitChanges(app, wbc, nil)
2813+
assert.NoError(t, err)
2814+
override, err := os.ReadFile(of)
2815+
assert.NoError(t, err)
2816+
assert.YAMLEq(t, `
2817+
helm:
2818+
parameters:
2819+
- name: foo
2820+
value: foo
2821+
forcestring: true
2822+
- name: bar
2823+
value: bar
2824+
forcestring: true
2825+
- name: baz
2826+
value: baz
2827+
forcestring: true
2828+
`, string(override))
2829+
})
2830+
27272831
t.Run("Good commit to kustomization", func(t *testing.T) {
27282832
app := app.DeepCopy()
27292833
app.Annotations[common.WriteBackTargetAnnotation] = "kustomization"

pkg/common/constants.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ const (
5757
)
5858

5959
// DefaultTargetFilePattern configurations related to the write-back functionality
60-
const DefaultTargetFilePattern = ".argocd-source-%s.yaml"
60+
const DefaultTargetFilePattern = ".argocd-source-%s_%s.yaml"
61+
const DefaultTargetFilePatternWithoutNamespace = ".argocd-source-%s.yaml"
6162
const DefaultHelmValuesFilename = "values.yaml"
6263

6364
// The default Git commit message's template

0 commit comments

Comments
 (0)