summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authornoah <noah@hackedu.io>2021-10-21 21:34:05 +1300
committerGitHub <noreply@github.com>2021-10-21 10:34:05 +0200
commit4b130437536e3e321b4ad1ca9dc725f771f3d697 (patch)
tree3196cff76463904e24564d1da2a97a5367c10902 /pkg
parent89b10c14b5015b644f6d909cce067001220033e6 (diff)
fix: use kyaml to preserve kustomization (#274)
* fix: use kyaml to preserve kustomization fixes #250 fixes #268 fixes #247 * chore: linter error * fix: tests and linting * go mod tidy
Diffstat (limited to 'pkg')
-rw-r--r--pkg/argocd/git.go79
-rw-r--r--pkg/argocd/git_test.go83
-rw-r--r--pkg/argocd/update_test.go6
3 files changed, 137 insertions, 31 deletions
diff --git a/pkg/argocd/git.go b/pkg/argocd/git.go
index 7a52421..c191a31 100644
--- a/pkg/argocd/git.go
+++ b/pkg/argocd/git.go
@@ -9,9 +9,9 @@ import (
"path/filepath"
"text/template"
- "sigs.k8s.io/kustomize/pkg/commands/kustfile"
- "sigs.k8s.io/kustomize/pkg/fs"
- image2 "sigs.k8s.io/kustomize/pkg/image"
+ "sigs.k8s.io/kustomize/api/konfig"
+ "sigs.k8s.io/kustomize/api/types"
+ kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
"github.com/argoproj-labs/argocd-image-updater/pkg/image"
@@ -221,36 +221,71 @@ func writeKustomization(app *v1alpha1.Application, wbc *WriteBackConfig, gitC gi
log.Infof("updating base %s", base)
- kf, err := kustfile.NewKustomizationFile(fs.MakeRealFS())
+ kustFile := findKustomization(base)
+ if kustFile == "" {
+ return fmt.Errorf("could not find kustomization in %s", base), false
+ }
+
+ filterFunc, err := imagesFilter(app.Spec.Source.Kustomize.Images)
if err != nil {
- return
+ return err, false
}
- kustomization, err := kf.Read()
+ err = kyaml.UpdateFile(filterFunc, kustFile)
if err != nil {
- return
+ return err, false
}
-Images:
- for _, img := range app.Spec.Source.Kustomize.Images {
- override := parseImageOverride(img)
- for i, imgSet := range kustomization.Images {
- if imgSet.Name == override.Name {
- kustomization.Images[i] = override
- continue Images
- }
+ return nil, false
+}
+
+func imagesFilter(images v1alpha1.KustomizeImages) (kyaml.Filter, error) {
+ var overrides []kyaml.Filter
+ for _, img := range images {
+ override, err := imageFilter(parseImageOverride(img))
+ if err != nil {
+ return nil, err
}
- // wasn't an existing override, add one
- kustomization.Images = append(kustomization.Images, override)
+ overrides = append(overrides, override)
}
- if err := kf.Write(kustomization); err != nil {
- return err, false
+ return kyaml.FilterFunc(func(object *kyaml.RNode) (*kyaml.RNode, error) {
+ err := object.PipeE(append([]kyaml.Filter{kyaml.LookupCreate(
+ kyaml.SequenceNode, "images",
+ )}, overrides...)...)
+ return object, err
+ }), nil
+}
+
+func imageFilter(imgSet types.Image) (kyaml.Filter, error) {
+ data, err := kyaml.Marshal(imgSet)
+ if err != nil {
+ return nil, err
+ }
+ update, err := kyaml.Parse(string(data))
+ if err != nil {
+ return nil, err
}
+ setter := kyaml.ElementSetter{
+ Element: update.YNode(),
+ Keys: []string{"name"},
+ Values: []string{imgSet.Name},
+ }
+ return kyaml.FilterFunc(func(object *kyaml.RNode) (*kyaml.RNode, error) {
+ return object, object.PipeE(setter)
+ }), nil
+}
- return
+func findKustomization(base string) string {
+ for _, f := range konfig.RecognizedKustomizationFileNames() {
+ kustFile := path.Join(base, f)
+ if stat, err := os.Stat(kustFile); err == nil && !stat.IsDir() {
+ return kustFile
+ }
+ }
+ return ""
}
-func parseImageOverride(str v1alpha1.KustomizeImage) image2.Image {
+func parseImageOverride(str v1alpha1.KustomizeImage) types.Image {
// TODO is this a valid use? format could diverge
img := image.NewFromIdentifier(string(str))
tagName := ""
@@ -267,7 +302,7 @@ func parseImageOverride(str v1alpha1.KustomizeImage) image2.Image {
img.ImageAlias = img.ImageName
img.ImageName = "" // inside baseball (see return): name isn't changing, just tag, so don't write newName
}
- return image2.Image{
+ return types.Image{
Name: img.ImageAlias,
NewName: img.ImageName,
NewTag: tagName,
diff --git a/pkg/argocd/git_test.go b/pkg/argocd/git_test.go
index 5a60d57..92731d5 100644
--- a/pkg/argocd/git_test.go
+++ b/pkg/argocd/git_test.go
@@ -9,9 +9,11 @@ import (
"github.com/argoproj-labs/argocd-image-updater/pkg/image"
"github.com/argoproj-labs/argocd-image-updater/pkg/tag"
+ "sigs.k8s.io/kustomize/api/types"
+ kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
+
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/stretchr/testify/assert"
- image2 "sigs.k8s.io/kustomize/pkg/image"
)
func Test_TemplateCommitMessage(t *testing.T) {
@@ -44,36 +46,36 @@ func Test_parseImageOverride(t *testing.T) {
cases := []struct {
name string
override v1alpha1.KustomizeImage
- expected image2.Image
+ expected types.Image
}{
- {"tag update", "ghcr.io:1234/foo/foo:123", image2.Image{
+ {"tag update", "ghcr.io:1234/foo/foo:123", types.Image{
Name: "ghcr.io:1234/foo/foo",
NewTag: "123",
}},
- {"image update", "ghcr.io:1234/foo/foo=ghcr.io:1234/bar", image2.Image{
+ {"image update", "ghcr.io:1234/foo/foo=ghcr.io:1234/bar", types.Image{
Name: "ghcr.io:1234/foo/foo",
NewName: "ghcr.io:1234/bar",
}},
- {"update everything", "ghcr.io:1234/foo/foo=1234.foo.com:9876/bar:123", image2.Image{
+ {"update everything", "ghcr.io:1234/foo/foo=1234.foo.com:9876/bar:123", types.Image{
Name: "ghcr.io:1234/foo/foo",
NewName: "1234.foo.com:9876/bar",
NewTag: "123",
}},
- {"change registry and tag", "ghcr.io:1234/foo/foo=1234.dkr.ecr.us-east-1.amazonaws.com/bar:123", image2.Image{
+ {"change registry and tag", "ghcr.io:1234/foo/foo=1234.dkr.ecr.us-east-1.amazonaws.com/bar:123", types.Image{
Name: "ghcr.io:1234/foo/foo",
NewName: "1234.dkr.ecr.us-east-1.amazonaws.com/bar",
NewTag: "123",
}},
- {"change only registry", "0001.dkr.ecr.us-east-1.amazonaws.com/bar=1234.dkr.ecr.us-east-1.amazonaws.com/bar", image2.Image{
+ {"change only registry", "0001.dkr.ecr.us-east-1.amazonaws.com/bar=1234.dkr.ecr.us-east-1.amazonaws.com/bar", types.Image{
Name: "0001.dkr.ecr.us-east-1.amazonaws.com/bar",
NewName: "1234.dkr.ecr.us-east-1.amazonaws.com/bar",
}},
- {"change image and set digest", "foo=acme/app@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", image2.Image{
+ {"change image and set digest", "foo=acme/app@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", types.Image{
Name: "foo",
NewName: "acme/app",
Digest: "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
}},
- {"set digest", "acme/app@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", image2.Image{
+ {"set digest", "acme/app@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", types.Image{
Name: "acme/app",
Digest: "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
}},
@@ -86,3 +88,66 @@ func Test_parseImageOverride(t *testing.T) {
}
}
+
+func Test_imagesFilter(t *testing.T) {
+ for _, tt := range []struct {
+ name string
+ images v1alpha1.KustomizeImages
+ expected string
+ }{
+ {name: "simple", images: v1alpha1.KustomizeImages{"foo"}, expected: `
+images:
+- name: foo
+`},
+ {name: "tagged", images: v1alpha1.KustomizeImages{"foo:bar"}, expected: `
+images:
+- name: foo
+ newTag: bar
+`},
+ {name: "rename", images: v1alpha1.KustomizeImages{"baz=foo:bar"}, expected: `
+images:
+- name: baz
+ newName: foo
+ newTag: bar
+`},
+ {name: "digest", images: v1alpha1.KustomizeImages{"baz=foo@sha12345"}, expected: `
+images:
+- name: baz
+ newName: foo
+ digest: sha12345
+`},
+ {name: "digest simple", images: v1alpha1.KustomizeImages{"foo@sha12345"}, expected: `
+images:
+- name: foo
+ digest: sha12345
+`},
+ {name: "all", images: v1alpha1.KustomizeImages{
+ "foo",
+ "foo=bar", // merges with above
+ "baz@sha12345",
+ "bar:123",
+ "foo=bar:123", // merges and overwrites the first two
+ }, expected: `
+images:
+- name: foo
+ newName: bar
+ newTag: "123"
+- name: baz
+ digest: sha12345
+- name: bar
+ newTag: "123"
+`},
+ } {
+ t.Run(tt.name, func(t *testing.T) {
+ filter, err := imagesFilter(tt.images)
+ assert.NoError(t, err)
+
+ node := kyaml.NewRNode(&kyaml.Node{Kind: kyaml.DocumentNode, Content: []*kyaml.Node{
+ kyaml.NewMapRNode(nil).YNode(),
+ }})
+ node, err = filter.Filter(node)
+ assert.NoError(t, err)
+ assert.YAMLEq(t, tt.expected, node.MustString())
+ })
+ }
+}
diff --git a/pkg/argocd/update_test.go b/pkg/argocd/update_test.go
index 5b94b31..8ae9b2c 100644
--- a/pkg/argocd/update_test.go
+++ b/pkg/argocd/update_test.go
@@ -1737,6 +1737,8 @@ func Test_CommitUpdates(t *testing.T) {
assert.NoError(t, ioutil.WriteFile(kf, []byte(`
kind: Kustomization
apiVersion: kustomize.config.k8s.io/v1beta1
+
+replacements: []
`), os.ModePerm))
gitMock.On("Checkout", mock.Anything).Run(func(args mock.Arguments) {
@@ -1765,6 +1767,8 @@ images:
- name: bar
newName: baz
newTag: "123"
+
+replacements: []
`, string(kust))
// test the merge case too
@@ -1781,6 +1785,8 @@ images:
newTag: "123"
- name: bar
newName: qux
+
+replacements: []
`, string(kust))
})