Skip to content

Commit

Permalink
Preserve field order when updating kustomization.yaml file (argoproj-…
Browse files Browse the repository at this point in the history
…labs#666)

Signed-off-by: Jaye Doepke <jdoepke@mintel.com>
  • Loading branch information
jtdoepke authored Jul 17, 2024
1 parent 2bf4b0a commit 50360e9
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 2 deletions.
34 changes: 32 additions & 2 deletions pkg/argocd/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/order"
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"

"github.com/argoproj-labs/argocd-image-updater/pkg/image"
Expand Down Expand Up @@ -327,14 +328,43 @@ func writeKustomization(app *v1alpha1.Application, wbc *WriteBackConfig, gitC gi
if err != nil {
return err, false
}
err = kyaml.UpdateFile(filterFunc, kustFile)
if err != nil {

if err = updateKustomizeFile(filterFunc, kustFile); err != nil {
return err, false
}

return nil, false
}

// updateKustomizeFile reads the kustomization file at path, applies the filter to it, and writes the result back
// to the file. This is the same behavior as kyaml.UpdateFile, but it preserves the original order
// of YAML fields to minimize git diffs.
func updateKustomizeFile(filter kyaml.Filter, path string) error {
// Read the yaml
y, err := kyaml.ReadFile(path)
if err != nil {
return err
}

// Update the yaml
yCpy := y.Copy()
if err := yCpy.PipeE(filter); err != nil {
return err
}

// Preserve the original order of fields
if err := order.SyncOrder(y, yCpy); err != nil {
return err
}

// Write the yaml
if err := kyaml.WriteFile(yCpy, path); err != nil {
return err
}

return nil
}

func imagesFilter(images v1alpha1.KustomizeImages) (kyaml.Filter, error) {
var overrides []kyaml.Filter
for _, img := range images {
Expand Down
72 changes: 72 additions & 0 deletions pkg/argocd/git_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package argocd

import (
"os"
"testing"
"text/template"
"time"
Expand Down Expand Up @@ -215,3 +216,74 @@ images:
})
}
}

func Test_updateKustomizeFile(t *testing.T) {
makeTmpKustomization := func(t *testing.T, content []byte) string {
f, err := os.CreateTemp("", "kustomization-*.yaml")
if err != nil {
t.Fatal(err)
}
_, err = f.Write(content)
if err != nil {
t.Fatal(err)
}
f.Close()
t.Cleanup(func() {
os.Remove(f.Name())
})
return f.Name()
}

filter, err := imagesFilter(v1alpha1.KustomizeImages{"foo@sha23456"})
if err != nil {
t.Fatal(err)
}

tests := []struct {
name string
content string
wantContent string
filter kyaml.Filter
wantErr bool
}{
{
name: "sorted",
content: `images:
- digest: sha12345
name: foo
`,
wantContent: `images:
- digest: sha23456
name: foo
`,
filter: filter,
},
{
name: "not-sorted",
content: `images:
- name: foo
digest: sha12345
`,
wantContent: `images:
- name: foo
digest: sha23456
`,
filter: filter,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
path := makeTmpKustomization(t, []byte(tt.content))
err := updateKustomizeFile(tt.filter, path)
if tt.wantErr {
assert.Error(t, err)
} else {
got, err := os.ReadFile(path)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, tt.wantContent, string(got))
}
})
}
}

0 comments on commit 50360e9

Please sign in to comment.