Add integration test for apiextensions
* add integration test for name conflicts of CRDs * fix naming controller so that when a resource is deleted, other resources in the same group are added to the queue * add integration test for self link (clusterscoped resources) * fix minor nits address comments add comments and fix nits Bigger poll interval customResource -> crd Fix DeleteCustomResourceDefinition condition
This commit is contained in:
		@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
Copyright 2016 The Kubernetes Authors.
 | 
					Copyright 2017 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
Copyright 2016 The Kubernetes Authors.
 | 
					Copyright 2017 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@ package status
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/golang/glog"
 | 
						"github.com/golang/glog"
 | 
				
			||||||
@@ -230,6 +231,11 @@ func equalToAcceptedOrFresh(requestedName, acceptedName string, usedNames sets.S
 | 
				
			|||||||
func (c *NamingConditionController) sync(key string) error {
 | 
					func (c *NamingConditionController) sync(key string) error {
 | 
				
			||||||
	inCustomResourceDefinition, err := c.crdLister.Get(key)
 | 
						inCustomResourceDefinition, err := c.crdLister.Get(key)
 | 
				
			||||||
	if apierrors.IsNotFound(err) {
 | 
						if apierrors.IsNotFound(err) {
 | 
				
			||||||
 | 
							// CRD was deleted and has freed its names.
 | 
				
			||||||
 | 
							// Reconsider all other CRDs in the same group.
 | 
				
			||||||
 | 
							if err := c.requeueAllOtherGroupCRDs(key); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -264,14 +270,8 @@ func (c *NamingConditionController) sync(key string) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// we updated our status, so we may be releasing a name.  When this happens, we need to rekick everything in our group
 | 
						// we updated our status, so we may be releasing a name.  When this happens, we need to rekick everything in our group
 | 
				
			||||||
	// if we fail to rekick, just return as normal.  We'll get everything on a resync
 | 
						// if we fail to rekick, just return as normal.  We'll get everything on a resync
 | 
				
			||||||
	list, err := c.crdLister.List(labels.Everything())
 | 
						if err := c.requeueAllOtherGroupCRDs(key); err != nil {
 | 
				
			||||||
	if err != nil {
 | 
							return err
 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, curr := range list {
 | 
					 | 
				
			||||||
		if curr.Spec.Group == crd.Spec.Group {
 | 
					 | 
				
			||||||
			c.queue.Add(curr.Name)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
@@ -358,3 +358,17 @@ func (c *NamingConditionController) deleteCustomResourceDefinition(obj interface
 | 
				
			|||||||
	glog.V(4).Infof("Deleting %q", castObj.Name)
 | 
						glog.V(4).Infof("Deleting %q", castObj.Name)
 | 
				
			||||||
	c.enqueue(castObj)
 | 
						c.enqueue(castObj)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *NamingConditionController) requeueAllOtherGroupCRDs(name string) error {
 | 
				
			||||||
 | 
						pluralGroup := strings.SplitN(name, ".", 2)
 | 
				
			||||||
 | 
						list, err := c.crdLister.List(labels.Everything())
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, curr := range list {
 | 
				
			||||||
 | 
							if curr.Spec.Group == pluralGroup[1] && curr.Name != name {
 | 
				
			||||||
 | 
								c.queue.Add(curr.Name)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,7 @@ go_test(
 | 
				
			|||||||
        "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
					        "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
				
			||||||
        "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
 | 
					        "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
 | 
				
			||||||
        "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
					        "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
 | 
				
			||||||
 | 
					        "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
 | 
				
			||||||
        "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
 | 
					        "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
 | 
				
			||||||
        "//vendor/k8s.io/client-go/dynamic:go_default_library",
 | 
					        "//vendor/k8s.io/client-go/dynamic:go_default_library",
 | 
				
			||||||
        "//vendor/k8s.io/kube-apiextensions-server/pkg/apis/apiextensions/v1alpha1:go_default_library",
 | 
					        "//vendor/k8s.io/kube-apiextensions-server/pkg/apis/apiextensions/v1alpha1:go_default_library",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,6 +26,7 @@ import (
 | 
				
			|||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 | 
						"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/util/wait"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/watch"
 | 
						"k8s.io/apimachinery/pkg/watch"
 | 
				
			||||||
	"k8s.io/client-go/dynamic"
 | 
						"k8s.io/client-go/dynamic"
 | 
				
			||||||
	apiextensionsv1alpha1 "k8s.io/kube-apiextensions-server/pkg/apis/apiextensions/v1alpha1"
 | 
						apiextensionsv1alpha1 "k8s.io/kube-apiextensions-server/pkg/apis/apiextensions/v1alpha1"
 | 
				
			||||||
@@ -309,6 +310,7 @@ func TestSelfLink(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	defer close(stopCh)
 | 
						defer close(stopCh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// namespace scoped
 | 
				
			||||||
	noxuDefinition := testserver.NewNoxuCustomResourceDefinition(apiextensionsv1alpha1.NamespaceScoped)
 | 
						noxuDefinition := testserver.NewNoxuCustomResourceDefinition(apiextensionsv1alpha1.NamespaceScoped)
 | 
				
			||||||
	noxuVersionClient, err := testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool)
 | 
						noxuVersionClient, err := testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -318,7 +320,7 @@ func TestSelfLink(t *testing.T) {
 | 
				
			|||||||
	ns := "not-the-default"
 | 
						ns := "not-the-default"
 | 
				
			||||||
	noxuNamespacedResourceClient := noxuVersionClient.Resource(&metav1.APIResource{
 | 
						noxuNamespacedResourceClient := noxuVersionClient.Resource(&metav1.APIResource{
 | 
				
			||||||
		Name:       noxuDefinition.Spec.Names.Plural,
 | 
							Name:       noxuDefinition.Spec.Names.Plural,
 | 
				
			||||||
		Namespaced: true,
 | 
							Namespaced: noxuDefinition.Spec.Scope == apiextensionsv1alpha1.NamespaceScoped,
 | 
				
			||||||
	}, ns)
 | 
						}, ns)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	noxuInstanceToCreate := testserver.NewNoxuInstance(ns, "foo")
 | 
						noxuInstanceToCreate := testserver.NewNoxuInstance(ns, "foo")
 | 
				
			||||||
@@ -331,8 +333,27 @@ func TestSelfLink(t *testing.T) {
 | 
				
			|||||||
		t.Errorf("expected %v, got %v", e, a)
 | 
							t.Errorf("expected %v, got %v", e, a)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO add test for cluster scoped self-link when its available
 | 
						// cluster scoped
 | 
				
			||||||
 | 
						curletDefinition := testserver.NewCurletCustomResourceDefinition(apiextensionsv1alpha1.ClusterScoped)
 | 
				
			||||||
 | 
						curletVersionClient, err := testserver.CreateNewCustomResourceDefinition(curletDefinition, apiExtensionClient, clientPool)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						curletResourceClient := curletVersionClient.Resource(&metav1.APIResource{
 | 
				
			||||||
 | 
							Name:       curletDefinition.Spec.Names.Plural,
 | 
				
			||||||
 | 
							Namespaced: curletDefinition.Spec.Scope == apiextensionsv1alpha1.NamespaceScoped,
 | 
				
			||||||
 | 
						}, ns)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						curletInstanceToCreate := testserver.NewCurletInstance(ns, "foo")
 | 
				
			||||||
 | 
						createdCurletInstance, err := curletResourceClient.Create(curletInstanceToCreate)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if e, a := "/apis/mygroup.example.com/v1alpha1/foo", createdCurletInstance.GetSelfLink(); e != a {
 | 
				
			||||||
 | 
							t.Errorf("expected %v, got %v", e, a)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestPreserveInt(t *testing.T) {
 | 
					func TestPreserveInt(t *testing.T) {
 | 
				
			||||||
@@ -515,3 +536,64 @@ func checkNamespacesWatchHelper(t *testing.T, ns string, namespacedwatch watch.I
 | 
				
			|||||||
		namespacedAddEvent++
 | 
							namespacedAddEvent++
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestNameConflict(t *testing.T) {
 | 
				
			||||||
 | 
						stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer close(stopCh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						noxuDefinition := testserver.NewNoxuCustomResourceDefinition(apiextensionsv1alpha1.NamespaceScoped)
 | 
				
			||||||
 | 
						_, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						noxu2Definition := testserver.NewNoxu2CustomResourceDefinition(apiextensionsv1alpha1.NamespaceScoped)
 | 
				
			||||||
 | 
						_, err = apiExtensionClient.Apiextensions().CustomResourceDefinitions().Create(noxu2Definition)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// A NameConflict occurs
 | 
				
			||||||
 | 
						err = wait.Poll(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) {
 | 
				
			||||||
 | 
							crd, err := testserver.GetCustomResourceDefinition(noxu2Definition, apiExtensionClient)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return false, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, condition := range crd.Status.Conditions {
 | 
				
			||||||
 | 
								if condition.Type == apiextensionsv1alpha1.NamesAccepted && condition.Status == apiextensionsv1alpha1.ConditionFalse {
 | 
				
			||||||
 | 
									return true, nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false, nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = testserver.DeleteCustomResourceDefinition(noxuDefinition, apiExtensionClient)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Names are now accepted
 | 
				
			||||||
 | 
						err = wait.Poll(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) {
 | 
				
			||||||
 | 
							crd, err := testserver.GetCustomResourceDefinition(noxu2Definition, apiExtensionClient)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return false, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, condition := range crd.Status.Conditions {
 | 
				
			||||||
 | 
								if condition.Type == apiextensionsv1alpha1.NamesAccepted && condition.Status == apiextensionsv1alpha1.ConditionTrue {
 | 
				
			||||||
 | 
									return true, nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false, nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -67,6 +67,24 @@ func NewNoxuInstance(namespace, name string) *unstructured.Unstructured {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewNoxu2CustomResourceDefinition(scope apiextensionsv1alpha1.ResourceScope) *apiextensionsv1alpha1.CustomResourceDefinition {
 | 
				
			||||||
 | 
						return &apiextensionsv1alpha1.CustomResourceDefinition{
 | 
				
			||||||
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "noxus2.mygroup.example.com"},
 | 
				
			||||||
 | 
							Spec: apiextensionsv1alpha1.CustomResourceDefinitionSpec{
 | 
				
			||||||
 | 
								Group:   "mygroup.example.com",
 | 
				
			||||||
 | 
								Version: "v1alpha1",
 | 
				
			||||||
 | 
								Names: apiextensionsv1alpha1.CustomResourceDefinitionNames{
 | 
				
			||||||
 | 
									Plural:     "noxus2",
 | 
				
			||||||
 | 
									Singular:   "nonenglishnoxu2",
 | 
				
			||||||
 | 
									Kind:       "WishIHadChosenNoxu2",
 | 
				
			||||||
 | 
									ShortNames: []string{"foo", "bar", "abc", "def"},
 | 
				
			||||||
 | 
									ListKind:   "Noxu2ItemList",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Scope: scope,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewCurletCustomResourceDefinition(scope apiextensionsv1alpha1.ResourceScope) *apiextensionsv1alpha1.CustomResourceDefinition {
 | 
					func NewCurletCustomResourceDefinition(scope apiextensionsv1alpha1.ResourceScope) *apiextensionsv1alpha1.CustomResourceDefinition {
 | 
				
			||||||
	return &apiextensionsv1alpha1.CustomResourceDefinition{
 | 
						return &apiextensionsv1alpha1.CustomResourceDefinition{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{Name: "curlets.mygroup.example.com"},
 | 
							ObjectMeta: metav1.ObjectMeta{Name: "curlets.mygroup.example.com"},
 | 
				
			||||||
@@ -100,20 +118,20 @@ func NewCurletInstance(namespace, name string) *unstructured.Unstructured {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func CreateNewCustomResourceDefinition(customResourceDefinition *apiextensionsv1alpha1.CustomResourceDefinition, apiExtensionsClient clientset.Interface, clientPool dynamic.ClientPool) (*dynamic.Client, error) {
 | 
					func CreateNewCustomResourceDefinition(crd *apiextensionsv1alpha1.CustomResourceDefinition, apiExtensionsClient clientset.Interface, clientPool dynamic.ClientPool) (*dynamic.Client, error) {
 | 
				
			||||||
	_, err := apiExtensionsClient.Apiextensions().CustomResourceDefinitions().Create(customResourceDefinition)
 | 
						_, err := apiExtensionsClient.Apiextensions().CustomResourceDefinitions().Create(crd)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// wait until the resource appears in discovery
 | 
						// wait until the resource appears in discovery
 | 
				
			||||||
	err = wait.PollImmediate(30*time.Millisecond, 30*time.Second, func() (bool, error) {
 | 
						err = wait.PollImmediate(500*time.Millisecond, 30*time.Second, func() (bool, error) {
 | 
				
			||||||
		resourceList, err := apiExtensionsClient.Discovery().ServerResourcesForGroupVersion(customResourceDefinition.Spec.Group + "/" + customResourceDefinition.Spec.Version)
 | 
							resourceList, err := apiExtensionsClient.Discovery().ServerResourcesForGroupVersion(crd.Spec.Group + "/" + crd.Spec.Version)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return false, nil
 | 
								return false, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for _, resource := range resourceList.APIResources {
 | 
							for _, resource := range resourceList.APIResources {
 | 
				
			||||||
			if resource.Name == customResourceDefinition.Spec.Names.Plural {
 | 
								if resource.Name == crd.Spec.Names.Plural {
 | 
				
			||||||
				return true, nil
 | 
									return true, nil
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -123,29 +141,36 @@ func CreateNewCustomResourceDefinition(customResourceDefinition *apiextensionsv1
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dynamicClient, err := clientPool.ClientForGroupVersionResource(schema.GroupVersionResource{Group: customResourceDefinition.Spec.Group, Version: customResourceDefinition.Spec.Version, Resource: customResourceDefinition.Spec.Names.Plural})
 | 
						dynamicClient, err := clientPool.ClientForGroupVersionResource(schema.GroupVersionResource{Group: crd.Spec.Group, Version: crd.Spec.Version, Resource: crd.Spec.Names.Plural})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return dynamicClient, nil
 | 
						return dynamicClient, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func DeleteCustomResourceDefinition(customResource *apiextensionsv1alpha1.CustomResourceDefinition, apiExtensionsClient clientset.Interface) error {
 | 
					func DeleteCustomResourceDefinition(crd *apiextensionsv1alpha1.CustomResourceDefinition, apiExtensionsClient clientset.Interface) error {
 | 
				
			||||||
	if err := apiExtensionsClient.Apiextensions().CustomResourceDefinitions().Delete(customResource.Name, nil); err != nil {
 | 
						if err := apiExtensionsClient.Apiextensions().CustomResourceDefinitions().Delete(crd.Name, nil); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err := wait.PollImmediate(30*time.Millisecond, 30*time.Second, func() (bool, error) {
 | 
						err := wait.PollImmediate(500*time.Millisecond, 30*time.Second, func() (bool, error) {
 | 
				
			||||||
		if _, err := apiExtensionsClient.Discovery().ServerResourcesForGroupVersion(customResource.Spec.Group + "/" + customResource.Spec.Version); err != nil {
 | 
							groupResource, err := apiExtensionsClient.Discovery().ServerResourcesForGroupVersion(crd.Spec.Group + "/" + crd.Spec.Version)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
			if errors.IsNotFound(err) {
 | 
								if errors.IsNotFound(err) {
 | 
				
			||||||
				return true, nil
 | 
									return true, nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return false, err
 | 
								return false, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return false, nil
 | 
							for _, g := range groupResource.APIResources {
 | 
				
			||||||
 | 
								if g.Name == crd.Spec.Names.Plural {
 | 
				
			||||||
 | 
									return false, nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return true, nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetCustomResourceDefinition(customResource *apiextensionsv1alpha1.CustomResourceDefinition, apiExtensionsClient clientset.Interface) (*apiextensionsv1alpha1.CustomResourceDefinition, error) {
 | 
					func GetCustomResourceDefinition(crd *apiextensionsv1alpha1.CustomResourceDefinition, apiExtensionsClient clientset.Interface) (*apiextensionsv1alpha1.CustomResourceDefinition, error) {
 | 
				
			||||||
	return apiExtensionsClient.Apiextensions().CustomResourceDefinitions().Get(customResource.Name, metav1.GetOptions{})
 | 
						return apiExtensionsClient.Apiextensions().CustomResourceDefinitions().Get(crd.Name, metav1.GetOptions{})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user