mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 03:11:40 +00:00
apiextensions: add x-kubernetes-embedded-resource integration tests
This commit is contained in:
parent
35054fa7ec
commit
e69f44e28b
@ -24,6 +24,7 @@ import (
|
||||
|
||||
"github.com/coreos/etcd/clientv3"
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
@ -33,9 +34,11 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
func TestPostInvalidObjectMeta(t *testing.T) {
|
||||
@ -99,6 +102,17 @@ func TestInvalidObjectMetaInStorage(t *testing.T) {
|
||||
}
|
||||
|
||||
noxuDefinition := fixtures.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.NamespaceScoped)
|
||||
noxuDefinition.Spec.Validation = &apiextensionsv1beta1.CustomResourceValidation{
|
||||
OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{
|
||||
Type: "object",
|
||||
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
|
||||
"embedded": {
|
||||
Type: "object",
|
||||
XEmbeddedResource: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -127,11 +141,17 @@ func TestInvalidObjectMetaInStorage(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Logf("Creating object with invalid labels manually in etcd")
|
||||
t.Logf("Creating object with wrongly typed annotations and non-validating labels manually in etcd")
|
||||
|
||||
original := fixtures.NewNoxuInstance("default", "foo")
|
||||
unstructured.SetNestedField(original.UnstructuredContent(), int64(42), "metadata", "unknown")
|
||||
unstructured.SetNestedField(original.UnstructuredContent(), map[string]interface{}{"foo": int64(42), "bar": "abc"}, "metadata", "labels")
|
||||
unstructured.SetNestedField(original.UnstructuredContent(), map[string]interface{}{"foo": int64(42), "bar": "abc"}, "metadata", "annotations")
|
||||
unstructured.SetNestedField(original.UnstructuredContent(), map[string]interface{}{"invalid": "x y"}, "metadata", "labels")
|
||||
unstructured.SetNestedField(original.UnstructuredContent(), int64(42), "embedded", "metadata", "unknown")
|
||||
unstructured.SetNestedField(original.UnstructuredContent(), map[string]interface{}{"foo": int64(42), "bar": "abc"}, "embedded", "metadata", "annotations")
|
||||
unstructured.SetNestedField(original.UnstructuredContent(), map[string]interface{}{"invalid": "x y"}, "embedded", "metadata", "labels")
|
||||
unstructured.SetNestedField(original.UnstructuredContent(), "Foo", "embedded", "kind")
|
||||
unstructured.SetNestedField(original.UnstructuredContent(), "foo/v1", "embedded", "apiVersion")
|
||||
|
||||
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), metav1.NamespaceDefault)
|
||||
key := path.Join("/", restOptions.StorageConfig.Prefix, noxuDefinition.Spec.Group, "noxus/default/foo")
|
||||
@ -140,25 +160,305 @@ func TestInvalidObjectMetaInStorage(t *testing.T) {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Checking that ObjectMeta is pruned from unknown fields")
|
||||
|
||||
t.Logf("Checking that invalid objects can be deleted")
|
||||
noxuResourceClient := newNamespacedCustomResourceClient("default", dynamicClient, noxuDefinition)
|
||||
obj, err := noxuResourceClient.Get("foo", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
if err := noxuResourceClient.Delete("foo", &metav1.DeleteOptions{}); err != nil {
|
||||
t.Fatalf("Unexpected delete error %v", err)
|
||||
}
|
||||
if _, err := etcdclient.Put(ctx, key, string(val)); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Checking that ObjectMeta is pruned from unknown fields")
|
||||
obj, err := noxuResourceClient.Get("foo", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
objJSON, _ := json.Marshal(obj.Object)
|
||||
t.Logf("Got object: %v", string(objJSON))
|
||||
|
||||
if unknown, found, err := unstructured.NestedFieldNoCopy(obj.UnstructuredContent(), "metadata", "unknown"); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
} else if found {
|
||||
t.Errorf("unexpected to find metadata.unknown=%#v", unknown)
|
||||
t.Errorf("Unexpected to find metadata.unknown=%#v", unknown)
|
||||
}
|
||||
if unknown, found, err := unstructured.NestedFieldNoCopy(obj.UnstructuredContent(), "embedded", "metadata", "unknown"); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
} else if found {
|
||||
t.Errorf("Unexpected to find embedded.metadata.unknown=%#v", unknown)
|
||||
}
|
||||
|
||||
t.Logf("Checking that ObjectMeta is pruned from invalid typed fields")
|
||||
t.Logf("Checking that ObjectMeta is pruned from wrongly-typed annotations")
|
||||
|
||||
if annotations, found, err := unstructured.NestedStringMap(obj.UnstructuredContent(), "metadata", "annotations"); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
} else if found {
|
||||
t.Errorf("Unexpected to find metadata.annotations: %#v", annotations)
|
||||
}
|
||||
if annotations, found, err := unstructured.NestedStringMap(obj.UnstructuredContent(), "embedded", "metadata", "annotations"); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
} else if found {
|
||||
t.Errorf("Unexpected to find embedded.metadata.annotations: %#v", annotations)
|
||||
}
|
||||
|
||||
t.Logf("Checking that ObjectMeta still has the non-validating labels")
|
||||
|
||||
if labels, found, err := unstructured.NestedStringMap(obj.UnstructuredContent(), "metadata", "labels"); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
} else if found && !reflect.DeepEqual(labels, map[string]string{"bar": "abc"}) {
|
||||
t.Errorf("unexpected to find metadata.lables=%#v", labels)
|
||||
} else if !found {
|
||||
t.Errorf("Expected to find metadata.labels, but didn't")
|
||||
} else if expected := map[string]string{"invalid": "x y"}; !reflect.DeepEqual(labels, expected) {
|
||||
t.Errorf("Expected metadata.labels to be %#v, got: %#v", expected, labels)
|
||||
}
|
||||
if labels, found, err := unstructured.NestedStringMap(obj.UnstructuredContent(), "embedded", "metadata", "labels"); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
} else if !found {
|
||||
t.Errorf("Expected to find embedded.metadata.labels, but didn't")
|
||||
} else if expected := map[string]string{"invalid": "x y"}; !reflect.DeepEqual(labels, expected) {
|
||||
t.Errorf("Expected embedded.metadata.labels to be %#v, got: %#v", expected, labels)
|
||||
}
|
||||
|
||||
t.Logf("Trying to fail on updating with invalid labels")
|
||||
unstructured.SetNestedField(obj.Object, "changed", "metadata", "labels", "something")
|
||||
if got, err := noxuResourceClient.Update(obj, metav1.UpdateOptions{}); err == nil {
|
||||
objJSON, _ := json.Marshal(obj.Object)
|
||||
gotJSON, _ := json.Marshal(got.Object)
|
||||
t.Fatalf("Expected update error, but didn't get one\nin: %s\nresponse: %v", string(objJSON), string(gotJSON))
|
||||
}
|
||||
|
||||
t.Logf("Trying to fail on updating with invalid embedded label")
|
||||
unstructured.SetNestedField(obj.Object, "fixed", "metadata", "labels", "invalid")
|
||||
if got, err := noxuResourceClient.Update(obj, metav1.UpdateOptions{}); err == nil {
|
||||
objJSON, _ := json.Marshal(obj.Object)
|
||||
gotJSON, _ := json.Marshal(got.Object)
|
||||
t.Fatalf("Expected update error, but didn't get one\nin: %s\nresponse: %v", string(objJSON), string(gotJSON))
|
||||
}
|
||||
|
||||
t.Logf("Fixed all labels and update should work")
|
||||
unstructured.SetNestedField(obj.Object, "fixed", "embedded", "metadata", "labels", "invalid")
|
||||
if _, err := noxuResourceClient.Update(obj, metav1.UpdateOptions{}); err != nil {
|
||||
t.Errorf("Unexpected update error with fixed labels: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Trying to fail on updating with wrongly-typed embedded label")
|
||||
unstructured.SetNestedField(obj.Object, int64(42), "embedded", "metadata", "labels", "invalid")
|
||||
if got, err := noxuResourceClient.Update(obj, metav1.UpdateOptions{}); err == nil {
|
||||
objJSON, _ := json.Marshal(obj.Object)
|
||||
gotJSON, _ := json.Marshal(got.Object)
|
||||
t.Fatalf("Expected update error, but didn't get one\nin: %s\nresponse: %v", string(objJSON), string(gotJSON))
|
||||
}
|
||||
}
|
||||
|
||||
var embeddedResourceFixture = &apiextensionsv1beta1.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foos.tests.apiextensions.k8s.io"},
|
||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
||||
Group: "tests.apiextensions.k8s.io",
|
||||
Version: "v1beta1",
|
||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
||||
Plural: "foos",
|
||||
Singular: "foo",
|
||||
Kind: "Foo",
|
||||
ListKind: "FooList",
|
||||
},
|
||||
Scope: apiextensionsv1beta1.ClusterScoped,
|
||||
PreserveUnknownFields: pointer.BoolPtr(true),
|
||||
Subresources: &apiextensionsv1beta1.CustomResourceSubresources{
|
||||
Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const (
|
||||
embeddedResourceSchema = `
|
||||
type: object
|
||||
properties:
|
||||
embedded:
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
noEmbeddedObject:
|
||||
type: object
|
||||
embeddedNested:
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
properties:
|
||||
embedded:
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
`
|
||||
|
||||
embeddedResourceInstance = `
|
||||
kind: Foo
|
||||
apiVersion: tests.apiextensions.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: foo
|
||||
embedded:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
unspecified: bar
|
||||
noEmbeddedObject:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
unspecified: bar
|
||||
embeddedNested:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
unspecified: bar
|
||||
embedded:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
unspecified: bar
|
||||
`
|
||||
|
||||
expectedEmbeddedResourceInstance = `
|
||||
kind: Foo
|
||||
apiVersion: tests.apiextensions.k8s.io/v1beta1
|
||||
embedded:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
noEmbeddedObject:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
unspecified: bar
|
||||
embeddedNested:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
embedded:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
`
|
||||
|
||||
wronglyTypedEmbeddedResourceInstance = `
|
||||
kind: Foo
|
||||
apiVersion: tests.apiextensions.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: invalid
|
||||
embedded:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: instance
|
||||
namespace: 42
|
||||
`
|
||||
|
||||
invalidEmbeddedResourceInstance = `
|
||||
kind: Foo
|
||||
apiVersion: tests.apiextensions.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: invalid
|
||||
embedded:
|
||||
apiVersion: foo/v1
|
||||
kind: "%"
|
||||
metadata:
|
||||
name: ..
|
||||
embeddedNested:
|
||||
apiVersion: foo/v1
|
||||
kind: "%"
|
||||
metadata:
|
||||
name: ..
|
||||
embedded:
|
||||
apiVersion: foo/v1
|
||||
kind: "%"
|
||||
metadata:
|
||||
name: ..
|
||||
`
|
||||
)
|
||||
|
||||
func TestEmbeddedResources(t *testing.T) {
|
||||
tearDownFn, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer tearDownFn()
|
||||
|
||||
crd := embeddedResourceFixture.DeepCopy()
|
||||
crd.Spec.Validation = &apiextensionsv1beta1.CustomResourceValidation{}
|
||||
if err := yaml.Unmarshal([]byte(embeddedResourceSchema), &crd.Spec.Validation.OpenAPIV3Schema); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
crd, err = fixtures.CreateNewCustomResourceDefinition(crd, apiExtensionClient, dynamicClient)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Logf("Creating CR and expect 'unspecified' fields to be pruned inside ObjectMetas")
|
||||
fooClient := dynamicClient.Resource(schema.GroupVersionResource{crd.Spec.Group, crd.Spec.Version, crd.Spec.Names.Plural})
|
||||
foo := &unstructured.Unstructured{}
|
||||
if err := yaml.Unmarshal([]byte(embeddedResourceInstance), &foo.Object); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
foo, err = fooClient.Create(foo, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create CR: %v", err)
|
||||
}
|
||||
t.Logf("CR created: %#v", foo.UnstructuredContent())
|
||||
|
||||
t.Logf("Checking that everything unknown inside ObjectMeta is gone")
|
||||
delete(foo.Object, "metadata")
|
||||
var expected map[string]interface{}
|
||||
if err := yaml.Unmarshal([]byte(expectedEmbeddedResourceInstance), &expected); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(expected, foo.Object) {
|
||||
t.Errorf("unexpected diff: %s", diff.ObjectDiff(expected, foo.Object))
|
||||
}
|
||||
|
||||
t.Logf("Trying to create wrongly typed CR")
|
||||
invalid := &unstructured.Unstructured{}
|
||||
if err := yaml.Unmarshal([]byte(wronglyTypedEmbeddedResourceInstance), &invalid.Object); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = fooClient.Create(invalid, metav1.CreateOptions{})
|
||||
if err == nil {
|
||||
t.Fatal("Expected creation to fail, but didn't")
|
||||
}
|
||||
t.Logf("Creation of wrongly typed object failed with: %v", err)
|
||||
|
||||
for _, s := range []string{
|
||||
`embedded.metadata: Invalid value`,
|
||||
} {
|
||||
if !strings.Contains(err.Error(), s) {
|
||||
t.Errorf("missing error: %s", s)
|
||||
}
|
||||
}
|
||||
|
||||
t.Logf("Trying to create invalid CR")
|
||||
wronglyTyped := &unstructured.Unstructured{}
|
||||
if err := yaml.Unmarshal([]byte(invalidEmbeddedResourceInstance), &wronglyTyped.Object); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = fooClient.Create(wronglyTyped, metav1.CreateOptions{})
|
||||
if err == nil {
|
||||
t.Fatal("Expected creation to fail, but didn't")
|
||||
}
|
||||
t.Logf("Creation of invalid object failed with: %v", err)
|
||||
|
||||
for _, s := range []string{
|
||||
`embedded.kind: Invalid value: "%"`,
|
||||
`embedded.metadata.name: Invalid value: ".."`,
|
||||
`embeddedNested.kind: Invalid value: "%"`,
|
||||
`embeddedNested.metadata.name: Invalid value: ".."`,
|
||||
`embeddedNested.embedded.kind: Invalid value: "%"`,
|
||||
`embeddedNested.embedded.metadata.name: Invalid value: ".."`,
|
||||
} {
|
||||
if !strings.Contains(err.Error(), s) {
|
||||
t.Errorf("missing error: %s", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,17 +18,21 @@ package integration
|
||||
|
||||
import (
|
||||
"path"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/coreos/etcd/clientv3"
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/client-go/dynamic"
|
||||
@ -107,6 +111,65 @@ properties:
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
`
|
||||
|
||||
fooSchemaEmbeddedResource = `
|
||||
type: object
|
||||
properties:
|
||||
embeddedPruning:
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
properties:
|
||||
specified:
|
||||
type: string
|
||||
embeddedPreserving:
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
embeddedNested:
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
properties:
|
||||
embeddedPruning:
|
||||
type: object
|
||||
x-kubernetes-embedded-resource: true
|
||||
properties:
|
||||
specified:
|
||||
type: string
|
||||
`
|
||||
|
||||
fooSchemaEmbeddedResourceInstance = fooInstance + `
|
||||
embeddedPruning:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
unspecified: bar
|
||||
unspecified: bar
|
||||
specified: bar
|
||||
embeddedPreserving:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
unspecified: bar
|
||||
unspecified: bar
|
||||
embeddedNested:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
unspecified: bar
|
||||
unspecified: bar
|
||||
embeddedPruning:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
unspecified: bar
|
||||
unspecified: bar
|
||||
specified: bar
|
||||
`
|
||||
|
||||
fooInstance = `
|
||||
kind: Foo
|
||||
apiVersion: tests.apiextensions.k8s.io/v1beta1
|
||||
@ -457,3 +520,72 @@ func TestPruningCreatePreservingUnknownFields(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPruningEmbeddedResources(t *testing.T) {
|
||||
tearDownFn, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer tearDownFn()
|
||||
|
||||
crd := pruningFixture.DeepCopy()
|
||||
crd.Spec.Validation = &apiextensionsv1beta1.CustomResourceValidation{}
|
||||
if err := yaml.Unmarshal([]byte(fooSchemaEmbeddedResource), &crd.Spec.Validation.OpenAPIV3Schema); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
crd, err = fixtures.CreateNewCustomResourceDefinition(crd, apiExtensionClient, dynamicClient)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Logf("Creating CR and expect 'unspecified' field to be pruned")
|
||||
fooClient := dynamicClient.Resource(schema.GroupVersionResource{crd.Spec.Group, crd.Spec.Version, crd.Spec.Names.Plural})
|
||||
foo := &unstructured.Unstructured{}
|
||||
if err := yaml.Unmarshal([]byte(fooSchemaEmbeddedResourceInstance), &foo.Object); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
foo, err = fooClient.Create(foo, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to create CR: %v", err)
|
||||
}
|
||||
t.Logf("CR created: %#v", foo.UnstructuredContent())
|
||||
|
||||
t.Logf("Comparing with expected, pruned value")
|
||||
x := runtime.DeepCopyJSON(foo.Object)
|
||||
delete(x, "apiVersion")
|
||||
delete(x, "kind")
|
||||
delete(x, "metadata")
|
||||
var expected map[string]interface{}
|
||||
if err := yaml.Unmarshal([]byte(`
|
||||
embeddedPruning:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
specified: bar
|
||||
embeddedPreserving:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
unspecified: bar
|
||||
embeddedNested:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
embeddedPruning:
|
||||
apiVersion: foo/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
name: foo
|
||||
specified: bar
|
||||
unspecified: bar
|
||||
`), &expected); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(expected, x) {
|
||||
t.Errorf("unexpected diff: %s", diff.ObjectDiff(expected, x))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user