|
4 | 4 | "bytes"
|
5 | 5 | "context"
|
6 | 6 | "encoding/json"
|
7 |
| - "errors" |
8 | 7 | "fmt"
|
9 | 8 | "path/filepath"
|
10 | 9 | "strconv"
|
@@ -32,7 +31,6 @@ import (
|
32 | 31 | k8sjson "k8s.io/apimachinery/pkg/runtime/serializer/json"
|
33 | 32 | "k8s.io/apimachinery/pkg/util/diff"
|
34 | 33 | "k8s.io/apimachinery/pkg/util/wait"
|
35 |
| - "k8s.io/apimachinery/pkg/watch" |
36 | 34 | "k8s.io/client-go/discovery"
|
37 | 35 | "k8s.io/client-go/util/retry"
|
38 | 36 | "sigs.k8s.io/controller-runtime/pkg/client"
|
@@ -2795,11 +2793,14 @@ var _ = Describe("Install Plan", func() {
|
2795 | 2793 | _, err := fetchCatalogSourceOnStatus(crc, mainCatalogSourceName, generatedNamespace.GetName(), catalogSourceRegistryPodSynced)
|
2796 | 2794 | require.NoError(GinkgoT(), err)
|
2797 | 2795 |
|
| 2796 | + By("Creating a Subscription") |
2798 | 2797 | subscriptionName := genName("sub-nginx-")
|
2799 |
| - subscriptionCleanup := createSubscriptionForCatalog(crc, generatedNamespace.GetName(), subscriptionName, mainCatalogSourceName, packageName, stableChannel, "", operatorsv1alpha1.ApprovalAutomatic) |
2800 |
| - defer subscriptionCleanup() |
| 2798 | + // Subscription is explitly deleted as part of the test to avoid CSV being recreated, |
| 2799 | + // so ignore cleanup function |
| 2800 | + _ = createSubscriptionForCatalog(crc, generatedNamespace.GetName(), subscriptionName, mainCatalogSourceName, packageName, stableChannel, "", operatorsv1alpha1.ApprovalAutomatic) |
2801 | 2801 |
|
2802 |
| - subscription, err := fetchSubscription(crc, generatedNamespace.GetName(), subscriptionName, subscriptionHasInstallPlanChecker) |
| 2802 | + By("Attempt to get Subscription") |
| 2803 | + subscription, err := fetchSubscription(crc, generatedNamespace.GetName(), subscriptionName, subscriptionHasInstallPlanChecker()) |
2803 | 2804 | require.NoError(GinkgoT(), err)
|
2804 | 2805 | require.NotNil(GinkgoT(), subscription)
|
2805 | 2806 |
|
@@ -2870,92 +2871,63 @@ var _ = Describe("Install Plan", func() {
|
2870 | 2871 | // Should have removed every matching step
|
2871 | 2872 | require.Equal(GinkgoT(), 0, len(expectedSteps), "Actual resource steps do not match expected: %#v", expectedSteps)
|
2872 | 2873 |
|
2873 |
| - // the test from here out verifies created RBAC is removed after CSV deletion |
2874 |
| - createdClusterRoles, err := c.KubernetesInterface().RbacV1().ClusterRoles().List(context.Background(), metav1.ListOptions{LabelSelector: fmt.Sprintf("%v=%v", ownerutil.OwnerKey, stableCSVName)}) |
2875 |
| - createdClusterRoleNames := map[string]struct{}{} |
2876 |
| - for _, role := range createdClusterRoles.Items { |
2877 |
| - createdClusterRoleNames[role.GetName()] = struct{}{} |
2878 |
| - GinkgoT().Logf("Monitoring cluster role %v", role.GetName()) |
2879 |
| - } |
2880 |
| - |
2881 |
| - createdClusterRoleBindings, err := c.KubernetesInterface().RbacV1().ClusterRoleBindings().List(context.Background(), metav1.ListOptions{LabelSelector: fmt.Sprintf("%v=%v", ownerutil.OwnerKey, stableCSVName)}) |
2882 |
| - createdClusterRoleBindingNames := map[string]struct{}{} |
2883 |
| - for _, binding := range createdClusterRoleBindings.Items { |
2884 |
| - createdClusterRoleBindingNames[binding.GetName()] = struct{}{} |
2885 |
| - GinkgoT().Logf("Monitoring cluster role binding %v", binding.GetName()) |
2886 |
| - } |
2887 |
| - |
2888 |
| - crWatcher, err := c.KubernetesInterface().RbacV1().ClusterRoles().Watch(context.Background(), metav1.ListOptions{LabelSelector: fmt.Sprintf("%v=%v", ownerutil.OwnerKey, stableCSVName)}) |
2889 |
| - require.NoError(GinkgoT(), err) |
2890 |
| - crbWatcher, err := c.KubernetesInterface().RbacV1().ClusterRoleBindings().Watch(context.Background(), metav1.ListOptions{LabelSelector: fmt.Sprintf("%v=%v", ownerutil.OwnerKey, stableCSVName)}) |
2891 |
| - require.NoError(GinkgoT(), err) |
2892 |
| - |
2893 |
| - done := make(chan struct{}) |
2894 |
| - errExit := make(chan error) |
2895 |
| - go func() { |
2896 |
| - defer GinkgoRecover() |
2897 |
| - for { |
2898 |
| - select { |
2899 |
| - case evt, ok := <-crWatcher.ResultChan(): |
2900 |
| - if !ok { |
2901 |
| - errExit <- errors.New("cr watch channel closed unexpectedly") |
2902 |
| - return |
2903 |
| - } |
2904 |
| - if evt.Type == watch.Deleted { |
2905 |
| - cr, ok := evt.Object.(*rbacv1.ClusterRole) |
2906 |
| - if !ok { |
2907 |
| - continue |
2908 |
| - } |
2909 |
| - delete(createdClusterRoleNames, cr.GetName()) |
2910 |
| - if len(createdClusterRoleNames) == 0 && len(createdClusterRoleBindingNames) == 0 { |
2911 |
| - done <- struct{}{} |
2912 |
| - return |
2913 |
| - } |
2914 |
| - } |
2915 |
| - case evt, ok := <-crbWatcher.ResultChan(): |
2916 |
| - if !ok { |
2917 |
| - errExit <- errors.New("crb watch channel closed unexpectedly") |
2918 |
| - return |
2919 |
| - } |
2920 |
| - if evt.Type == watch.Deleted { |
2921 |
| - crb, ok := evt.Object.(*rbacv1.ClusterRoleBinding) |
2922 |
| - if !ok { |
2923 |
| - continue |
2924 |
| - } |
2925 |
| - delete(createdClusterRoleBindingNames, crb.GetName()) |
2926 |
| - if len(createdClusterRoleNames) == 0 && len(createdClusterRoleBindingNames) == 0 { |
2927 |
| - done <- struct{}{} |
2928 |
| - return |
2929 |
| - } |
2930 |
| - } |
2931 |
| - case <-time.After(pollDuration): |
2932 |
| - done <- struct{}{} |
2933 |
| - return |
| 2874 | + By(fmt.Sprintf("Explicitly deleting subscription %s/%s", generatedNamespace.GetName(), subscriptionName)) |
| 2875 | + err = crc.OperatorsV1alpha1().Subscriptions(generatedNamespace.GetName()).Delete(context.Background(), subscriptionName, metav1.DeleteOptions{}) |
| 2876 | + By("Looking for no error OR IsNotFound error") |
| 2877 | + require.NoError(GinkgoT(), client.IgnoreNotFound(err)) |
| 2878 | + |
| 2879 | + By("Waiting for the Subscription to delete") |
| 2880 | + err = waitForSubscriptionToDelete(generatedNamespace.GetName(), subscriptionName, crc) |
| 2881 | + require.NoError(GinkgoT(), client.IgnoreNotFound(err)) |
| 2882 | + |
| 2883 | + By(fmt.Sprintf("Explicitly deleting csv %s/%s", generatedNamespace.GetName(), stableCSVName)) |
| 2884 | + err = crc.OperatorsV1alpha1().ClusterServiceVersions(generatedNamespace.GetName()).Delete(context.Background(), stableCSVName, metav1.DeleteOptions{}) |
| 2885 | + By("Looking for no error OR IsNotFound error") |
| 2886 | + require.NoError(GinkgoT(), client.IgnoreNotFound(err)) |
| 2887 | + By("Waiting for the CSV to delete") |
| 2888 | + err = waitForCsvToDelete(generatedNamespace.GetName(), stableCSVName, crc) |
| 2889 | + require.NoError(GinkgoT(), client.IgnoreNotFound(err)) |
| 2890 | + |
| 2891 | + nCrs := 0 |
| 2892 | + nCrbs := 0 |
| 2893 | + By("Waiting for CRBs and CRs and SAs to delete") |
| 2894 | + Eventually(func() bool { |
| 2895 | + |
| 2896 | + crbs, err := c.KubernetesInterface().RbacV1().ClusterRoleBindings().List(context.Background(), metav1.ListOptions{LabelSelector: fmt.Sprintf("%v=%v", ownerutil.OwnerKey, stableCSVName)}) |
| 2897 | + if err != nil { |
| 2898 | + GinkgoT().Logf("error getting crbs: %v", err) |
| 2899 | + return false |
| 2900 | + } |
| 2901 | + if n := len(crbs.Items); n != 0 { |
| 2902 | + if n != nCrbs { |
| 2903 | + GinkgoT().Logf("CRBs remaining: %v", n) |
| 2904 | + nCrbs = n |
2934 | 2905 | }
|
| 2906 | + return false |
2935 | 2907 | }
|
2936 |
| - }() |
2937 |
| - GinkgoT().Logf("Deleting CSV '%v' in namespace %v", stableCSVName, generatedNamespace.GetName()) |
2938 |
| - require.NoError(GinkgoT(), crc.OperatorsV1alpha1().ClusterServiceVersions(generatedNamespace.GetName()).DeleteCollection(context.Background(), metav1.DeleteOptions{}, metav1.ListOptions{})) |
2939 |
| - select { |
2940 |
| - case <-done: |
2941 |
| - break |
2942 |
| - case err := <-errExit: |
2943 |
| - GinkgoT().Fatal(err) |
2944 |
| - } |
2945 | 2908 |
|
2946 |
| - require.Emptyf(GinkgoT(), createdClusterRoleNames, "unexpected cluster role remain: %v", createdClusterRoleNames) |
2947 |
| - require.Emptyf(GinkgoT(), createdClusterRoleBindingNames, "unexpected cluster role binding remain: %v", createdClusterRoleBindingNames) |
2948 |
| - |
2949 |
| - Eventually(func() error { |
2950 |
| - _, err := c.GetServiceAccount(generatedNamespace.GetName(), serviceAccountName) |
2951 |
| - if err == nil { |
2952 |
| - return fmt.Errorf("The %v/%v ServiceAccount should have been deleted", generatedNamespace.GetName(), serviceAccountName) |
| 2909 | + crs, err := c.KubernetesInterface().RbacV1().ClusterRoles().List(context.Background(), metav1.ListOptions{LabelSelector: fmt.Sprintf("%v=%v", ownerutil.OwnerKey, stableCSVName)}) |
| 2910 | + if err != nil { |
| 2911 | + GinkgoT().Logf("error getting crs: %v", err) |
| 2912 | + return false |
2953 | 2913 | }
|
2954 |
| - if !apierrors.IsNotFound(err) { |
2955 |
| - return err |
| 2914 | + if n := len(crs.Items); n != 0 { |
| 2915 | + if n != nCrs { |
| 2916 | + GinkgoT().Logf("CRs remaining: %v", n) |
| 2917 | + nCrs = n |
| 2918 | + } |
| 2919 | + return false |
2956 | 2920 | }
|
2957 |
| - return nil |
2958 |
| - }, timeout, interval).Should(BeNil()) |
| 2921 | + |
| 2922 | + _, err = c.KubernetesInterface().CoreV1().ServiceAccounts(generatedNamespace.GetName()).Get(context.Background(), serviceAccountName, metav1.GetOptions{}) |
| 2923 | + if client.IgnoreNotFound(err) != nil { |
| 2924 | + GinkgoT().Logf("error getting sa %s/%s: %v", generatedNamespace.GetName(), serviceAccountName, err) |
| 2925 | + return false |
| 2926 | + } |
| 2927 | + |
| 2928 | + return true |
| 2929 | + }, pollDuration*2, pollInterval).Should(BeTrue()) |
| 2930 | + By("Cleaning up the test") |
2959 | 2931 | })
|
2960 | 2932 |
|
2961 | 2933 | It("CRD validation", func() {
|
|
0 commit comments