open-cluster-management.io/governance-policy-propagator@v0.13.0/test/e2e/case13_policyset_dependencies_test.go (about)

     1  // Copyright (c) 2022 Red Hat, Inc.
     2  // Copyright Contributors to the Open Cluster Management project
     3  
     4  package e2e
     5  
     6  import (
     7  	"context"
     8  	"time"
     9  
    10  	. "github.com/onsi/ginkgo/v2"
    11  	. "github.com/onsi/gomega"
    12  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    13  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    14  
    15  	"open-cluster-management.io/governance-policy-propagator/controllers/common"
    16  	"open-cluster-management.io/governance-policy-propagator/test/utils"
    17  )
    18  
    19  var _ = Describe("Test replacement of policysets in dependencies", Ordered, func() {
    20  	const (
    21  		case13PolicyName     string = "case13-test-policy"
    22  		case13PolicySetName  string = "case13-test-policyset"
    23  		case13PolicyYaml     string = "../resources/case13_policyset_dependencies/case13-resources.yaml"
    24  		case13Set2Yaml       string = "../resources/case13_policyset_dependencies/policyset2.yaml"
    25  		case13Set2updateYaml string = "../resources/case13_policyset_dependencies/policyset2update.yaml"
    26  	)
    27  
    28  	setup := func() {
    29  		By("Creating the policy, policyset, binding, and rule")
    30  		utils.Kubectl("apply", "-f", case13PolicyYaml, "-n", testNamespace, "--kubeconfig="+kubeconfigHub)
    31  		rootplc := utils.GetWithTimeout(
    32  			clientHubDynamic, gvrPolicy, case13PolicyName, testNamespace, true, defaultTimeoutSeconds,
    33  		)
    34  		Expect(rootplc).NotTo(BeNil())
    35  		plcset := utils.GetWithTimeout(
    36  			clientHubDynamic, gvrPolicySet, case13PolicySetName, testNamespace, true, defaultTimeoutSeconds,
    37  		)
    38  		Expect(plcset).NotTo(BeNil())
    39  
    40  		By("Patching the rule with a decision of cluster managed1")
    41  		plr := utils.GetWithTimeout(
    42  			clientHubDynamic, gvrPlacementRule, case13PolicyName+"-plr", testNamespace, true, defaultTimeoutSeconds,
    43  		)
    44  		plr.Object["status"] = utils.GeneratePlrStatus("managed1")
    45  		_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
    46  			context.TODO(), plr, metav1.UpdateOptions{},
    47  		)
    48  		Expect(err).ToNot(HaveOccurred())
    49  
    50  		By("Verifying the replicated policy was created")
    51  		plc := utils.GetWithTimeout(
    52  			clientHubDynamic, gvrPolicy, testNamespace+"."+case13PolicyName, "managed1", true, defaultTimeoutSeconds,
    53  		)
    54  		Expect(plc).ToNot(BeNil())
    55  		opt := metav1.ListOptions{
    56  			LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case13PolicyName,
    57  		}
    58  		utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
    59  
    60  		DeferCleanup(func() {
    61  			By("Running cleanup")
    62  			utils.Kubectl("delete", "-f", case13PolicyYaml, "-n", testNamespace, "--kubeconfig="+kubeconfigHub)
    63  			utils.Kubectl("delete", "-f", case13Set2Yaml, "--kubeconfig="+kubeconfigHub)
    64  			time.Sleep(5 * time.Second) // this helps everything get cleaned up completely
    65  		})
    66  	}
    67  
    68  	Describe("testing top-level dependencies", Ordered, func() {
    69  		const (
    70  			case13Test1Yaml string = "../resources/case13_policyset_dependencies/test1.yaml"
    71  			case13Test2Yaml string = "../resources/case13_policyset_dependencies/test2.yaml"
    72  		)
    73  
    74  		BeforeAll(setup)
    75  
    76  		getDependencies := func(g Gomega) []string {
    77  			plc := utils.GetWithTimeout(clientHubDynamic, gvrPolicy,
    78  				testNamespace+"."+case13PolicyName, "managed1", true, defaultTimeoutSeconds)
    79  			deps, found, err := unstructured.NestedSlice(plc.Object, "spec", "dependencies")
    80  			g.Expect(found).To(BeTrue())
    81  			g.Expect(err).ToNot(HaveOccurred())
    82  
    83  			gotdeps := make([]string, 0)
    84  
    85  			for _, d := range deps {
    86  				dep, ok := d.(map[string]interface{})
    87  				g.Expect(ok).To(BeTrue())
    88  
    89  				kind, ok := dep["kind"].(string)
    90  				g.Expect(ok).To(BeTrue())
    91  
    92  				name, ok := dep["name"].(string)
    93  				g.Expect(ok).To(BeTrue())
    94  
    95  				gotdeps = append(gotdeps, kind+":"+name)
    96  			}
    97  
    98  			return gotdeps
    99  		}
   100  
   101  		It("should replace a PolicySet dependency with each policy in the existing set", func() {
   102  			By("Updating the root policy to have a PolicySet dependency")
   103  			_, err := utils.KubectlWithOutput("apply", "-f", case13Test1Yaml,
   104  				"-n", testNamespace, "--kubeconfig="+kubeconfigHub)
   105  			Expect(err).ToNot(HaveOccurred())
   106  
   107  			By("Checking that the replicated policy has the correct list of dependencies")
   108  			Eventually(getDependencies, defaultTimeoutSeconds, 1).Should(ConsistOf(
   109  				"Policy:"+testNamespace+".case13-geodude",
   110  				"Policy:"+testNamespace+".case13-slowpoke",
   111  			))
   112  		})
   113  
   114  		It("should keep a non-existent PolicySet dependency as-is", func() {
   115  			By("Updating the root policy to have a non-existent PolicySet dependency")
   116  			_, err := utils.KubectlWithOutput("apply", "-f", case13Test2Yaml,
   117  				"-n", testNamespace, "--kubeconfig="+kubeconfigHub)
   118  			Expect(err).ToNot(HaveOccurred())
   119  
   120  			By("Checking that the replicated policy has the correct list of dependencies")
   121  			Eventually(getDependencies, defaultTimeoutSeconds, 1).Should(ConsistOf(
   122  				"Policy:"+testNamespace+".case13-geodude",
   123  				"Policy:"+testNamespace+".case13-slowpoke",
   124  				"PolicySet:case13-test-policyset2",
   125  			))
   126  		})
   127  
   128  		It("should update when the policy set is created", func() {
   129  			By("Waiting some time, to make sure extra policy reconciles aren't pending")
   130  			// This helps verify that the policy is correctly watching the PolicySets,
   131  			// and isn't just coincidently being re-reconiled for some other reason.
   132  			time.Sleep(5 * time.Second)
   133  
   134  			By("Creating the PolicySet that was non-existent")
   135  			_, err := utils.KubectlWithOutput("apply", "-f", case13Set2Yaml, "--kubeconfig="+kubeconfigHub)
   136  			Expect(err).ToNot(HaveOccurred())
   137  
   138  			By("Checking that the replicated policy has the correct list of dependencies")
   139  			Eventually(getDependencies, defaultTimeoutSeconds, 1).Should(ConsistOf(
   140  				"Policy:"+testNamespace+".case13-geodude",
   141  				"Policy:"+testNamespace+".case13-slowpoke",
   142  				"Policy:case13-namespace.case13-zubat",
   143  				"Policy:case13-namespace.case13-psyduck",
   144  			))
   145  		})
   146  
   147  		It("should update when a dependency policy set is updated", func() {
   148  			By("Waiting some time, to make sure extra policy reconciles aren't pending")
   149  			// This helps verify that the policy is correctly watching the PolicySets,
   150  			// and isn't just coincidently being re-reconiled for some other reason.
   151  			time.Sleep(5 * time.Second)
   152  
   153  			By("Updating the PolicySet")
   154  			_, err := utils.KubectlWithOutput("apply", "-f", case13Set2updateYaml, "--kubeconfig="+kubeconfigHub)
   155  			Expect(err).ToNot(HaveOccurred())
   156  
   157  			By("Checking that the replicated policy has the correct list of dependencies")
   158  			Eventually(getDependencies, defaultTimeoutSeconds, 1).Should(ConsistOf(
   159  				"Policy:"+testNamespace+".case13-geodude",
   160  				"Policy:"+testNamespace+".case13-slowpoke",
   161  				"Policy:case13-namespace.case13-golbat", // note: these names changed
   162  				"Policy:case13-namespace.case13-golduck",
   163  			))
   164  		})
   165  	})
   166  
   167  	Describe("testing extraDependencies", Ordered, func() {
   168  		const (
   169  			case13Test3Yaml string = "../resources/case13_policyset_dependencies/test3.yaml"
   170  			case13Test4Yaml string = "../resources/case13_policyset_dependencies/test4.yaml"
   171  		)
   172  
   173  		BeforeAll(setup)
   174  
   175  		getExtraDependencies := func(g Gomega) []string {
   176  			plc := utils.GetWithTimeout(clientHubDynamic, gvrPolicy,
   177  				testNamespace+"."+case13PolicyName, "managed1", true, defaultTimeoutSeconds)
   178  
   179  			templates, found, err := unstructured.NestedSlice(plc.Object, "spec", "policy-templates")
   180  			g.Expect(found).To(BeTrue())
   181  			g.Expect(err).ToNot(HaveOccurred())
   182  			g.Expect(templates).To(HaveLen(1))
   183  
   184  			template, ok := templates[0].(map[string]interface{})
   185  			g.Expect(ok).To(BeTrue())
   186  
   187  			extraDeps, ok := template["extraDependencies"].([]interface{})
   188  			g.Expect(ok).To(BeTrue())
   189  
   190  			gotdeps := make([]string, 0)
   191  
   192  			for _, d := range extraDeps {
   193  				dep, ok := d.(map[string]interface{})
   194  				g.Expect(ok).To(BeTrue())
   195  
   196  				kind, ok := dep["kind"].(string)
   197  				g.Expect(ok).To(BeTrue())
   198  
   199  				name, ok := dep["name"].(string)
   200  				g.Expect(ok).To(BeTrue())
   201  
   202  				gotdeps = append(gotdeps, kind+":"+name)
   203  			}
   204  
   205  			return gotdeps
   206  		}
   207  
   208  		It("should replace a PolicySet extraDependency with each policy in the existing set", func() {
   209  			By("Updating the root policy to have a PolicySet extraDependency")
   210  			_, err := utils.KubectlWithOutput("apply", "-f", case13Test3Yaml,
   211  				"-n", testNamespace, "--kubeconfig="+kubeconfigHub)
   212  			Expect(err).ToNot(HaveOccurred())
   213  
   214  			By("Checking that the replicated policy has the correct list of extraDependencies")
   215  			Eventually(getExtraDependencies, defaultTimeoutSeconds, 1).Should(ConsistOf(
   216  				"Policy:"+testNamespace+".case13-geodude",
   217  				"Policy:"+testNamespace+".case13-slowpoke",
   218  			))
   219  		})
   220  
   221  		It("should keep a non-existent PolicySet extraDependency as-is", func() {
   222  			By("Updating the root policy to have a non-existent PolicySet dependency")
   223  			_, err := utils.KubectlWithOutput("apply", "-f", case13Test4Yaml,
   224  				"-n", testNamespace, "--kubeconfig="+kubeconfigHub)
   225  			Expect(err).ToNot(HaveOccurred())
   226  
   227  			By("Checking that the replicated policy has the correct list of extraDependencies")
   228  			Eventually(getExtraDependencies, defaultTimeoutSeconds, 1).Should(ConsistOf(
   229  				"Policy:"+testNamespace+".case13-geodude",
   230  				"Policy:"+testNamespace+".case13-slowpoke",
   231  				"PolicySet:case13-test-policyset2",
   232  			))
   233  		})
   234  
   235  		It("should update when the policy set is created", func() {
   236  			By("Waiting some time, to make sure extra policy reconciles aren't pending")
   237  			// This helps verify that the policy is correctly watching the PolicySets,
   238  			// and isn't just coincidently being re-reconiled for some other reason.
   239  			time.Sleep(5 * time.Second)
   240  
   241  			By("Creating the PolicySet that was non-existent")
   242  			_, err := utils.KubectlWithOutput("apply", "-f", case13Set2Yaml, "--kubeconfig="+kubeconfigHub)
   243  			Expect(err).ToNot(HaveOccurred())
   244  
   245  			By("Checking that the replicated policy has the correct list of extraDependencies")
   246  			Eventually(getExtraDependencies, defaultTimeoutSeconds, 1).Should(ConsistOf(
   247  				"Policy:"+testNamespace+".case13-geodude",
   248  				"Policy:"+testNamespace+".case13-slowpoke",
   249  				"Policy:case13-namespace.case13-zubat",
   250  				"Policy:case13-namespace.case13-psyduck",
   251  			))
   252  		})
   253  
   254  		It("should update when a dependency policy set is updated", func() {
   255  			By("Waiting some time, to make sure extra policy reconciles aren't pending")
   256  			// This helps verify that the policy is correctly watching the PolicySets,
   257  			// and isn't just coincidently being re-reconiled for some other reason.
   258  			time.Sleep(5 * time.Second)
   259  
   260  			By("Updating the PolicySet")
   261  			_, err := utils.KubectlWithOutput("apply", "-f", case13Set2updateYaml, "--kubeconfig="+kubeconfigHub)
   262  			Expect(err).ToNot(HaveOccurred())
   263  
   264  			By("Checking that the replicated policy has the correct list of dependencies")
   265  			Eventually(getExtraDependencies, defaultTimeoutSeconds, 1).Should(ConsistOf(
   266  				"Policy:"+testNamespace+".case13-geodude",
   267  				"Policy:"+testNamespace+".case13-slowpoke",
   268  				"Policy:case13-namespace.case13-golbat", // note: these names changed
   269  				"Policy:case13-namespace.case13-golduck",
   270  			))
   271  		})
   272  	})
   273  })