CRD v1: switch integration tests with defaulting to v1

This commit is contained in:
Jordan Liggitt 2019-08-07 18:15:23 -04:00
parent 9c3eedea18
commit c8d085c19e
7 changed files with 175 additions and 92 deletions

View File

@ -41,8 +41,8 @@ import (
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/dynamic"
featuregatetesting "k8s.io/component-base/featuregate/testing"
"k8s.io/utils/pointer"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
"k8s.io/apiextensions-apiserver/pkg/cmd/server/options"
@ -845,8 +845,12 @@ func uidMutatingConverter(desiredAPIVersion string, obj runtime.RawExtension) (r
return runtime.RawExtension{Raw: raw}, nil
}
func newConversionTestContext(t *testing.T, apiExtensionsClient clientset.Interface, dynamicClient dynamic.Interface, etcdObjectReader *storage.EtcdObjectReader, crd *apiextensionsv1beta1.CustomResourceDefinition) (func(), *conversionTestContext) {
crd, err := fixtures.CreateNewCustomResourceDefinition(crd, apiExtensionsClient, dynamicClient)
func newConversionTestContext(t *testing.T, apiExtensionsClient clientset.Interface, dynamicClient dynamic.Interface, etcdObjectReader *storage.EtcdObjectReader, v1CRD *apiextensionsv1.CustomResourceDefinition) (func(), *conversionTestContext) {
v1CRD, err := fixtures.CreateNewV1CustomResourceDefinition(v1CRD, apiExtensionsClient, dynamicClient)
if err != nil {
t.Fatal(err)
}
crd, err := apiExtensionsClient.ApiextensionsV1beta1().CustomResourceDefinitions().Get(v1CRD.Name, metav1.GetOptions{})
if err != nil {
t.Fatal(err)
}
@ -1000,12 +1004,11 @@ func (c *conversionTestContext) waitForServed(t *testing.T, version string, serv
}
}
var multiVersionFixture = &apiextensionsv1beta1.CustomResourceDefinition{
var multiVersionFixture = &apiextensionsv1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{Name: "multiversion.stable.example.com"},
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
Group: "stable.example.com",
Version: "v1beta1",
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
Group: "stable.example.com",
Names: apiextensionsv1.CustomResourceDefinitionNames{
Plural: "multiversion",
Singular: "multiversion",
Kind: "MultiVersion",
@ -1013,34 +1016,41 @@ var multiVersionFixture = &apiextensionsv1beta1.CustomResourceDefinition{
ListKind: "MultiVersionList",
Categories: []string{"all"},
},
Scope: apiextensionsv1beta1.NamespaceScoped,
PreserveUnknownFields: pointer.BoolPtr(false),
Versions: []apiextensionsv1beta1.CustomResourceDefinitionVersion{
Scope: apiextensionsv1.NamespaceScoped,
PreserveUnknownFields: false,
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
{
// storage version, same schema as v1alpha1
Name: "v1beta1",
Served: true,
Storage: true,
Schema: &apiextensionsv1beta1.CustomResourceValidation{
OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{
Subresources: &apiextensionsv1.CustomResourceSubresources{
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
Scale: &apiextensionsv1.CustomResourceSubresourceScale{
SpecReplicasPath: ".spec.num.num1",
StatusReplicasPath: ".status.num.num2",
},
},
Schema: &apiextensionsv1.CustomResourceValidation{
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
Type: "object",
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"content": {
Type: "object",
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"key": {Type: "string"},
},
},
"num": {
Type: "object",
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"num1": {Type: "integer"},
"num2": {Type: "integer"},
},
},
"defaults": {
Type: "object",
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"v1alpha1": {Type: "boolean"},
"v1beta1": {Type: "boolean", Default: jsonPtr(true)},
"v1beta2": {Type: "boolean"},
@ -1055,26 +1065,33 @@ var multiVersionFixture = &apiextensionsv1beta1.CustomResourceDefinition{
Name: "v1alpha1",
Served: true,
Storage: false,
Schema: &apiextensionsv1beta1.CustomResourceValidation{
OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{
Subresources: &apiextensionsv1.CustomResourceSubresources{
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
Scale: &apiextensionsv1.CustomResourceSubresourceScale{
SpecReplicasPath: ".spec.num.num1",
StatusReplicasPath: ".status.num.num2",
},
},
Schema: &apiextensionsv1.CustomResourceValidation{
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
Type: "object",
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"content": {
Type: "object",
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"key": {Type: "string"},
},
},
"num": {
Type: "object",
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"num1": {Type: "integer"},
"num2": {Type: "integer"},
},
},
"defaults": {
Type: "object",
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"v1alpha1": {Type: "boolean", Default: jsonPtr(true)},
"v1beta1": {Type: "boolean"},
"v1beta2": {Type: "boolean"},
@ -1089,26 +1106,33 @@ var multiVersionFixture = &apiextensionsv1beta1.CustomResourceDefinition{
Name: "v1beta2",
Served: true,
Storage: false,
Schema: &apiextensionsv1beta1.CustomResourceValidation{
OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{
Subresources: &apiextensionsv1.CustomResourceSubresources{
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
Scale: &apiextensionsv1.CustomResourceSubresourceScale{
SpecReplicasPath: ".spec.num.num1",
StatusReplicasPath: ".status.num.num2",
},
},
Schema: &apiextensionsv1.CustomResourceValidation{
OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
Type: "object",
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"contentv2": {
Type: "object",
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"key": {Type: "string"},
},
},
"numv2": {
Type: "object",
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"num1": {Type: "integer"},
"num2": {Type: "integer"},
},
},
"defaults": {
Type: "object",
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
Properties: map[string]apiextensionsv1.JSONSchemaProps{
"v1alpha1": {Type: "boolean"},
"v1beta1": {Type: "boolean"},
"v1beta2": {Type: "boolean", Default: jsonPtr(true)},
@ -1119,13 +1143,6 @@ var multiVersionFixture = &apiextensionsv1beta1.CustomResourceDefinition{
},
},
},
Subresources: &apiextensionsv1beta1.CustomResourceSubresources{
Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{},
Scale: &apiextensionsv1beta1.CustomResourceSubresourceScale{
SpecReplicasPath: ".spec.num.num1",
StatusReplicasPath: ".status.num.num2",
},
},
},
}
@ -1234,11 +1251,11 @@ func closeOnCall(h http.Handler) (chan struct{}, http.Handler) {
})
}
func jsonPtr(x interface{}) *apiextensionsv1beta1.JSON {
func jsonPtr(x interface{}) *apiextensionsv1.JSON {
bs, err := json.Marshal(x)
if err != nil {
panic(err)
}
ret := apiextensionsv1beta1.JSON{Raw: bs}
ret := apiextensionsv1.JSON{Raw: bs}
return &ret
}

View File

@ -33,41 +33,42 @@ import (
"k8s.io/apimachinery/pkg/watch"
utilfeature "k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting "k8s.io/component-base/featuregate/testing"
"k8s.io/utils/pointer"
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apiextensions-apiserver/pkg/features"
"k8s.io/apiextensions-apiserver/test/integration/fixtures"
)
var defaultingFixture = &apiextensionsv1beta1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{Name: "foos.tests.apiextensions.k8s.io"},
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
Group: "tests.apiextensions.k8s.io",
Version: "v1beta1",
Versions: []apiextensionsv1beta1.CustomResourceDefinitionVersion{
var defaultingFixture = &apiextensionsv1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{Name: "foos.tests.example.com"},
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
Group: "tests.example.com",
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
{
Name: "v1beta1",
Storage: false,
Served: true,
Subresources: &apiextensionsv1.CustomResourceSubresources{
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
},
},
{
Name: "v1beta2",
Storage: true,
Served: false,
Subresources: &apiextensionsv1.CustomResourceSubresources{
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
},
},
},
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
Names: apiextensionsv1.CustomResourceDefinitionNames{
Plural: "foos",
Singular: "foo",
Kind: "Foo",
ListKind: "FooList",
},
Scope: apiextensionsv1beta1.ClusterScoped,
PreserveUnknownFields: pointer.BoolPtr(false),
Subresources: &apiextensionsv1beta1.CustomResourceSubresources{
Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{},
},
Scope: apiextensionsv1.ClusterScoped,
PreserveUnknownFields: false,
},
}
@ -163,16 +164,16 @@ func testDefaulting(t *testing.T, watchCache bool) {
defer tearDownFn()
crd := defaultingFixture.DeepCopy()
crd.Spec.Versions[0].Schema = &apiextensionsv1beta1.CustomResourceValidation{}
crd.Spec.Versions[0].Schema = &apiextensionsv1.CustomResourceValidation{}
if err := yaml.Unmarshal([]byte(defaultingFooV1beta1Schema), &crd.Spec.Versions[0].Schema.OpenAPIV3Schema); err != nil {
t.Fatal(err)
}
crd.Spec.Versions[1].Schema = &apiextensionsv1beta1.CustomResourceValidation{}
crd.Spec.Versions[1].Schema = &apiextensionsv1.CustomResourceValidation{}
if err := yaml.Unmarshal([]byte(defaultingFooV1beta2Schema), &crd.Spec.Versions[1].Schema.OpenAPIV3Schema); err != nil {
t.Fatal(err)
}
crd, err = fixtures.CreateNewCustomResourceDefinition(crd, apiExtensionClient, dynamicClient)
crd, err = fixtures.CreateNewV1CustomResourceDefinition(crd, apiExtensionClient, dynamicClient)
if err != nil {
t.Fatal(err)
}
@ -193,17 +194,17 @@ func testDefaulting(t *testing.T, watchCache bool) {
}
}
}
updateCRD := func(update func(*apiextensionsv1beta1.CustomResourceDefinition)) {
updateCRD := func(update func(*apiextensionsv1.CustomResourceDefinition)) {
t.Helper()
var err error
for retry := 0; retry < 10; retry++ {
var obj *apiextensionsv1beta1.CustomResourceDefinition
obj, err = apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().Get(crd.Name, metav1.GetOptions{})
var obj *apiextensionsv1.CustomResourceDefinition
obj, err = apiExtensionClient.ApiextensionsV1().CustomResourceDefinitions().Get(crd.Name, metav1.GetOptions{})
if err != nil {
t.Fatal(err)
}
update(obj)
obj, err = apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().Update(obj)
obj, err = apiExtensionClient.ApiextensionsV1().CustomResourceDefinitions().Update(obj)
if err != nil && apierrors.IsConflict(err) {
continue
} else if err != nil {
@ -218,13 +219,13 @@ func testDefaulting(t *testing.T, watchCache bool) {
}
addDefault := func(version string, key string, value interface{}) {
t.Helper()
updateCRD(func(obj *apiextensionsv1beta1.CustomResourceDefinition) {
updateCRD(func(obj *apiextensionsv1.CustomResourceDefinition) {
for _, root := range []string{"spec", "status"} {
for i := range obj.Spec.Versions {
if obj.Spec.Versions[i].Name != version {
continue
}
obj.Spec.Versions[i].Schema.OpenAPIV3Schema.Properties[root].Properties[key] = apiextensionsv1beta1.JSONSchemaProps{
obj.Spec.Versions[i].Schema.OpenAPIV3Schema.Properties[root].Properties[key] = apiextensionsv1.JSONSchemaProps{
Type: "string",
Default: jsonPtr(value),
}
@ -234,7 +235,7 @@ func testDefaulting(t *testing.T, watchCache bool) {
}
removeDefault := func(version string, key string) {
t.Helper()
updateCRD(func(obj *apiextensionsv1beta1.CustomResourceDefinition) {
updateCRD(func(obj *apiextensionsv1.CustomResourceDefinition) {
for _, root := range []string{"spec", "status"} {
for i := range obj.Spec.Versions {
if obj.Spec.Versions[i].Name != version {
@ -249,7 +250,7 @@ func testDefaulting(t *testing.T, watchCache bool) {
}
t.Logf("Creating CR and expecting defaulted fields in spec, but status does not exist at all")
fooClient := dynamicClient.Resource(schema.GroupVersionResource{crd.Spec.Group, crd.Spec.Version, crd.Spec.Names.Plural})
fooClient := dynamicClient.Resource(schema.GroupVersionResource{crd.Spec.Group, crd.Spec.Versions[0].Name, crd.Spec.Names.Plural})
foo := &unstructured.Unstructured{}
if err := yaml.Unmarshal([]byte(fooInstance), &foo.Object); err != nil {
t.Fatal(err)
@ -399,11 +400,11 @@ func testDefaulting(t *testing.T, watchCache bool) {
mustNotExist(foo.Object, [][]string{{"spec", "c"}})
}
func jsonPtr(x interface{}) *apiextensionsv1beta1.JSON {
func jsonPtr(x interface{}) *apiextensionsv1.JSON {
bs, err := json.Marshal(x)
if err != nil {
panic(err)
}
ret := apiextensionsv1beta1.JSON{Raw: bs}
ret := apiextensionsv1.JSON{Raw: bs}
return &ret
}

View File

@ -20,6 +20,7 @@ import (
"fmt"
"time"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
"k8s.io/apimachinery/pkg/api/errors"
@ -275,6 +276,63 @@ func CreateNewCustomResourceDefinition(crd *apiextensionsv1beta1.CustomResourceD
return crd, nil
}
// CreateNewV1CustomResourceDefinitionWatchUnsafe creates the CRD and makes sure
// the apiextension apiserver has installed the CRD. But it's not safe to watch
// the created CR. Please call CreateNewV1CustomResourceDefinition if you need to
// watch the CR.
func CreateNewV1CustomResourceDefinitionWatchUnsafe(v1CRD *apiextensionsv1.CustomResourceDefinition, apiExtensionsClient clientset.Interface) (*apiextensionsv1.CustomResourceDefinition, error) {
v1CRD, err := apiExtensionsClient.ApiextensionsV1().CustomResourceDefinitions().Create(v1CRD)
if err != nil {
return nil, err
}
crd, err := apiExtensionsClient.ApiextensionsV1beta1().CustomResourceDefinitions().Get(v1CRD.Name, metav1.GetOptions{})
if err != nil {
return nil, err
}
// wait until all resources appears in discovery
for _, version := range servedVersions(crd) {
err := wait.PollImmediate(500*time.Millisecond, 30*time.Second, func() (bool, error) {
return existsInDiscovery(crd, apiExtensionsClient, version)
})
if err != nil {
return nil, err
}
}
return v1CRD, err
}
// CreateNewV1CustomResourceDefinition creates the given CRD and makes sure its watch cache is primed on the server.
func CreateNewV1CustomResourceDefinition(v1CRD *apiextensionsv1.CustomResourceDefinition, apiExtensionsClient clientset.Interface, dynamicClientSet dynamic.Interface) (*apiextensionsv1.CustomResourceDefinition, error) {
v1CRD, err := CreateNewV1CustomResourceDefinitionWatchUnsafe(v1CRD, apiExtensionsClient)
if err != nil {
return nil, err
}
crd, err := apiExtensionsClient.ApiextensionsV1beta1().CustomResourceDefinitions().Get(v1CRD.Name, metav1.GetOptions{})
if err != nil {
return nil, err
}
// This is only for a test. We need the watch cache to have a resource version that works for the test.
// When new REST storage is created, the storage cacher for the CR starts asynchronously.
// REST API operations return like list use the RV of etcd, but the storage cacher's reflector's list
// can get a different RV because etcd can be touched in between the initial list operation (if that's what you're doing first)
// and the storage cache reflector starting.
// Later, you can issue a watch with the REST apis list.RV and end up earlier than the storage cacher.
// The general working model is that if you get a "resourceVersion too old" message, you re-list and rewatch.
// For this test, we'll actually cycle, "list/watch/create/delete" until we get an RV from list that observes the create and not an error.
// This way all the tests that are checking for watches don't have to worry about RV too old problems because crazy things *could* happen
// before like the created RV could be too old to watch.
err = wait.PollImmediate(500*time.Millisecond, 30*time.Second, func() (bool, error) {
return isWatchCachePrimed(crd, dynamicClientSet)
})
if err != nil {
return nil, err
}
return v1CRD, nil
}
func resourceClientForVersion(crd *apiextensionsv1beta1.CustomResourceDefinition, dynamicClientSet dynamic.Interface, namespace, version string) dynamic.ResourceInterface {
gvr := schema.GroupVersionResource{Group: crd.Spec.Group, Version: version, Resource: crd.Spec.Names.Plural}
if crd.Spec.Scope != apiextensionsv1beta1.ClusterScoped {

View File

@ -26,6 +26,7 @@ import (
"github.com/coreos/etcd/pkg/transport"
"sigs.k8s.io/yaml"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
serveroptions "k8s.io/apiextensions-apiserver/pkg/cmd/server/options"
@ -253,22 +254,28 @@ func TestInvalidObjectMetaInStorage(t *testing.T) {
}
}
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{
var embeddedResourceFixture = &apiextensionsv1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{Name: "foos.tests.example.com"},
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
Group: "tests.example.com",
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
{
Name: "v1beta1",
Storage: true,
Served: true,
Subresources: &apiextensionsv1.CustomResourceSubresources{
Status: &apiextensionsv1.CustomResourceSubresourceStatus{},
},
},
},
Names: apiextensionsv1.CustomResourceDefinitionNames{
Plural: "foos",
Singular: "foo",
Kind: "Foo",
ListKind: "FooList",
},
Scope: apiextensionsv1beta1.ClusterScoped,
PreserveUnknownFields: pointer.BoolPtr(false),
Subresources: &apiextensionsv1beta1.CustomResourceSubresources{
Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{},
},
Scope: apiextensionsv1.ClusterScoped,
PreserveUnknownFields: false,
},
}
@ -319,7 +326,7 @@ properties:
embeddedResourceInstance = `
kind: Foo
apiVersion: tests.apiextensions.k8s.io/v1beta1
apiVersion: tests.example.com/v1beta1
embedded:
apiVersion: foo/v1
kind: Foo
@ -348,7 +355,7 @@ embeddedNested:
expectedEmbeddedResourceInstance = `
kind: Foo
apiVersion: tests.apiextensions.k8s.io/v1beta1
apiVersion: tests.example.com/v1beta1
embedded:
apiVersion: foo/v1
kind: Foo
@ -379,7 +386,7 @@ defaults:
wronglyTypedEmbeddedResourceInstance = `
kind: Foo
apiVersion: tests.apiextensions.k8s.io/v1beta1
apiVersion: tests.example.com/v1beta1
embedded:
apiVersion: foo/v1
kind: Foo
@ -390,7 +397,7 @@ embedded:
invalidEmbeddedResourceInstance = `
kind: Foo
apiVersion: tests.apiextensions.k8s.io/v1beta1
apiVersion: tests.example.com/v1beta1
embedded:
apiVersion: foo/v1
kind: "%"
@ -420,18 +427,18 @@ func TestEmbeddedResources(t *testing.T) {
defer tearDownFn()
crd := embeddedResourceFixture.DeepCopy()
crd.Spec.Validation = &apiextensionsv1beta1.CustomResourceValidation{}
if err := yaml.Unmarshal([]byte(embeddedResourceSchema), &crd.Spec.Validation.OpenAPIV3Schema); err != nil {
crd.Spec.Versions[0].Schema = &apiextensionsv1.CustomResourceValidation{}
if err := yaml.Unmarshal([]byte(embeddedResourceSchema), &crd.Spec.Versions[0].Schema.OpenAPIV3Schema); err != nil {
t.Fatal(err)
}
crd, err = fixtures.CreateNewCustomResourceDefinition(crd, apiExtensionClient, dynamicClient)
crd, err = fixtures.CreateNewV1CustomResourceDefinition(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})
fooClient := dynamicClient.Resource(schema.GroupVersionResource{crd.Spec.Group, crd.Spec.Versions[0].Name, crd.Spec.Names.Plural})
foo := &unstructured.Unstructured{}
if err := yaml.Unmarshal([]byte(embeddedResourceInstance), &foo.Object); err != nil {
t.Fatal(err)

View File

@ -44,9 +44,9 @@ import (
)
var pruningFixture = &apiextensionsv1beta1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{Name: "foos.tests.apiextensions.k8s.io"},
ObjectMeta: metav1.ObjectMeta{Name: "foos.tests.example.com"},
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
Group: "tests.apiextensions.k8s.io",
Group: "tests.example.com",
Version: "v1beta1",
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
Plural: "foos",
@ -172,7 +172,7 @@ embeddedNested:
fooInstance = `
kind: Foo
apiVersion: tests.apiextensions.k8s.io/v1beta1
apiVersion: tests.example.com/v1beta1
metadata:
name: foo
`

View File

@ -25,7 +25,7 @@ import (
"github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/pkg/transport"
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/storage/storagebackend"
@ -35,11 +35,11 @@ import (
type EtcdObjectReader struct {
etcdClient *clientv3.Client
storagePrefix string
crd *apiextensionsv1beta1.CustomResourceDefinition
crd *apiextensionsv1.CustomResourceDefinition
}
// NewEtcdObjectReader creates a reader for accessing custom resource objects directly from etcd.
func NewEtcdObjectReader(etcdClient *clientv3.Client, restOptions *generic.RESTOptions, crd *apiextensionsv1beta1.CustomResourceDefinition) *EtcdObjectReader {
func NewEtcdObjectReader(etcdClient *clientv3.Client, restOptions *generic.RESTOptions, crd *apiextensionsv1.CustomResourceDefinition) *EtcdObjectReader {
return &EtcdObjectReader{etcdClient, restOptions.StorageConfig.Prefix, crd}
}

View File

@ -548,9 +548,9 @@ func TestNonStructuralSchemaConditionUpdate(t *testing.T) {
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: foos.tests.apiextensions.k8s.io
name: foos.tests.example.com
spec:
group: tests.apiextensions.k8s.io
group: tests.example.com
version: v1beta1
names:
plural: foos