mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
CRD v1: switch integration tests with defaulting to v1
This commit is contained in:
parent
9c3eedea18
commit
c8d085c19e
@ -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{
|
||||
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||
Group: "stable.example.com",
|
||||
Version: "v1beta1",
|
||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
||||
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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
`
|
||||
|
@ -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}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user