mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Updating federation e2e tests to verify cascading deletion
This commit is contained in:
		@@ -22,6 +22,7 @@ import (
 | 
			
		||||
	"os"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
 | 
			
		||||
@@ -53,13 +54,8 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
 | 
			
		||||
	Describe("Federated Ingresses", func() {
 | 
			
		||||
		AfterEach(func() {
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			// Delete registered ingresses.
 | 
			
		||||
			ingressList, err := f.FederationClientset_1_5.Extensions().Ingresses(nsName).List(v1.ListOptions{})
 | 
			
		||||
			Expect(err).NotTo(HaveOccurred())
 | 
			
		||||
			for _, ingress := range ingressList.Items {
 | 
			
		||||
				err := f.FederationClientset_1_5.Extensions().Ingresses(nsName).Delete(ingress.Name, &v1.DeleteOptions{})
 | 
			
		||||
				Expect(err).NotTo(HaveOccurred())
 | 
			
		||||
			}
 | 
			
		||||
			// Delete all ingresses.
 | 
			
		||||
			deleteAllIngressesOrFail(f.FederationClientset_1_5, nsName)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should be created and deleted successfully", func() {
 | 
			
		||||
@@ -97,26 +93,43 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		AfterEach(func() {
 | 
			
		||||
			// Delete all ingresses.
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			deleteAllIngressesOrFail(f.FederationClientset_1_5, nsName)
 | 
			
		||||
			unregisterClusters(clusters, f)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should create and update matching ingresses in underlying clusters", func() {
 | 
			
		||||
			ingress := createIngressOrFail(f.FederationClientset_1_5, ns)
 | 
			
		||||
			defer func() { // Cleanup
 | 
			
		||||
				By(fmt.Sprintf("Deleting ingress %q in namespace %q", ingress.Name, ns))
 | 
			
		||||
				err := f.FederationClientset_1_5.Ingresses(ns).Delete(ingress.Name, &v1.DeleteOptions{})
 | 
			
		||||
				framework.ExpectNoError(err, "Error deleting ingress %q/%q in federation", ns, ingress.Name)
 | 
			
		||||
				for clusterName, cluster := range clusters {
 | 
			
		||||
					err := cluster.Ingresses(ns).Delete(ingress.Name, &v1.DeleteOptions{})
 | 
			
		||||
					framework.ExpectNoError(err, "Error deleting ingress %q/%q in cluster %q", ns, ingress.Name, clusterName)
 | 
			
		||||
				}
 | 
			
		||||
			}()
 | 
			
		||||
			// wait for ingress shards being created
 | 
			
		||||
			waitForIngressShardsOrFail(ns, ingress, clusters)
 | 
			
		||||
			ingress = updateIngressOrFail(f.FederationClientset_1_5, ns)
 | 
			
		||||
			waitForIngressShardsUpdatedOrFail(ns, ingress, clusters)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should be deleted from underlying clusters when OrphanDependents is false", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			orphanDependents := false
 | 
			
		||||
			verifyCascadingDeletionForIngress(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that ingresses were deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			orphanDependents := true
 | 
			
		||||
			verifyCascadingDeletionForIngress(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that ingresses were not deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			verifyCascadingDeletionForIngress(f.FederationClientset_1_5, clusters, nil, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that ingresses were not deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		var _ = Describe("Ingress connectivity and DNS", func() {
 | 
			
		||||
 | 
			
		||||
			var (
 | 
			
		||||
@@ -147,7 +160,7 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
 | 
			
		||||
					By("No service to delete. Service is nil")
 | 
			
		||||
				}
 | 
			
		||||
				if jig.ing != nil {
 | 
			
		||||
					deleteIngressOrFail(f.FederationClientset_1_5, ns, jig.ing.Name)
 | 
			
		||||
					deleteIngressOrFail(f.FederationClientset_1_5, ns, jig.ing.Name, nil)
 | 
			
		||||
					for clusterName, cluster := range clusters {
 | 
			
		||||
						deleteClusterIngressOrFail(clusterName, cluster.Clientset, ns, jig.ing.Name)
 | 
			
		||||
					}
 | 
			
		||||
@@ -182,6 +195,13 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
 | 
			
		||||
	})
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// Deletes all Ingresses in the given namespace name.
 | 
			
		||||
func deleteAllIngressesOrFail(clientset *fedclientset.Clientset, nsName string) {
 | 
			
		||||
	orphanDependents := false
 | 
			
		||||
	err := clientset.Extensions().Ingresses(nsName).DeleteCollection(&v1.DeleteOptions{OrphanDependents: &orphanDependents}, v1.ListOptions{})
 | 
			
		||||
	Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error in deleting ingresses in namespace: %s", nsName))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
   equivalent returns true if the two ingress spec are equivalent.
 | 
			
		||||
*/
 | 
			
		||||
@@ -189,6 +209,36 @@ func equivalentIngress(federatedIngress, clusterIngress v1beta1.Ingress) bool {
 | 
			
		||||
	return reflect.DeepEqual(clusterIngress.Spec, federatedIngress.Spec)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// verifyCascadingDeletionForIngress verifies that ingresses are deleted from
 | 
			
		||||
// underlying clusters when orphan dependents is false and they are not deleted
 | 
			
		||||
// when orphan dependents is true.
 | 
			
		||||
func verifyCascadingDeletionForIngress(clientset *fedclientset.Clientset, clusters map[string]*cluster, orphanDependents *bool, nsName string) {
 | 
			
		||||
	ingress := createIngressOrFail(clientset, nsName)
 | 
			
		||||
	ingressName := ingress.Name
 | 
			
		||||
	// Check subclusters if the ingress was created there.
 | 
			
		||||
	By(fmt.Sprintf("Waiting for ingress %s to be created in all underlying clusters", ingressName))
 | 
			
		||||
	waitForIngressShardsOrFail(nsName, ingress, clusters)
 | 
			
		||||
 | 
			
		||||
	By(fmt.Sprintf("Deleting ingress %s", ingressName))
 | 
			
		||||
	deleteIngressOrFail(clientset, nsName, ingressName, orphanDependents)
 | 
			
		||||
 | 
			
		||||
	By(fmt.Sprintf("Verifying ingresses %s in underlying clusters", ingressName))
 | 
			
		||||
	errMessages := []string{}
 | 
			
		||||
	// ingress should be present in underlying clusters unless orphanDependents is false.
 | 
			
		||||
	shouldExist := orphanDependents == nil || *orphanDependents == true
 | 
			
		||||
	for clusterName, clusterClientset := range clusters {
 | 
			
		||||
		_, err := clusterClientset.Extensions().Ingresses(nsName).Get(ingressName)
 | 
			
		||||
		if shouldExist && errors.IsNotFound(err) {
 | 
			
		||||
			errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for ingress %s in cluster %s, expected ingress to exist", ingressName, clusterName))
 | 
			
		||||
		} else if !shouldExist && !errors.IsNotFound(err) {
 | 
			
		||||
			errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for ingress %s in cluster %s, got error: %v", ingressName, clusterName, err))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(errMessages) != 0 {
 | 
			
		||||
		framework.Failf("%s", strings.Join(errMessages, "; "))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
   waitForIngressOrFail waits until a ingress is either present or absent in the cluster specified by clientset.
 | 
			
		||||
   If the condition is not met within timout, it fails the calling test.
 | 
			
		||||
@@ -268,12 +318,23 @@ func waitForIngressShardsGoneOrFail(namespace string, ingress *v1beta1.Ingress,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func deleteIngressOrFail(clientset *fedclientset.Clientset, namespace string, ingressName string) {
 | 
			
		||||
func deleteIngressOrFail(clientset *fedclientset.Clientset, namespace string, ingressName string, orphanDependents *bool) {
 | 
			
		||||
	if clientset == nil || len(namespace) == 0 || len(ingressName) == 0 {
 | 
			
		||||
		Fail(fmt.Sprintf("Internal error: invalid parameters passed to deleteIngressOrFail: clientset: %v, namespace: %v, ingress: %v", clientset, namespace, ingressName))
 | 
			
		||||
	}
 | 
			
		||||
	err := clientset.Ingresses(namespace).Delete(ingressName, v1.NewDeleteOptions(0))
 | 
			
		||||
	err := clientset.Ingresses(namespace).Delete(ingressName, &v1.DeleteOptions{OrphanDependents: orphanDependents})
 | 
			
		||||
	framework.ExpectNoError(err, "Error deleting ingress %q from namespace %q", ingressName, namespace)
 | 
			
		||||
	// Wait for the ingress to be deleted.
 | 
			
		||||
	err = wait.Poll(framework.Poll, wait.ForeverTestTimeout, func() (bool, error) {
 | 
			
		||||
		_, err := clientset.Extensions().Ingresses(namespace).Get(ingressName)
 | 
			
		||||
		if err != nil && errors.IsNotFound(err) {
 | 
			
		||||
			return true, nil
 | 
			
		||||
		}
 | 
			
		||||
		return false, err
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		framework.Failf("Error in deleting ingress %s: %v", ingressName, err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: quinton: This is largely a cut 'n paste of the above.  Yuck! Refactor as soon as we have a common interface implmented by both fedclientset.Clientset and kubeclientset.Clientset
 | 
			
		||||
 
 | 
			
		||||
@@ -59,11 +59,11 @@ var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func
 | 
			
		||||
 | 
			
		||||
		AfterEach(func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			deleteAllTestNamespaces(false,
 | 
			
		||||
			deleteAllTestNamespaces(nil,
 | 
			
		||||
				f.FederationClientset_1_5.Core().Namespaces().List,
 | 
			
		||||
				f.FederationClientset_1_5.Core().Namespaces().Delete)
 | 
			
		||||
			for _, cluster := range clusters {
 | 
			
		||||
				deleteAllTestNamespaces(false,
 | 
			
		||||
				deleteAllTestNamespaces(nil,
 | 
			
		||||
					cluster.Core().Namespaces().List,
 | 
			
		||||
					cluster.Core().Namespaces().Delete)
 | 
			
		||||
			}
 | 
			
		||||
@@ -76,22 +76,30 @@ var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func
 | 
			
		||||
			nsName := createNamespace(f.FederationClientset_1_5.Core().Namespaces())
 | 
			
		||||
 | 
			
		||||
			By(fmt.Sprintf("Deleting namespace %s", nsName))
 | 
			
		||||
			deleteAllTestNamespaces(false,
 | 
			
		||||
			deleteAllTestNamespaces(nil,
 | 
			
		||||
				f.FederationClientset_1_5.Core().Namespaces().List,
 | 
			
		||||
				f.FederationClientset_1_5.Core().Namespaces().Delete)
 | 
			
		||||
			By(fmt.Sprintf("Verified that deletion succeeded"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should be deleted from underlying clusters when OrphanDependents is false", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
 | 
			
		||||
			verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, false)
 | 
			
		||||
			orphanDependents := false
 | 
			
		||||
			verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, &orphanDependents)
 | 
			
		||||
			By(fmt.Sprintf("Verified that namespaces were deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			orphanDependents := true
 | 
			
		||||
			verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, &orphanDependents)
 | 
			
		||||
			By(fmt.Sprintf("Verified that namespaces were not deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
			verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, true)
 | 
			
		||||
		It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
 | 
			
		||||
			verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, nil)
 | 
			
		||||
			By(fmt.Sprintf("Verified that namespaces were not deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
@@ -119,7 +127,7 @@ var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			By(fmt.Sprintf("Deleting namespace %s", nsName))
 | 
			
		||||
			deleteAllTestNamespaces(false,
 | 
			
		||||
			deleteAllTestNamespaces(nil,
 | 
			
		||||
				f.FederationClientset_1_5.Core().Namespaces().List,
 | 
			
		||||
				f.FederationClientset_1_5.Core().Namespaces().Delete)
 | 
			
		||||
 | 
			
		||||
@@ -133,10 +141,10 @@ var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func
 | 
			
		||||
	})
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// Verifies that namespaces are deleted from underlying clusters when orphan dependents is false
 | 
			
		||||
// and they are not deleted when orphan dependents is true.
 | 
			
		||||
func verifyNsCascadingDeletion(nsClient clientset.NamespaceInterface,
 | 
			
		||||
	clusters map[string]*cluster, orphanDependents bool) {
 | 
			
		||||
// verifyNsCascadingDeletion verifies that namespaces are deleted from
 | 
			
		||||
// underlying clusters when orphan dependents is false and they are not
 | 
			
		||||
// deleted when orphan dependents is true.
 | 
			
		||||
func verifyNsCascadingDeletion(nsClient clientset.NamespaceInterface, clusters map[string]*cluster, orphanDependents *bool) {
 | 
			
		||||
	nsName := createNamespace(nsClient)
 | 
			
		||||
	// Check subclusters if the namespace was created there.
 | 
			
		||||
	By(fmt.Sprintf("Waiting for namespace %s to be created in all underlying clusters", nsName))
 | 
			
		||||
@@ -159,11 +167,13 @@ func verifyNsCascadingDeletion(nsClient clientset.NamespaceInterface,
 | 
			
		||||
 | 
			
		||||
	By(fmt.Sprintf("Verifying namespaces %s in underlying clusters", nsName))
 | 
			
		||||
	errMessages := []string{}
 | 
			
		||||
	// namespace should be present in underlying clusters unless orphanDependents is false.
 | 
			
		||||
	shouldExist := orphanDependents == nil || *orphanDependents == true
 | 
			
		||||
	for clusterName, clusterClientset := range clusters {
 | 
			
		||||
		_, err := clusterClientset.Core().Namespaces().Get(nsName)
 | 
			
		||||
		if orphanDependents && errors.IsNotFound(err) {
 | 
			
		||||
		if shouldExist && errors.IsNotFound(err) {
 | 
			
		||||
			errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for namespace %s in cluster %s, expected namespace to exist", nsName, clusterName))
 | 
			
		||||
		} else if !orphanDependents && (err == nil || !errors.IsNotFound(err)) {
 | 
			
		||||
		} else if !shouldExist && !errors.IsNotFound(err) {
 | 
			
		||||
			errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for namespace %s in cluster %s, got error: %v", nsName, clusterName, err))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -185,7 +195,7 @@ func createNamespace(nsClient clientset.NamespaceInterface) string {
 | 
			
		||||
	return ns.Name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func deleteAllTestNamespaces(orphanDependents bool, lister func(api_v1.ListOptions) (*api_v1.NamespaceList, error), deleter func(string, *api_v1.DeleteOptions) error) {
 | 
			
		||||
func deleteAllTestNamespaces(orphanDependents *bool, lister func(api_v1.ListOptions) (*api_v1.NamespaceList, error), deleter func(string, *api_v1.DeleteOptions) error) {
 | 
			
		||||
	list, err := lister(api_v1.ListOptions{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		framework.Failf("Failed to get all namespaes: %v", err)
 | 
			
		||||
@@ -194,7 +204,7 @@ func deleteAllTestNamespaces(orphanDependents bool, lister func(api_v1.ListOptio
 | 
			
		||||
	for _, namespace := range list.Items {
 | 
			
		||||
		if strings.HasPrefix(namespace.Name, namespacePrefix) {
 | 
			
		||||
			By(fmt.Sprintf("Deleting ns: %s, found by listing", namespace.Name))
 | 
			
		||||
			err := deleter(namespace.Name, &api_v1.DeleteOptions{OrphanDependents: &orphanDependents})
 | 
			
		||||
			err := deleter(namespace.Name, &api_v1.DeleteOptions{OrphanDependents: orphanDependents})
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				framework.Failf("Failed to set %s for deletion: %v", namespace.Name, err)
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -55,16 +55,17 @@ var _ = framework.KubeDescribe("Federation secrets [Feature:Federation]", func()
 | 
			
		||||
 | 
			
		||||
		AfterEach(func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			// Delete all secrets.
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			deleteAllSecretsOrFail(f.FederationClientset_1_5, nsName)
 | 
			
		||||
			unregisterClusters(clusters, f)
 | 
			
		||||
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should be created and deleted successfully", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			secret := createSecretOrFail(f.FederationClientset_1_5, nsName)
 | 
			
		||||
			defer func() { // Cleanup
 | 
			
		||||
				deleteSecretOrFail(f.FederationClientset_1_5, nsName, secret.Name, true)
 | 
			
		||||
			}()
 | 
			
		||||
			// wait for secret shards being created
 | 
			
		||||
			waitForSecretShardsOrFail(nsName, secret, clusters)
 | 
			
		||||
			secret = updateSecretOrFail(f.FederationClientset_1_5, nsName, secret.Name)
 | 
			
		||||
@@ -74,23 +75,42 @@ var _ = framework.KubeDescribe("Federation secrets [Feature:Federation]", func()
 | 
			
		||||
		It("should be deleted from underlying clusters when OrphanDependents is false", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			verifyCascadingDeletion(f.FederationClientset_1_5, clusters, false, nsName)
 | 
			
		||||
			orphanDependents := false
 | 
			
		||||
			verifyCascadingDeletionForSecret(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that secrets were deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			verifyCascadingDeletion(f.FederationClientset_1_5, clusters, true, nsName)
 | 
			
		||||
			orphanDependents := true
 | 
			
		||||
			verifyCascadingDeletionForSecret(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that secrets were not deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			verifyCascadingDeletionForSecret(f.FederationClientset_1_5, clusters, nil, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that secrets were not deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// Verifies that secrets are deleted from underlying clusters when orphan dependents is false
 | 
			
		||||
// and they are not deleted when orphan dependents is true.
 | 
			
		||||
func verifyCascadingDeletion(clientset *fedclientset.Clientset,
 | 
			
		||||
	clusters map[string]*cluster, orphanDependents bool, nsName string) {
 | 
			
		||||
// deleteAllSecretsOrFail deletes all secrets in the given namespace name.
 | 
			
		||||
func deleteAllSecretsOrFail(clientset *fedclientset.Clientset, nsName string) {
 | 
			
		||||
	SecretList, err := clientset.Core().Secrets(nsName).List(v1.ListOptions{})
 | 
			
		||||
	Expect(err).NotTo(HaveOccurred())
 | 
			
		||||
	orphanDependents := false
 | 
			
		||||
	for _, Secret := range SecretList.Items {
 | 
			
		||||
		deleteSecretOrFail(clientset, nsName, Secret.Name, &orphanDependents)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// verifyCascadingDeletionForSecret verifies that secrets are deleted from
 | 
			
		||||
// underlying clusters when orphan dependents is false and they are not
 | 
			
		||||
// deleted when orphan dependents is true.
 | 
			
		||||
func verifyCascadingDeletionForSecret(clientset *fedclientset.Clientset, clusters map[string]*cluster, orphanDependents *bool, nsName string) {
 | 
			
		||||
	secret := createSecretOrFail(clientset, nsName)
 | 
			
		||||
	secretName := secret.Name
 | 
			
		||||
	// Check subclusters if the secret was created there.
 | 
			
		||||
@@ -104,7 +124,6 @@ func verifyCascadingDeletion(clientset *fedclientset.Clientset,
 | 
			
		||||
				}
 | 
			
		||||
				return false, nil
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		return true, nil
 | 
			
		||||
	})
 | 
			
		||||
@@ -115,11 +134,13 @@ func verifyCascadingDeletion(clientset *fedclientset.Clientset,
 | 
			
		||||
 | 
			
		||||
	By(fmt.Sprintf("Verifying secrets %s in underlying clusters", secretName))
 | 
			
		||||
	errMessages := []string{}
 | 
			
		||||
	// secret should be present in underlying clusters unless orphanDependents is false.
 | 
			
		||||
	shouldExist := orphanDependents == nil || *orphanDependents == true
 | 
			
		||||
	for clusterName, clusterClientset := range clusters {
 | 
			
		||||
		_, err := clusterClientset.Core().Secrets(nsName).Get(secretName)
 | 
			
		||||
		if orphanDependents && errors.IsNotFound(err) {
 | 
			
		||||
		if shouldExist && errors.IsNotFound(err) {
 | 
			
		||||
			errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for secret %s in cluster %s, expected secret to exist", secretName, clusterName))
 | 
			
		||||
		} else if !orphanDependents && (err == nil || !errors.IsNotFound(err)) {
 | 
			
		||||
		} else if !shouldExist && !errors.IsNotFound(err) {
 | 
			
		||||
			errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for secret %s in cluster %s, got error: %v", secretName, clusterName, err))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -146,9 +167,9 @@ func createSecretOrFail(clientset *fedclientset.Clientset, nsName string) *v1.Se
 | 
			
		||||
	return secret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func deleteSecretOrFail(clientset *fedclientset.Clientset, nsName string, secretName string, orphanDependents bool) {
 | 
			
		||||
func deleteSecretOrFail(clientset *fedclientset.Clientset, nsName string, secretName string, orphanDependents *bool) {
 | 
			
		||||
	By(fmt.Sprintf("Deleting secret %q in namespace %q", secretName, nsName))
 | 
			
		||||
	err := clientset.Core().Secrets(nsName).Delete(secretName, &v1.DeleteOptions{OrphanDependents: &orphanDependents})
 | 
			
		||||
	err := clientset.Core().Secrets(nsName).Delete(secretName, &v1.DeleteOptions{OrphanDependents: orphanDependents})
 | 
			
		||||
	framework.ExpectNoError(err, "Error deleting secret %q in namespace %q", secretName, nsName)
 | 
			
		||||
 | 
			
		||||
	// Wait for the secret to be deleted.
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ package e2e
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	. "github.com/onsi/ginkgo"
 | 
			
		||||
@@ -39,7 +40,7 @@ const (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Create/delete daemonset api objects
 | 
			
		||||
var _ = framework.KubeDescribe("Federation daemonsets [Feature:Federation12]", func() {
 | 
			
		||||
var _ = framework.KubeDescribe("Federation daemonsets [Feature:Federation]", func() {
 | 
			
		||||
	var clusters map[string]*cluster // All clusters, keyed by cluster name
 | 
			
		||||
 | 
			
		||||
	f := framework.NewDefaultFederatedFramework("federated-daemonset")
 | 
			
		||||
@@ -54,6 +55,9 @@ var _ = framework.KubeDescribe("Federation daemonsets [Feature:Federation12]", f
 | 
			
		||||
 | 
			
		||||
		AfterEach(func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			// Delete all daemonsets.
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			deleteAllDaemonSetsOrFail(f.FederationClientset_1_5, nsName)
 | 
			
		||||
			unregisterClusters(clusters, f)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
@@ -71,8 +75,82 @@ var _ = framework.KubeDescribe("Federation daemonsets [Feature:Federation12]", f
 | 
			
		||||
			daemonset = updateDaemonSetOrFail(f.FederationClientset_1_5, nsName)
 | 
			
		||||
			waitForDaemonSetShardsUpdatedOrFail(nsName, daemonset, clusters)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should be deleted from underlying clusters when OrphanDependents is false", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			orphanDependents := false
 | 
			
		||||
			verifyCascadingDeletionForDS(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that daemonsets were deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			orphanDependents := true
 | 
			
		||||
			verifyCascadingDeletionForDS(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that daemonsets were not deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
		It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			verifyCascadingDeletionForDS(f.FederationClientset_1_5, clusters, nil, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that daemonsets were not deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// deleteAllDaemonSetsOrFail deletes all DaemonSets in the given namespace name.
 | 
			
		||||
func deleteAllDaemonSetsOrFail(clientset *fedclientset.Clientset, nsName string) {
 | 
			
		||||
	DaemonSetList, err := clientset.Extensions().DaemonSets(nsName).List(v1.ListOptions{})
 | 
			
		||||
	Expect(err).NotTo(HaveOccurred())
 | 
			
		||||
	orphanDependents := false
 | 
			
		||||
	for _, daemonSet := range DaemonSetList.Items {
 | 
			
		||||
		deleteDaemonSetOrFail(clientset, nsName, daemonSet.Name, &orphanDependents)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// verifyCascadingDeletionForDS verifies that daemonsets are deleted from
 | 
			
		||||
// underlying clusters when orphan dependents is false and they are not
 | 
			
		||||
// deleted when orphan dependents is true.
 | 
			
		||||
func verifyCascadingDeletionForDS(clientset *fedclientset.Clientset, clusters map[string]*cluster, orphanDependents *bool, nsName string) {
 | 
			
		||||
	daemonset := createDaemonSetOrFail(clientset, nsName)
 | 
			
		||||
	daemonsetName := daemonset.Name
 | 
			
		||||
	// Check subclusters if the daemonset was created there.
 | 
			
		||||
	By(fmt.Sprintf("Waiting for daemonset %s to be created in all underlying clusters", daemonsetName))
 | 
			
		||||
	err := wait.Poll(5*time.Second, 2*time.Minute, func() (bool, error) {
 | 
			
		||||
		for _, cluster := range clusters {
 | 
			
		||||
			_, err := cluster.Extensions().DaemonSets(nsName).Get(daemonsetName)
 | 
			
		||||
			if err != nil && errors.IsNotFound(err) {
 | 
			
		||||
				return false, nil
 | 
			
		||||
			}
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return false, err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true, nil
 | 
			
		||||
	})
 | 
			
		||||
	framework.ExpectNoError(err, "Not all daemonsets created")
 | 
			
		||||
 | 
			
		||||
	By(fmt.Sprintf("Deleting daemonset %s", daemonsetName))
 | 
			
		||||
	deleteDaemonSetOrFail(clientset, nsName, daemonsetName, orphanDependents)
 | 
			
		||||
 | 
			
		||||
	By(fmt.Sprintf("Verifying daemonsets %s in underlying clusters", daemonsetName))
 | 
			
		||||
	errMessages := []string{}
 | 
			
		||||
	// daemon set should be present in underlying clusters unless orphanDependents is false.
 | 
			
		||||
	shouldExist := orphanDependents == nil || *orphanDependents == true
 | 
			
		||||
	for clusterName, clusterClientset := range clusters {
 | 
			
		||||
		_, err := clusterClientset.Extensions().DaemonSets(nsName).Get(daemonsetName)
 | 
			
		||||
		if shouldExist && errors.IsNotFound(err) {
 | 
			
		||||
			errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for daemonset %s in cluster %s, expected daemonset to exist", daemonsetName, clusterName))
 | 
			
		||||
		} else if !shouldExist && !errors.IsNotFound(err) {
 | 
			
		||||
			errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for daemonset %s in cluster %s, got error: %v", daemonsetName, clusterName, err))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(errMessages) != 0 {
 | 
			
		||||
		framework.Failf("%s", strings.Join(errMessages, "; "))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func createDaemonSetOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.DaemonSet {
 | 
			
		||||
	if clientset == nil || len(namespace) == 0 {
 | 
			
		||||
@@ -108,6 +186,24 @@ func createDaemonSetOrFail(clientset *fedclientset.Clientset, namespace string)
 | 
			
		||||
	return daemonset
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func deleteDaemonSetOrFail(clientset *fedclientset.Clientset, nsName string, daemonsetName string, orphanDependents *bool) {
 | 
			
		||||
	By(fmt.Sprintf("Deleting daemonset %q in namespace %q", daemonsetName, nsName))
 | 
			
		||||
	err := clientset.Extensions().DaemonSets(nsName).Delete(daemonsetName, &v1.DeleteOptions{OrphanDependents: orphanDependents})
 | 
			
		||||
	framework.ExpectNoError(err, "Error deleting daemonset %q in namespace %q", daemonsetName, nsName)
 | 
			
		||||
 | 
			
		||||
	// Wait for the daemonset to be deleted.
 | 
			
		||||
	err = wait.Poll(5*time.Second, wait.ForeverTestTimeout, func() (bool, error) {
 | 
			
		||||
		_, err := clientset.Extensions().DaemonSets(nsName).Get(daemonsetName)
 | 
			
		||||
		if err != nil && errors.IsNotFound(err) {
 | 
			
		||||
			return true, nil
 | 
			
		||||
		}
 | 
			
		||||
		return false, err
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		framework.Failf("Error in deleting daemonset %s: %v", daemonsetName, err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func updateDaemonSetOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.DaemonSet {
 | 
			
		||||
	if clientset == nil || len(namespace) == 0 {
 | 
			
		||||
		Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateDaemonSetOrFail: clientset: %v, namespace: %v", clientset, namespace))
 | 
			
		||||
 
 | 
			
		||||
@@ -19,9 +19,10 @@ package e2e
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
 | 
			
		||||
	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
 | 
			
		||||
	fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/unversioned"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/v1"
 | 
			
		||||
@@ -49,14 +50,9 @@ var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", fu
 | 
			
		||||
		AfterEach(func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
 | 
			
		||||
			// Delete registered deployments.
 | 
			
		||||
			// Delete all deployments.
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			deploymentList, err := f.FederationClientset_1_5.Extensions().Deployments(nsName).List(v1.ListOptions{})
 | 
			
		||||
			Expect(err).NotTo(HaveOccurred())
 | 
			
		||||
			for _, deployment := range deploymentList.Items {
 | 
			
		||||
				err := f.FederationClientset_1_5.Extensions().Deployments(nsName).Delete(deployment.Name, &v1.DeleteOptions{})
 | 
			
		||||
				Expect(err).NotTo(HaveOccurred())
 | 
			
		||||
			}
 | 
			
		||||
			deleteAllDeploymentsOrFail(f.FederationClientset_1_5, nsName)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should be created and deleted successfully", func() {
 | 
			
		||||
@@ -89,6 +85,8 @@ var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", fu
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		AfterEach(func() {
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			deleteAllDeploymentsOrFail(f.FederationClientset_1_5, nsName)
 | 
			
		||||
			unregisterClusters(clusters, f)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
@@ -111,25 +109,101 @@ var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", fu
 | 
			
		||||
			waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters)
 | 
			
		||||
			By(fmt.Sprintf("Successfuly updated and synced deployment %q/%q to clusters", nsName, dep.Name))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should be deleted from underlying clusters when OrphanDependents is false", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			orphanDependents := false
 | 
			
		||||
			verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that deployments were deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			orphanDependents := true
 | 
			
		||||
			verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that deployments were not deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, nil, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that deployments were not deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
	})
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
func waitForDeploymentOrFail(c *federation_release_1_5.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) {
 | 
			
		||||
	err := waitForDeployment(c, namespace, replicaSetName, clusters)
 | 
			
		||||
	framework.ExpectNoError(err, "Failed to verify deployment %q/%q, err: %v", namespace, replicaSetName, err)
 | 
			
		||||
// deleteAllDeploymentsOrFail deletes all deployments in the given namespace name.
 | 
			
		||||
func deleteAllDeploymentsOrFail(clientset *fedclientset.Clientset, nsName string) {
 | 
			
		||||
	deploymentList, err := clientset.Extensions().Deployments(nsName).List(v1.ListOptions{})
 | 
			
		||||
	Expect(err).NotTo(HaveOccurred())
 | 
			
		||||
	orphanDependents := false
 | 
			
		||||
	for _, deployment := range deploymentList.Items {
 | 
			
		||||
		deleteDeploymentOrFail(clientset, nsName, deployment.Name, &orphanDependents)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func waitForDeployment(c *federation_release_1_5.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) error {
 | 
			
		||||
// verifyCascadingDeletionForDeployment verifies that deployments are deleted
 | 
			
		||||
// from underlying clusters when orphan dependents is false and they are not
 | 
			
		||||
// deleted when orphan dependents is true.
 | 
			
		||||
func verifyCascadingDeletionForDeployment(clientset *fedclientset.Clientset, clusters map[string]*cluster, orphanDependents *bool, nsName string) {
 | 
			
		||||
	deployment := createDeploymentOrFail(clientset, nsName)
 | 
			
		||||
	deploymentName := deployment.Name
 | 
			
		||||
	// Check subclusters if the deployment was created there.
 | 
			
		||||
	By(fmt.Sprintf("Waiting for deployment %s to be created in all underlying clusters", deploymentName))
 | 
			
		||||
	err := wait.Poll(5*time.Second, 2*time.Minute, func() (bool, error) {
 | 
			
		||||
		for _, cluster := range clusters {
 | 
			
		||||
			_, err := cluster.Extensions().Deployments(nsName).Get(deploymentName)
 | 
			
		||||
			if err != nil && errors.IsNotFound(err) {
 | 
			
		||||
				return false, nil
 | 
			
		||||
			}
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return false, err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true, nil
 | 
			
		||||
	})
 | 
			
		||||
	framework.ExpectNoError(err, "Not all deployments created")
 | 
			
		||||
 | 
			
		||||
	By(fmt.Sprintf("Deleting deployment %s", deploymentName))
 | 
			
		||||
	deleteDeploymentOrFail(clientset, nsName, deploymentName, orphanDependents)
 | 
			
		||||
 | 
			
		||||
	By(fmt.Sprintf("Verifying deployments %s in underlying clusters", deploymentName))
 | 
			
		||||
	errMessages := []string{}
 | 
			
		||||
	// deployment should be present in underlying clusters unless orphanDependents is false.
 | 
			
		||||
	shouldExist := orphanDependents == nil || *orphanDependents == true
 | 
			
		||||
	for clusterName, clusterClientset := range clusters {
 | 
			
		||||
		_, err := clusterClientset.Extensions().Deployments(nsName).Get(deploymentName)
 | 
			
		||||
		if shouldExist && errors.IsNotFound(err) {
 | 
			
		||||
			errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for deployment %s in cluster %s, expected deployment to exist", deploymentName, clusterName))
 | 
			
		||||
		} else if shouldExist && !errors.IsNotFound(err) {
 | 
			
		||||
			errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for deployment %s in cluster %s, got error: %v", deploymentName, clusterName, err))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(errMessages) != 0 {
 | 
			
		||||
		framework.Failf("%s", strings.Join(errMessages, "; "))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func waitForDeploymentOrFail(c *fedclientset.Clientset, namespace string, deploymentName string, clusters map[string]*cluster) {
 | 
			
		||||
	err := waitForDeployment(c, namespace, deploymentName, clusters)
 | 
			
		||||
	framework.ExpectNoError(err, "Failed to verify deployment %q/%q, err: %v", namespace, deploymentName, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func waitForDeployment(c *fedclientset.Clientset, namespace string, deploymentName string, clusters map[string]*cluster) error {
 | 
			
		||||
	err := wait.Poll(10*time.Second, FederatedDeploymentTimeout, func() (bool, error) {
 | 
			
		||||
		fdep, err := c.Deployments(namespace).Get(replicaSetName)
 | 
			
		||||
		fdep, err := c.Deployments(namespace).Get(deploymentName)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return false, err
 | 
			
		||||
		}
 | 
			
		||||
		specReplicas, statusReplicas := int32(0), int32(0)
 | 
			
		||||
		for _, cluster := range clusters {
 | 
			
		||||
			dep, err := cluster.Deployments(namespace).Get(replicaSetName)
 | 
			
		||||
			dep, err := cluster.Deployments(namespace).Get(deploymentName)
 | 
			
		||||
			if err != nil && !errors.IsNotFound(err) {
 | 
			
		||||
				By(fmt.Sprintf("Failed getting deployment: %q/%q/%q, err: %v", cluster.name, namespace, replicaSetName, err))
 | 
			
		||||
				By(fmt.Sprintf("Failed getting deployment: %q/%q/%q, err: %v", cluster.name, namespace, deploymentName, err))
 | 
			
		||||
				return false, err
 | 
			
		||||
			}
 | 
			
		||||
			if err == nil {
 | 
			
		||||
@@ -158,7 +232,7 @@ func equivalentDeployment(fedDeployment, localDeployment *v1beta1.Deployment) bo
 | 
			
		||||
		reflect.DeepEqual(fedDeployment.Spec, localDeploymentSpec)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func createDeploymentOrFail(clientset *federation_release_1_5.Clientset, namespace string) *v1beta1.Deployment {
 | 
			
		||||
func createDeploymentOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.Deployment {
 | 
			
		||||
	if clientset == nil || len(namespace) == 0 {
 | 
			
		||||
		Fail(fmt.Sprintf("Internal error: invalid parameters passed to createDeploymentOrFail: clientset: %v, namespace: %v", clientset, namespace))
 | 
			
		||||
	}
 | 
			
		||||
@@ -172,7 +246,7 @@ func createDeploymentOrFail(clientset *federation_release_1_5.Clientset, namespa
 | 
			
		||||
	return deployment
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func updateDeploymentOrFail(clientset *federation_release_1_5.Clientset, namespace string) *v1beta1.Deployment {
 | 
			
		||||
func updateDeploymentOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.Deployment {
 | 
			
		||||
	if clientset == nil || len(namespace) == 0 {
 | 
			
		||||
		Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateDeploymentOrFail: clientset: %v, namespace: %v", clientset, namespace))
 | 
			
		||||
	}
 | 
			
		||||
@@ -187,6 +261,24 @@ func updateDeploymentOrFail(clientset *federation_release_1_5.Clientset, namespa
 | 
			
		||||
	return newRs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func deleteDeploymentOrFail(clientset *fedclientset.Clientset, nsName string, deploymentName string, orphanDependents *bool) {
 | 
			
		||||
	By(fmt.Sprintf("Deleting deployment %q in namespace %q", deploymentName, nsName))
 | 
			
		||||
	err := clientset.Extensions().Deployments(nsName).Delete(deploymentName, &v1.DeleteOptions{OrphanDependents: orphanDependents})
 | 
			
		||||
	framework.ExpectNoError(err, "Error deleting deployment %q in namespace %q", deploymentName, nsName)
 | 
			
		||||
 | 
			
		||||
	// Wait for the deployment to be deleted.
 | 
			
		||||
	err = wait.Poll(5*time.Second, wait.ForeverTestTimeout, func() (bool, error) {
 | 
			
		||||
		_, err := clientset.Extensions().Deployments(nsName).Get(deploymentName)
 | 
			
		||||
		if err != nil && errors.IsNotFound(err) {
 | 
			
		||||
			return true, nil
 | 
			
		||||
		}
 | 
			
		||||
		return false, err
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		framework.Failf("Error in deleting deployment %s: %v", deploymentName, err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newDeploymentForFed(namespace string, name string, replicas int32) *v1beta1.Deployment {
 | 
			
		||||
	return &v1beta1.Deployment{
 | 
			
		||||
		ObjectMeta: v1.ObjectMeta{
 | 
			
		||||
 
 | 
			
		||||
@@ -19,9 +19,10 @@ package e2e
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
 | 
			
		||||
	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
 | 
			
		||||
	fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/unversioned"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/v1"
 | 
			
		||||
@@ -49,14 +50,9 @@ var _ = framework.KubeDescribe("Federation replicasets [Feature:Federation]", fu
 | 
			
		||||
		AfterEach(func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
 | 
			
		||||
			// Delete registered replicasets.
 | 
			
		||||
			// Delete all replicasets.
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			replicasetList, err := f.FederationClientset_1_5.Extensions().ReplicaSets(nsName).List(v1.ListOptions{})
 | 
			
		||||
			Expect(err).NotTo(HaveOccurred())
 | 
			
		||||
			for _, replicaset := range replicasetList.Items {
 | 
			
		||||
				err := f.FederationClientset_1_5.Extensions().ReplicaSets(nsName).Delete(replicaset.Name, &v1.DeleteOptions{})
 | 
			
		||||
				Expect(err).NotTo(HaveOccurred())
 | 
			
		||||
			}
 | 
			
		||||
			deleteAllReplicaSetsOrFail(f.FederationClientset_1_5, nsName)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should be created and deleted successfully", func() {
 | 
			
		||||
@@ -89,6 +85,9 @@ var _ = framework.KubeDescribe("Federation replicasets [Feature:Federation]", fu
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		AfterEach(func() {
 | 
			
		||||
			// Delete all replicasets.
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			deleteAllReplicaSetsOrFail(f.FederationClientset_1_5, nsName)
 | 
			
		||||
			unregisterClusters(clusters, f)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
@@ -111,15 +110,88 @@ var _ = framework.KubeDescribe("Federation replicasets [Feature:Federation]", fu
 | 
			
		||||
			waitForReplicaSetOrFail(f.FederationClientset_1_5, nsName, rs.Name, clusters)
 | 
			
		||||
			By(fmt.Sprintf("Successfuly updated and synced replicaset %q/%q to clusters", nsName, rs.Name))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should be deleted from underlying clusters when OrphanDependents is false", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			orphanDependents := false
 | 
			
		||||
			verifyCascadingDeletionForReplicaSet(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that replica sets were deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			orphanDependents := true
 | 
			
		||||
			verifyCascadingDeletionForReplicaSet(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that replica sets were not deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
 | 
			
		||||
			framework.SkipUnlessFederated(f.ClientSet)
 | 
			
		||||
			nsName := f.FederationNamespace.Name
 | 
			
		||||
			verifyCascadingDeletionForReplicaSet(f.FederationClientset_1_5, clusters, nil, nsName)
 | 
			
		||||
			By(fmt.Sprintf("Verified that replica sets were not deleted from underlying clusters"))
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
func waitForReplicaSetOrFail(c *federation_release_1_5.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) {
 | 
			
		||||
// deleteAllReplicaSetsOrFail deletes all replicasets in the given namespace name.
 | 
			
		||||
func deleteAllReplicaSetsOrFail(clientset *fedclientset.Clientset, nsName string) {
 | 
			
		||||
	replicasetList, err := clientset.Extensions().ReplicaSets(nsName).List(v1.ListOptions{})
 | 
			
		||||
	Expect(err).NotTo(HaveOccurred())
 | 
			
		||||
	orphanDependents := false
 | 
			
		||||
	for _, replicaset := range replicasetList.Items {
 | 
			
		||||
		deleteReplicaSetOrFail(clientset, nsName, replicaset.Name, &orphanDependents)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// verifyCascadingDeletionForReplicaSet verifies that replicaSets are deleted
 | 
			
		||||
// from underlying clusters when orphan dependents is false and they are not
 | 
			
		||||
// deleted when orphan dependents is true.
 | 
			
		||||
func verifyCascadingDeletionForReplicaSet(clientset *fedclientset.Clientset, clusters map[string]*cluster, orphanDependents *bool, nsName string) {
 | 
			
		||||
	replicaSet := createReplicaSetOrFail(clientset, nsName)
 | 
			
		||||
	replicaSetName := replicaSet.Name
 | 
			
		||||
	// Check subclusters if the replicaSet was created there.
 | 
			
		||||
	By(fmt.Sprintf("Waiting for replica sets %s to be created in all underlying clusters", replicaSetName))
 | 
			
		||||
	err := wait.Poll(5*time.Second, 2*time.Minute, func() (bool, error) {
 | 
			
		||||
		for _, cluster := range clusters {
 | 
			
		||||
			_, err := cluster.Extensions().ReplicaSets(nsName).Get(replicaSetName)
 | 
			
		||||
			if err != nil && errors.IsNotFound(err) {
 | 
			
		||||
				return false, nil
 | 
			
		||||
			}
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return false, err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true, nil
 | 
			
		||||
	})
 | 
			
		||||
	framework.ExpectNoError(err, "Not all replica sets created")
 | 
			
		||||
 | 
			
		||||
	By(fmt.Sprintf("Deleting replica set %s", replicaSetName))
 | 
			
		||||
	deleteReplicaSetOrFail(clientset, nsName, replicaSetName, orphanDependents)
 | 
			
		||||
 | 
			
		||||
	By(fmt.Sprintf("Verifying replica sets %s in underlying clusters", replicaSetName))
 | 
			
		||||
	errMessages := []string{}
 | 
			
		||||
	for clusterName, clusterClientset := range clusters {
 | 
			
		||||
		_, err := clusterClientset.Extensions().ReplicaSets(nsName).Get(replicaSetName)
 | 
			
		||||
		if (orphanDependents == nil || *orphanDependents == true) && errors.IsNotFound(err) {
 | 
			
		||||
			errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for replica set %s in cluster %s, expected replica set to exist", replicaSetName, clusterName))
 | 
			
		||||
		} else if (orphanDependents != nil && *orphanDependents == false) && (err == nil || !errors.IsNotFound(err)) {
 | 
			
		||||
			errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for replica set %s in cluster %s, got error: %v", replicaSetName, clusterName, err))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(errMessages) != 0 {
 | 
			
		||||
		framework.Failf("%s", strings.Join(errMessages, "; "))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func waitForReplicaSetOrFail(c *fedclientset.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) {
 | 
			
		||||
	err := waitForReplicaSet(c, namespace, replicaSetName, clusters)
 | 
			
		||||
	framework.ExpectNoError(err, "Failed to verify replica set %q/%q, err: %v", namespace, replicaSetName, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func waitForReplicaSet(c *federation_release_1_5.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) error {
 | 
			
		||||
func waitForReplicaSet(c *fedclientset.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) error {
 | 
			
		||||
	err := wait.Poll(10*time.Second, FederatedReplicaSetTimeout, func() (bool, error) {
 | 
			
		||||
		frs, err := c.ReplicaSets(namespace).Get(replicaSetName)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
@@ -158,7 +230,7 @@ func equivalentReplicaSet(fedReplicaSet, localReplicaSet *v1beta1.ReplicaSet) bo
 | 
			
		||||
		reflect.DeepEqual(fedReplicaSet.Spec, localReplicaSetSpec)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func createReplicaSetOrFail(clientset *federation_release_1_5.Clientset, namespace string) *v1beta1.ReplicaSet {
 | 
			
		||||
func createReplicaSetOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.ReplicaSet {
 | 
			
		||||
	if clientset == nil || len(namespace) == 0 {
 | 
			
		||||
		Fail(fmt.Sprintf("Internal error: invalid parameters passed to createReplicaSetOrFail: clientset: %v, namespace: %v", clientset, namespace))
 | 
			
		||||
	}
 | 
			
		||||
@@ -172,7 +244,25 @@ func createReplicaSetOrFail(clientset *federation_release_1_5.Clientset, namespa
 | 
			
		||||
	return replicaset
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func updateReplicaSetOrFail(clientset *federation_release_1_5.Clientset, namespace string) *v1beta1.ReplicaSet {
 | 
			
		||||
func deleteReplicaSetOrFail(clientset *fedclientset.Clientset, nsName string, replicaSetName string, orphanDependents *bool) {
 | 
			
		||||
	By(fmt.Sprintf("Deleting replica set %q in namespace %q", replicaSetName, nsName))
 | 
			
		||||
	err := clientset.Extensions().ReplicaSets(nsName).Delete(replicaSetName, &v1.DeleteOptions{OrphanDependents: orphanDependents})
 | 
			
		||||
	framework.ExpectNoError(err, "Error deleting replica set %q in namespace %q", replicaSetName, nsName)
 | 
			
		||||
 | 
			
		||||
	// Wait for the replicaSet to be deleted.
 | 
			
		||||
	err = wait.Poll(5*time.Second, wait.ForeverTestTimeout, func() (bool, error) {
 | 
			
		||||
		_, err := clientset.Extensions().ReplicaSets(nsName).Get(replicaSetName)
 | 
			
		||||
		if err != nil && errors.IsNotFound(err) {
 | 
			
		||||
			return true, nil
 | 
			
		||||
		}
 | 
			
		||||
		return false, err
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		framework.Failf("Error in deleting replica set %s: %v", replicaSetName, err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func updateReplicaSetOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.ReplicaSet {
 | 
			
		||||
	if clientset == nil || len(namespace) == 0 {
 | 
			
		||||
		Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateReplicaSetOrFail: clientset: %v, namespace: %v", clientset, namespace))
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user