mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-07-01 18:30:15 +00:00
Merge pull request #2718 from Shell32-Natsu/unknown-fields
Uniform unmarshal function
This commit is contained in:
@@ -4,7 +4,6 @@
|
|||||||
package target
|
package target
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -60,7 +59,7 @@ func (kt *KustTarget) Load() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var k types.Kustomization
|
var k types.Kustomization
|
||||||
err = unmarshal(content, &k)
|
err = k.Unmarshal(content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
// MakeCustomizedResMap creates a fully customized ResMap
|
||||||
// per the instructions contained in its kustomiztion instance.
|
// per the instructions contained in its kustomiztion instance.
|
||||||
func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) {
|
func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) {
|
||||||
|
|||||||
@@ -3,6 +3,13 @@
|
|||||||
|
|
||||||
package types
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"sigs.k8s.io/yaml"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
KustomizationVersion = "kustomize.config.k8s.io/v1beta1"
|
KustomizationVersion = "kustomize.config.k8s.io/v1beta1"
|
||||||
KustomizationKind = "Kustomization"
|
KustomizationKind = "Kustomization"
|
||||||
@@ -165,3 +172,20 @@ func (k *Kustomization) EnforceFields() []string {
|
|||||||
}
|
}
|
||||||
return errs
|
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
|
||||||
|
}
|
||||||
|
|||||||
184
api/types/kustomization_test.go
Normal file
184
api/types/kustomization_test.go
Normal file
@@ -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 output: %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 output: %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")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -153,7 +153,7 @@ func (mf *kustomizationFile) Read() (*types.Kustomization, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var k types.Kustomization
|
var k types.Kustomization
|
||||||
err = yaml.Unmarshal(data, &k)
|
err = k.Unmarshal(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -340,3 +340,21 @@ kind: Kustomization
|
|||||||
string(expected), string(bytes))
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user