open-cluster-management.io/governance-policy-propagator@v0.13.0/test/e2e/case12_encryptionkeys_controller_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 "bytes" 8 "context" 9 "encoding/base64" 10 "strings" 11 12 . "github.com/onsi/ginkgo/v2" 13 . "github.com/onsi/gomega" 14 corev1 "k8s.io/api/core/v1" 15 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 16 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 17 18 "open-cluster-management.io/governance-policy-propagator/controllers/common" 19 "open-cluster-management.io/governance-policy-propagator/test/utils" 20 ) 21 22 var _ = Describe("Test policy encryption key rotation", func() { 23 key := bytes.Repeat([]byte{byte('A')}, 256/8) 24 keyB64 := base64.StdEncoding.EncodeToString(key) 25 previousKey := bytes.Repeat([]byte{byte('B')}, 256/8) 26 27 rsrcPath := "../resources/case12_encryptionkeys_controller/" 28 policyOneYaml := rsrcPath + "policy-one.yaml" 29 policyTwoYaml := rsrcPath + "policy-two.yaml" 30 policyOneName := "policy-one" 31 policyTwoName := "policy-two" 32 replicatedPolicyOneYaml := rsrcPath + "replicated-policy-one.yaml" 33 replicatedPolicyOneName := "policy-propagator-test.policy-one" 34 35 It("should create some sample policies", func() { 36 By("Creating the root policies with placement rules and bindings") 37 utils.Kubectl("apply", "-f", policyOneYaml, 38 "-n", testNamespace, "--kubeconfig="+kubeconfigHub) 39 rootOne := utils.GetWithTimeout( 40 clientHubDynamic, gvrPolicy, policyOneName, testNamespace, true, defaultTimeoutSeconds, 41 ) 42 Expect(rootOne).NotTo(BeNil()) 43 44 utils.Kubectl("apply", "-f", policyTwoYaml, 45 "-n", testNamespace, "--kubeconfig="+kubeconfigHub) 46 rootTwo := utils.GetWithTimeout( 47 clientHubDynamic, gvrPolicy, policyTwoName, testNamespace, true, defaultTimeoutSeconds, 48 ) 49 Expect(rootTwo).NotTo(BeNil()) 50 51 By("Patching in the decision for policy-one") 52 plrOne := utils.GetWithTimeout( 53 clientHubDynamic, gvrPlacementRule, policyOneName+"-plr", testNamespace, true, defaultTimeoutSeconds, 54 ) 55 plrOne.Object["status"] = utils.GeneratePlrStatus("managed1") 56 _, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus( 57 context.TODO(), plrOne, metav1.UpdateOptions{}, 58 ) 59 Expect(err).ToNot(HaveOccurred()) 60 replicatedOne := utils.GetWithTimeout( 61 clientHubDynamic, gvrPolicy, testNamespace+"."+policyOneName, "managed1", true, defaultTimeoutSeconds, 62 ) 63 Expect(replicatedOne).ToNot(BeNil()) 64 opt := metav1.ListOptions{ 65 LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + policyOneName, 66 } 67 utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds) 68 69 By("Patching in the decision for policy-two") 70 plrTwo := utils.GetWithTimeout( 71 clientHubDynamic, gvrPlacementRule, policyTwoName+"-plr", testNamespace, true, defaultTimeoutSeconds, 72 ) 73 plrTwo.Object["status"] = utils.GeneratePlrStatus("managed1") 74 _, err = clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus( 75 context.TODO(), plrTwo, metav1.UpdateOptions{}, 76 ) 77 Expect(err).ToNot(HaveOccurred()) 78 replicatedTwo := utils.GetWithTimeout( 79 clientHubDynamic, gvrPolicy, testNamespace+"."+policyTwoName, "managed1", true, defaultTimeoutSeconds, 80 ) 81 Expect(replicatedTwo).ToNot(BeNil()) 82 opt = metav1.ListOptions{ 83 LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + policyTwoName, 84 } 85 utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds) 86 87 By("Adding the IV Annotation to the replicated policy-one") 88 utils.Kubectl("apply", "-n", "managed1", 89 "-f", replicatedPolicyOneYaml, "--kubeconfig="+kubeconfigHub) 90 91 Eventually(func() interface{} { 92 replicatedPolicy := utils.GetWithTimeout( 93 clientHubDynamic, gvrPolicy, replicatedPolicyOneName, "managed1", true, defaultTimeoutSeconds, 94 ) 95 96 return replicatedPolicy.GetAnnotations() 97 }, defaultTimeoutSeconds, 1).Should(HaveKey(IVAnnotation)) 98 }) 99 100 It("should create a "+EncryptionKeySecret+" secret that needs a rotation", func() { 101 secret := &corev1.Secret{ 102 ObjectMeta: metav1.ObjectMeta{ 103 Name: EncryptionKeySecret, 104 Namespace: "managed1", 105 Annotations: map[string]string{LastRotatedAnnotation: "2020-04-15T01:02:03Z"}, 106 }, 107 Data: map[string][]byte{"key": key, "previousKey": previousKey}, 108 } 109 _, err := clientHub.CoreV1().Secrets("managed1").Create(context.TODO(), secret, metav1.CreateOptions{}) 110 Expect(err).ShouldNot(HaveOccurred()) 111 }) 112 113 It("should have rotated the key in the "+EncryptionKeySecret+" secret", func() { 114 var secret *unstructured.Unstructured 115 Eventually(func() interface{} { 116 secret = utils.GetWithTimeout( 117 clientHubDynamic, 118 gvrSecret, 119 EncryptionKeySecret, 120 "managed1", 121 true, 122 defaultTimeoutSeconds, 123 ) 124 125 data, ok := secret.Object["data"].(map[string]interface{}) 126 if !ok { 127 return "" 128 } 129 130 currentKey, ok := data["key"].(string) 131 if !ok { 132 return "" 133 } 134 135 return currentKey 136 }, defaultTimeoutSeconds, 1).ShouldNot(Equal(keyB64)) 137 138 currentPrevKey, ok := secret.Object["data"].(map[string]interface{})["previousKey"].(string) 139 Expect(ok).Should(BeTrue()) 140 Expect(currentPrevKey).Should(Equal(keyB64)) 141 }) 142 143 It("should have triggered policies to be reprocessed", func() { 144 Eventually(func() interface{} { 145 policy := utils.GetWithTimeout( 146 clientHubDynamic, 147 gvrPolicy, 148 "policy-one", 149 testNamespace, 150 true, 151 defaultTimeoutSeconds, 152 ) 153 154 return strings.HasPrefix(policy.GetAnnotations()[TriggerUpdateAnnotation], "rotate-key-") 155 }, defaultTimeoutSeconds, 1).Should(BeTrue()) 156 157 policy, err := clientHubDynamic.Resource(gvrPolicy).Namespace(testNamespace).Get( 158 context.TODO(), "policy-two", metav1.GetOptions{}, 159 ) 160 Expect(err).ShouldNot(HaveOccurred()) 161 Expect(policy.GetAnnotations()[TriggerUpdateAnnotation]).Should(Equal("")) 162 }) 163 164 It("clean up", func() { 165 err := clientHub.CoreV1().Secrets("managed1").Delete( 166 context.TODO(), EncryptionKeySecret, metav1.DeleteOptions{}, 167 ) 168 Expect(err).ShouldNot(HaveOccurred()) 169 170 for _, policyName := range []string{"policy-one", "policy-two"} { 171 err = clientHubDynamic.Resource(gvrPolicy).Namespace(testNamespace).Delete( 172 context.TODO(), policyName, metav1.DeleteOptions{}, 173 ) 174 Expect(err).ShouldNot(HaveOccurred()) 175 } 176 }) 177 })