mirror of https://github.com/k3s-io/k3s
Updating federation e2e tests to verify cascading deletion
parent
d51e27fe96
commit
14246a9494
|
@ -22,6 +22,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
|
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() {
|
Describe("Federated Ingresses", func() {
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
// Delete registered ingresses.
|
// Delete all ingresses.
|
||||||
ingressList, err := f.FederationClientset_1_5.Extensions().Ingresses(nsName).List(v1.ListOptions{})
|
deleteAllIngressesOrFail(f.FederationClientset_1_5, nsName)
|
||||||
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())
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be created and deleted successfully", func() {
|
It("should be created and deleted successfully", func() {
|
||||||
|
@ -97,26 +93,43 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
// Delete all ingresses.
|
||||||
|
nsName := f.FederationNamespace.Name
|
||||||
|
deleteAllIngressesOrFail(f.FederationClientset_1_5, nsName)
|
||||||
unregisterClusters(clusters, f)
|
unregisterClusters(clusters, f)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should create and update matching ingresses in underlying clusters", func() {
|
It("should create and update matching ingresses in underlying clusters", func() {
|
||||||
ingress := createIngressOrFail(f.FederationClientset_1_5, ns)
|
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
|
// wait for ingress shards being created
|
||||||
waitForIngressShardsOrFail(ns, ingress, clusters)
|
waitForIngressShardsOrFail(ns, ingress, clusters)
|
||||||
ingress = updateIngressOrFail(f.FederationClientset_1_5, ns)
|
ingress = updateIngressOrFail(f.FederationClientset_1_5, ns)
|
||||||
waitForIngressShardsUpdatedOrFail(ns, ingress, clusters)
|
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 _ = Describe("Ingress connectivity and DNS", func() {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -147,7 +160,7 @@ var _ = framework.KubeDescribe("Federated ingresses [Feature:Federation]", func(
|
||||||
By("No service to delete. Service is nil")
|
By("No service to delete. Service is nil")
|
||||||
}
|
}
|
||||||
if jig.ing != 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 {
|
for clusterName, cluster := range clusters {
|
||||||
deleteClusterIngressOrFail(clusterName, cluster.Clientset, ns, jig.ing.Name)
|
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.
|
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)
|
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.
|
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.
|
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 {
|
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))
|
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)
|
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
|
// 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() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
framework.SkipUnlessFederated(f.ClientSet)
|
||||||
deleteAllTestNamespaces(false,
|
deleteAllTestNamespaces(nil,
|
||||||
f.FederationClientset_1_5.Core().Namespaces().List,
|
f.FederationClientset_1_5.Core().Namespaces().List,
|
||||||
f.FederationClientset_1_5.Core().Namespaces().Delete)
|
f.FederationClientset_1_5.Core().Namespaces().Delete)
|
||||||
for _, cluster := range clusters {
|
for _, cluster := range clusters {
|
||||||
deleteAllTestNamespaces(false,
|
deleteAllTestNamespaces(nil,
|
||||||
cluster.Core().Namespaces().List,
|
cluster.Core().Namespaces().List,
|
||||||
cluster.Core().Namespaces().Delete)
|
cluster.Core().Namespaces().Delete)
|
||||||
}
|
}
|
||||||
|
@ -76,22 +76,30 @@ var _ = framework.KubeDescribe("Federation namespace [Feature:Federation]", func
|
||||||
nsName := createNamespace(f.FederationClientset_1_5.Core().Namespaces())
|
nsName := createNamespace(f.FederationClientset_1_5.Core().Namespaces())
|
||||||
|
|
||||||
By(fmt.Sprintf("Deleting namespace %s", nsName))
|
By(fmt.Sprintf("Deleting namespace %s", nsName))
|
||||||
deleteAllTestNamespaces(false,
|
deleteAllTestNamespaces(nil,
|
||||||
f.FederationClientset_1_5.Core().Namespaces().List,
|
f.FederationClientset_1_5.Core().Namespaces().List,
|
||||||
f.FederationClientset_1_5.Core().Namespaces().Delete)
|
f.FederationClientset_1_5.Core().Namespaces().Delete)
|
||||||
By(fmt.Sprintf("Verified that deletion succeeded"))
|
By(fmt.Sprintf("Verified that deletion succeeded"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
framework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
orphanDependents := false
|
||||||
verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, false)
|
verifyNsCascadingDeletion(f.FederationClientset_1_5.Core().Namespaces(), clusters, &orphanDependents)
|
||||||
By(fmt.Sprintf("Verified that namespaces were deleted from underlying clusters"))
|
By(fmt.Sprintf("Verified that namespaces were deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
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"))
|
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))
|
By(fmt.Sprintf("Deleting namespace %s", nsName))
|
||||||
deleteAllTestNamespaces(false,
|
deleteAllTestNamespaces(nil,
|
||||||
f.FederationClientset_1_5.Core().Namespaces().List,
|
f.FederationClientset_1_5.Core().Namespaces().List,
|
||||||
f.FederationClientset_1_5.Core().Namespaces().Delete)
|
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
|
// verifyNsCascadingDeletion verifies that namespaces are deleted from
|
||||||
// and they are not deleted when orphan dependents is true.
|
// underlying clusters when orphan dependents is false and they are not
|
||||||
func verifyNsCascadingDeletion(nsClient clientset.NamespaceInterface,
|
// deleted when orphan dependents is true.
|
||||||
clusters map[string]*cluster, orphanDependents bool) {
|
func verifyNsCascadingDeletion(nsClient clientset.NamespaceInterface, clusters map[string]*cluster, orphanDependents *bool) {
|
||||||
nsName := createNamespace(nsClient)
|
nsName := createNamespace(nsClient)
|
||||||
// Check subclusters if the namespace was created there.
|
// Check subclusters if the namespace was created there.
|
||||||
By(fmt.Sprintf("Waiting for namespace %s to be created in all underlying clusters", nsName))
|
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))
|
By(fmt.Sprintf("Verifying namespaces %s in underlying clusters", nsName))
|
||||||
errMessages := []string{}
|
errMessages := []string{}
|
||||||
|
// namespace should be present in underlying clusters unless orphanDependents is false.
|
||||||
|
shouldExist := orphanDependents == nil || *orphanDependents == true
|
||||||
for clusterName, clusterClientset := range clusters {
|
for clusterName, clusterClientset := range clusters {
|
||||||
_, err := clusterClientset.Core().Namespaces().Get(nsName)
|
_, 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))
|
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))
|
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
|
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{})
|
list, err := lister(api_v1.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Failf("Failed to get all namespaes: %v", err)
|
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 {
|
for _, namespace := range list.Items {
|
||||||
if strings.HasPrefix(namespace.Name, namespacePrefix) {
|
if strings.HasPrefix(namespace.Name, namespacePrefix) {
|
||||||
By(fmt.Sprintf("Deleting ns: %s, found by listing", namespace.Name))
|
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 {
|
if err != nil {
|
||||||
framework.Failf("Failed to set %s for deletion: %v", namespace.Name, err)
|
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() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
framework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
// Delete all secrets.
|
||||||
|
nsName := f.FederationNamespace.Name
|
||||||
|
deleteAllSecretsOrFail(f.FederationClientset_1_5, nsName)
|
||||||
unregisterClusters(clusters, f)
|
unregisterClusters(clusters, f)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be created and deleted successfully", func() {
|
It("should be created and deleted successfully", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
framework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
secret := createSecretOrFail(f.FederationClientset_1_5, nsName)
|
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
|
// wait for secret shards being created
|
||||||
waitForSecretShardsOrFail(nsName, secret, clusters)
|
waitForSecretShardsOrFail(nsName, secret, clusters)
|
||||||
secret = updateSecretOrFail(f.FederationClientset_1_5, nsName, secret.Name)
|
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() {
|
It("should be deleted from underlying clusters when OrphanDependents is false", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
framework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
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"))
|
By(fmt.Sprintf("Verified that secrets were deleted from underlying clusters"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
framework.SkipUnlessFederated(f.ClientSet)
|
||||||
nsName := f.FederationNamespace.Name
|
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"))
|
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
|
// deleteAllSecretsOrFail deletes all secrets in the given namespace name.
|
||||||
// and they are not deleted when orphan dependents is true.
|
func deleteAllSecretsOrFail(clientset *fedclientset.Clientset, nsName string) {
|
||||||
func verifyCascadingDeletion(clientset *fedclientset.Clientset,
|
SecretList, err := clientset.Core().Secrets(nsName).List(v1.ListOptions{})
|
||||||
clusters map[string]*cluster, orphanDependents bool, nsName string) {
|
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)
|
secret := createSecretOrFail(clientset, nsName)
|
||||||
secretName := secret.Name
|
secretName := secret.Name
|
||||||
// Check subclusters if the secret was created there.
|
// Check subclusters if the secret was created there.
|
||||||
|
@ -104,7 +124,6 @@ func verifyCascadingDeletion(clientset *fedclientset.Clientset,
|
||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
})
|
})
|
||||||
|
@ -115,11 +134,13 @@ func verifyCascadingDeletion(clientset *fedclientset.Clientset,
|
||||||
|
|
||||||
By(fmt.Sprintf("Verifying secrets %s in underlying clusters", secretName))
|
By(fmt.Sprintf("Verifying secrets %s in underlying clusters", secretName))
|
||||||
errMessages := []string{}
|
errMessages := []string{}
|
||||||
|
// secret should be present in underlying clusters unless orphanDependents is false.
|
||||||
|
shouldExist := orphanDependents == nil || *orphanDependents == true
|
||||||
for clusterName, clusterClientset := range clusters {
|
for clusterName, clusterClientset := range clusters {
|
||||||
_, err := clusterClientset.Core().Secrets(nsName).Get(secretName)
|
_, 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))
|
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))
|
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
|
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))
|
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)
|
framework.ExpectNoError(err, "Error deleting secret %q in namespace %q", secretName, nsName)
|
||||||
|
|
||||||
// Wait for the secret to be deleted.
|
// Wait for the secret to be deleted.
|
||||||
|
|
|
@ -18,6 +18,7 @@ package e2e
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
|
@ -39,7 +40,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create/delete daemonset api objects
|
// 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
|
var clusters map[string]*cluster // All clusters, keyed by cluster name
|
||||||
|
|
||||||
f := framework.NewDefaultFederatedFramework("federated-daemonset")
|
f := framework.NewDefaultFederatedFramework("federated-daemonset")
|
||||||
|
@ -54,6 +55,9 @@ var _ = framework.KubeDescribe("Federation daemonsets [Feature:Federation12]", f
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
framework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
// Delete all daemonsets.
|
||||||
|
nsName := f.FederationNamespace.Name
|
||||||
|
deleteAllDaemonSetsOrFail(f.FederationClientset_1_5, nsName)
|
||||||
unregisterClusters(clusters, f)
|
unregisterClusters(clusters, f)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -71,9 +75,83 @@ var _ = framework.KubeDescribe("Federation daemonsets [Feature:Federation12]", f
|
||||||
daemonset = updateDaemonSetOrFail(f.FederationClientset_1_5, nsName)
|
daemonset = updateDaemonSetOrFail(f.FederationClientset_1_5, nsName)
|
||||||
waitForDaemonSetShardsUpdatedOrFail(nsName, daemonset, clusters)
|
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 {
|
func createDaemonSetOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.DaemonSet {
|
||||||
if clientset == nil || len(namespace) == 0 {
|
if clientset == nil || len(namespace) == 0 {
|
||||||
Fail(fmt.Sprintf("Internal error: invalid parameters passed to createDaemonSetOrFail: clientset: %v, namespace: %v", clientset, namespace))
|
Fail(fmt.Sprintf("Internal error: invalid parameters passed to createDaemonSetOrFail: clientset: %v, namespace: %v", clientset, namespace))
|
||||||
|
@ -108,6 +186,24 @@ func createDaemonSetOrFail(clientset *fedclientset.Clientset, namespace string)
|
||||||
return daemonset
|
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 {
|
func updateDaemonSetOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.DaemonSet {
|
||||||
if clientset == nil || len(namespace) == 0 {
|
if clientset == nil || len(namespace) == 0 {
|
||||||
Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateDaemonSetOrFail: clientset: %v, namespace: %v", clientset, namespace))
|
Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateDaemonSetOrFail: clientset: %v, namespace: %v", clientset, namespace))
|
||||||
|
|
|
@ -19,9 +19,10 @@ package e2e
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"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"
|
fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
@ -49,14 +50,9 @@ var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", fu
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
framework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
// Delete registered deployments.
|
// Delete all deployments.
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
deploymentList, err := f.FederationClientset_1_5.Extensions().Deployments(nsName).List(v1.ListOptions{})
|
deleteAllDeploymentsOrFail(f.FederationClientset_1_5, nsName)
|
||||||
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())
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be created and deleted successfully", func() {
|
It("should be created and deleted successfully", func() {
|
||||||
|
@ -89,6 +85,8 @@ var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", fu
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
nsName := f.FederationNamespace.Name
|
||||||
|
deleteAllDeploymentsOrFail(f.FederationClientset_1_5, nsName)
|
||||||
unregisterClusters(clusters, f)
|
unregisterClusters(clusters, f)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -111,25 +109,101 @@ var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", fu
|
||||||
waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters)
|
waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters)
|
||||||
By(fmt.Sprintf("Successfuly updated and synced deployment %q/%q to clusters", nsName, dep.Name))
|
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) {
|
// deleteAllDeploymentsOrFail deletes all deployments in the given namespace name.
|
||||||
err := waitForDeployment(c, namespace, replicaSetName, clusters)
|
func deleteAllDeploymentsOrFail(clientset *fedclientset.Clientset, nsName string) {
|
||||||
framework.ExpectNoError(err, "Failed to verify deployment %q/%q, err: %v", namespace, replicaSetName, err)
|
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) {
|
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 {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
specReplicas, statusReplicas := int32(0), int32(0)
|
specReplicas, statusReplicas := int32(0), int32(0)
|
||||||
for _, cluster := range clusters {
|
for _, cluster := range clusters {
|
||||||
dep, err := cluster.Deployments(namespace).Get(replicaSetName)
|
dep, err := cluster.Deployments(namespace).Get(deploymentName)
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
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
|
return false, err
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -158,7 +232,7 @@ func equivalentDeployment(fedDeployment, localDeployment *v1beta1.Deployment) bo
|
||||||
reflect.DeepEqual(fedDeployment.Spec, localDeploymentSpec)
|
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 {
|
if clientset == nil || len(namespace) == 0 {
|
||||||
Fail(fmt.Sprintf("Internal error: invalid parameters passed to createDeploymentOrFail: clientset: %v, namespace: %v", clientset, namespace))
|
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
|
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 {
|
if clientset == nil || len(namespace) == 0 {
|
||||||
Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateDeploymentOrFail: clientset: %v, namespace: %v", clientset, namespace))
|
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
|
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 {
|
func newDeploymentForFed(namespace string, name string, replicas int32) *v1beta1.Deployment {
|
||||||
return &v1beta1.Deployment{
|
return &v1beta1.Deployment{
|
||||||
ObjectMeta: v1.ObjectMeta{
|
ObjectMeta: v1.ObjectMeta{
|
||||||
|
|
|
@ -19,9 +19,10 @@ package e2e
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"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"
|
fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
|
@ -49,14 +50,9 @@ var _ = framework.KubeDescribe("Federation replicasets [Feature:Federation]", fu
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
framework.SkipUnlessFederated(f.ClientSet)
|
framework.SkipUnlessFederated(f.ClientSet)
|
||||||
|
|
||||||
// Delete registered replicasets.
|
// Delete all replicasets.
|
||||||
nsName := f.FederationNamespace.Name
|
nsName := f.FederationNamespace.Name
|
||||||
replicasetList, err := f.FederationClientset_1_5.Extensions().ReplicaSets(nsName).List(v1.ListOptions{})
|
deleteAllReplicaSetsOrFail(f.FederationClientset_1_5, nsName)
|
||||||
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())
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be created and deleted successfully", func() {
|
It("should be created and deleted successfully", func() {
|
||||||
|
@ -89,6 +85,9 @@ var _ = framework.KubeDescribe("Federation replicasets [Feature:Federation]", fu
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
// Delete all replicasets.
|
||||||
|
nsName := f.FederationNamespace.Name
|
||||||
|
deleteAllReplicaSetsOrFail(f.FederationClientset_1_5, nsName)
|
||||||
unregisterClusters(clusters, f)
|
unregisterClusters(clusters, f)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -111,15 +110,88 @@ var _ = framework.KubeDescribe("Federation replicasets [Feature:Federation]", fu
|
||||||
waitForReplicaSetOrFail(f.FederationClientset_1_5, nsName, rs.Name, clusters)
|
waitForReplicaSetOrFail(f.FederationClientset_1_5, nsName, rs.Name, clusters)
|
||||||
By(fmt.Sprintf("Successfuly updated and synced replicaset %q/%q to clusters", nsName, rs.Name))
|
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.
|
||||||
err := waitForReplicaSet(c, namespace, replicaSetName, clusters)
|
func deleteAllReplicaSetsOrFail(clientset *fedclientset.Clientset, nsName string) {
|
||||||
framework.ExpectNoError(err, "Failed to verify replicaset %q/%q, err: %v", namespace, replicaSetName, err)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitForReplicaSet(c *federation_release_1_5.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) error {
|
// 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 *fedclientset.Clientset, namespace string, replicaSetName string, clusters map[string]*cluster) error {
|
||||||
err := wait.Poll(10*time.Second, FederatedReplicaSetTimeout, func() (bool, error) {
|
err := wait.Poll(10*time.Second, FederatedReplicaSetTimeout, func() (bool, error) {
|
||||||
frs, err := c.ReplicaSets(namespace).Get(replicaSetName)
|
frs, err := c.ReplicaSets(namespace).Get(replicaSetName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -158,7 +230,7 @@ func equivalentReplicaSet(fedReplicaSet, localReplicaSet *v1beta1.ReplicaSet) bo
|
||||||
reflect.DeepEqual(fedReplicaSet.Spec, localReplicaSetSpec)
|
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 {
|
if clientset == nil || len(namespace) == 0 {
|
||||||
Fail(fmt.Sprintf("Internal error: invalid parameters passed to createReplicaSetOrFail: clientset: %v, namespace: %v", clientset, namespace))
|
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
|
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 {
|
if clientset == nil || len(namespace) == 0 {
|
||||||
Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateReplicaSetOrFail: clientset: %v, namespace: %v", clientset, namespace))
|
Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateReplicaSetOrFail: clientset: %v, namespace: %v", clientset, namespace))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue