From 897698fb29bab9df188e8197a0c9d4a51561d2ee Mon Sep 17 00:00:00 2001 From: Donny Xia Date: Tue, 14 Jul 2020 17:01:11 -0700 Subject: [PATCH 1/3] Uniform unmarshal function --- api/internal/target/kusttarget.go | 13 +--------- api/types/kustomization.go | 24 +++++++++++++++++++ .../commands/kustfile/kustomizationfile.go | 2 +- .../kustfile/kustomizationfile_test.go | 18 ++++++++++++++ 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/api/internal/target/kusttarget.go b/api/internal/target/kusttarget.go index 275ebc990..9471ae5a5 100644 --- a/api/internal/target/kusttarget.go +++ b/api/internal/target/kusttarget.go @@ -4,7 +4,6 @@ package target import ( - "bytes" "encoding/json" "fmt" "strings" @@ -60,7 +59,7 @@ func (kt *KustTarget) Load() error { return err } var k types.Kustomization - err = unmarshal(content, &k) + err = k.Unmarshal(content) if err != nil { return err } @@ -104,16 +103,6 @@ func loadKustFile(ldr ifc.Loader) ([]byte, error) { } } -func unmarshal(y []byte, o interface{}) error { - j, err := yaml.YAMLToJSON(y) - if err != nil { - return err - } - dec := json.NewDecoder(bytes.NewReader(j)) - dec.DisallowUnknownFields() - return dec.Decode(o) -} - // MakeCustomizedResMap creates a fully customized ResMap // per the instructions contained in its kustomiztion instance. func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) { diff --git a/api/types/kustomization.go b/api/types/kustomization.go index e7a1f9dac..8cc7299b7 100644 --- a/api/types/kustomization.go +++ b/api/types/kustomization.go @@ -3,6 +3,13 @@ package types +import ( + "bytes" + "encoding/json" + + "sigs.k8s.io/yaml" +) + const ( KustomizationVersion = "kustomize.config.k8s.io/v1beta1" KustomizationKind = "Kustomization" @@ -165,3 +172,20 @@ func (k *Kustomization) EnforceFields() []string { } return errs } + +// Unmarshal replace k with the content in YAML input y +func (k *Kustomization) Unmarshal(y []byte) error { + j, err := yaml.YAMLToJSON(y) + if err != nil { + return err + } + dec := json.NewDecoder(bytes.NewReader(j)) + dec.DisallowUnknownFields() + var nk Kustomization + err = dec.Decode(&nk) + if err != nil { + return err + } + *k = nk + return nil +} diff --git a/kustomize/internal/commands/kustfile/kustomizationfile.go b/kustomize/internal/commands/kustfile/kustomizationfile.go index 2a9a77916..70a261372 100644 --- a/kustomize/internal/commands/kustfile/kustomizationfile.go +++ b/kustomize/internal/commands/kustfile/kustomizationfile.go @@ -153,7 +153,7 @@ func (mf *kustomizationFile) Read() (*types.Kustomization, error) { return nil, err } var k types.Kustomization - err = yaml.Unmarshal(data, &k) + err = k.Unmarshal(data) if err != nil { return nil, err } diff --git a/kustomize/internal/commands/kustfile/kustomizationfile_test.go b/kustomize/internal/commands/kustfile/kustomizationfile_test.go index a04338d19..59c5f77b6 100644 --- a/kustomize/internal/commands/kustfile/kustomizationfile_test.go +++ b/kustomize/internal/commands/kustfile/kustomizationfile_test.go @@ -340,3 +340,21 @@ kind: Kustomization string(expected), string(bytes)) } } + +func TestUnknownFieldInKustomization(t *testing.T) { + kContent := []byte(` +foo: + bar +`) + fSys := filesys.MakeFsInMemory() + testutils_test.WriteTestKustomizationWith(fSys, kContent) + mf, err := NewKustomizationFile(fSys) + if err != nil { + t.Fatalf("Unexpected Error: %v", err) + } + + _, err = mf.Read() + if err == nil || err.Error() != "json: unknown field \"foo\"" { + t.Fatalf("Expect an unknown field error but got: %v", err) + } +} From 14edc3890c82264777b48806cc3fb5d3464aafe2 Mon Sep 17 00:00:00 2001 From: Donny Xia Date: Wed, 15 Jul 2020 11:42:50 -0700 Subject: [PATCH 2/3] Add tests for kustomization.go --- api/types/kustomization_test.go | 184 ++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 api/types/kustomization_test.go diff --git a/api/types/kustomization_test.go b/api/types/kustomization_test.go new file mode 100644 index 000000000..f3482d90e --- /dev/null +++ b/api/types/kustomization_test.go @@ -0,0 +1,184 @@ +package types + +import ( + "testing" +) + +func fixKustomizationPostUnmarshallingCheck(k, e *Kustomization) bool { + return (k.Kind == e.Kind && k.APIVersion == e.APIVersion && + len(k.Resources) == len(e.Resources) && k.Resources[0] == e.Resources[0] && + k.Bases == nil) +} + +func TestFixKustomizationPostUnmarshalling(t *testing.T) { + var k Kustomization + k.Bases = append(k.Bases, "foo") + k.FixKustomizationPostUnmarshalling() + + expected := Kustomization{ + TypeMeta: TypeMeta{ + Kind: KustomizationKind, + APIVersion: KustomizationVersion, + }, + Resources: []string{"foo"}, + } + + if !fixKustomizationPostUnmarshallingCheck(&k, &expected) { + t.Fatalf("unexpected ouput: %v", k) + } +} + +func TestFixKustomizationPostUnmarshalling_2(t *testing.T) { + k := Kustomization{ + TypeMeta: TypeMeta{ + Kind: ComponentKind, + }, + } + k.Bases = append(k.Bases, "foo") + k.FixKustomizationPostUnmarshalling() + + expected := Kustomization{ + TypeMeta: TypeMeta{ + Kind: ComponentKind, + APIVersion: ComponentVersion, + }, + Resources: []string{"foo"}, + } + + if !fixKustomizationPostUnmarshallingCheck(&k, &expected) { + t.Fatalf("unexpected ouput: %v", k) + } +} + +func TestEnforceFields_InvalidKindAndVersion(t *testing.T) { + k := Kustomization{ + TypeMeta: TypeMeta{ + Kind: "foo", + APIVersion: "bar", + }, + } + + errs := k.EnforceFields() + if len(errs) != 2 { + t.Fatalf("number of errors should be 2 but got: %v", errs) + } +} + +func TestEnforceFields_InvalidKind(t *testing.T) { + k := Kustomization{ + TypeMeta: TypeMeta{ + Kind: "foo", + APIVersion: KustomizationVersion, + }, + } + + errs := k.EnforceFields() + if len(errs) != 1 { + t.Fatalf("number of errors should be 1 but got: %v", errs) + } + + expected := "kind should be " + KustomizationKind + " or " + ComponentKind + if errs[0] != expected { + t.Fatalf("error should be %v but got: %v", expected, errs[0]) + } +} + +func TestEnforceFields_InvalidVersion(t *testing.T) { + k := Kustomization{ + TypeMeta: TypeMeta{ + Kind: KustomizationKind, + APIVersion: "bar", + }, + } + + errs := k.EnforceFields() + if len(errs) != 1 { + t.Fatalf("number of errors should be 1 but got: %v", errs) + } + + expected := "apiVersion for " + k.Kind + " should be " + KustomizationVersion + if errs[0] != expected { + t.Fatalf("error should be %v but got: %v", expected, errs[0]) + } +} + +func TestEnforceFields_ComponentKind(t *testing.T) { + k := Kustomization{ + TypeMeta: TypeMeta{ + Kind: ComponentKind, + APIVersion: "bar", + }, + } + + errs := k.EnforceFields() + if len(errs) != 1 { + t.Fatalf("number of errors should be 1 but got: %v", errs) + } + + expected := "apiVersion for " + k.Kind + " should be " + ComponentVersion + if errs[0] != expected { + t.Fatalf("error should be %v but got: %v", expected, errs[0]) + } +} + +func TestEnforceFields(t *testing.T) { + k := Kustomization{ + TypeMeta: TypeMeta{ + Kind: KustomizationKind, + APIVersion: KustomizationVersion, + }, + } + + errs := k.EnforceFields() + if len(errs) != 0 { + t.Fatalf("number of errors should be 0 but got: %v", errs) + } +} + +func TestUnmarshal(t *testing.T) { + y := []byte(` +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- foo +- bar +nameSuffix: dog +namePrefix: cat`) + var k Kustomization + err := k.Unmarshal(y) + if err != nil { + t.Fatal(err) + } + if k.Kind != KustomizationKind || k.APIVersion != KustomizationVersion || + len(k.Resources) != 2 || k.NamePrefix != "cat" || k.NameSuffix != "dog" { + t.Fatalf("wrong unmarshal result: %v", k) + } +} + +func TestUnmarshal_UnkownField(t *testing.T) { + y := []byte(` +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +unknown: foo`) + var k Kustomization + err := k.Unmarshal(y) + if err == nil { + t.Fatalf("expect an error") + } + expect := "json: unknown field \"unknown\"" + if err.Error() != expect { + t.Fatalf("expect %v but got: %v", expect, err.Error()) + } +} + +func TestUnmarshal_InvalidYaml(t *testing.T) { + y := []byte(` +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +unknown`) + var k Kustomization + err := k.Unmarshal(y) + if err == nil { + t.Fatalf("expect an error") + } +} From 8401196ef92ce7ed3fd0ca4e3cfd5d593d7f7c0c Mon Sep 17 00:00:00 2001 From: Donny Xia Date: Wed, 15 Jul 2020 11:47:47 -0700 Subject: [PATCH 3/3] fix typo --- api/types/kustomization_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/types/kustomization_test.go b/api/types/kustomization_test.go index f3482d90e..57373ee5b 100644 --- a/api/types/kustomization_test.go +++ b/api/types/kustomization_test.go @@ -24,7 +24,7 @@ func TestFixKustomizationPostUnmarshalling(t *testing.T) { } if !fixKustomizationPostUnmarshallingCheck(&k, &expected) { - t.Fatalf("unexpected ouput: %v", k) + t.Fatalf("unexpected output: %v", k) } } @@ -46,7 +46,7 @@ func TestFixKustomizationPostUnmarshalling_2(t *testing.T) { } if !fixKustomizationPostUnmarshallingCheck(&k, &expected) { - t.Fatalf("unexpected ouput: %v", k) + t.Fatalf("unexpected output: %v", k) } }