Skip to content

Commit 4914065

Browse files
committed
Add support for the copy template functions to the propagator
Adding the `copyConfigMapData` and the `copySecretData` template functions to the policy propagator. Refs: - https://issues.redhat.com/browse/ACM-2611 Signed-off-by: Gus Parvin <[email protected]>
1 parent 3ee5fae commit 4914065

File tree

4 files changed

+350
-0
lines changed

4 files changed

+350
-0
lines changed

test/e2e/case9_templates_test.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ const (
2929
case9EncryptionSecretName = "policy-encryption-key"
3030
case9SecretName = "case9-secret"
3131
IVAnnotation = "policy.open-cluster-management.io/encryption-iv"
32+
case9PolicyNameCopy = "case9-test-policy-copy"
33+
case9PolicyYamlCopy = "../resources/case9_templates/case9-test-policy_copy.yaml"
34+
case9PolicyYamlCopiedRepl = "../resources/case9_templates/case9-test-replpolicy_copied-"
3235
)
3336

3437
var _ = Describe("Test policy templates", func() {
@@ -282,3 +285,150 @@ var _ = Describe("Test encrypted policy templates", func() {
282285
}
283286
})
284287
})
288+
289+
var _ = Describe("Test encrypted policy templates with secret copy", func() {
290+
Describe("Create policy, placement and referenced resource in ns: "+testNamespace, Ordered, func() {
291+
for i := 1; i <= 2; i++ {
292+
managedCluster := "managed" + fmt.Sprint(i)
293+
294+
It("should be created in user ns", func() {
295+
By("Creating " + case9PolicyYamlCopy)
296+
utils.Kubectl("apply",
297+
"-f", case9PolicyYamlCopy,
298+
"-n", testNamespace)
299+
plc := utils.GetWithTimeout(
300+
clientHubDynamic, gvrPolicy, case9PolicyNameCopy, testNamespace,
301+
true, defaultTimeoutSeconds,
302+
)
303+
Expect(plc).NotTo(BeNil())
304+
})
305+
306+
It("should resolve templates and propagate to cluster ns "+managedCluster, func() {
307+
By("Initializing AES Encryption Secret")
308+
_, err := utils.KubectlWithOutput("apply",
309+
"-f", case9EncryptionSecret,
310+
"-n", managedCluster)
311+
Expect(err).To(BeNil())
312+
313+
By("Patching test-policy-plr with decision of cluster " + managedCluster)
314+
plr := utils.GetWithTimeout(
315+
clientHubDynamic, gvrPlacementRule, case9PolicyNameCopy+"-plr", testNamespace,
316+
true, defaultTimeoutSeconds,
317+
)
318+
plr.Object["status"] = utils.GeneratePlrStatus(managedCluster)
319+
_, err = clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
320+
context.TODO(), plr, metav1.UpdateOptions{},
321+
)
322+
Expect(err).To(BeNil())
323+
324+
var replicatedPlc *unstructured.Unstructured
325+
By("Waiting for encrypted values")
326+
Eventually(func() interface{} {
327+
replicatedPlc = utils.GetWithTimeout(
328+
clientHubDynamic,
329+
gvrPolicy,
330+
testNamespace+"."+case9PolicyNameCopy,
331+
managedCluster,
332+
true,
333+
defaultTimeoutSeconds,
334+
)
335+
336+
return fmt.Sprint(replicatedPlc.Object["spec"])
337+
}, defaultTimeoutSeconds, 1).Should(ContainSubstring("$ocm_encrypted:"))
338+
339+
By("Patching the initialization vector with a static value")
340+
// Setting Initialization Vector so that the test results will be deterministic
341+
initializationVector := "7cznVUq5SXEE4RMZNkGOrQ=="
342+
annotations := replicatedPlc.GetAnnotations()
343+
annotations[IVAnnotation] = initializationVector
344+
replicatedPlc.SetAnnotations(annotations)
345+
_, err = clientHubDynamic.Resource(gvrPolicy).Namespace(managedCluster).Update(
346+
context.TODO(), replicatedPlc, metav1.UpdateOptions{},
347+
)
348+
Expect(err).To(BeNil())
349+
350+
By("Verifying the replicated policy against a snapshot")
351+
yamlPlc := utils.ParseYaml(case9PolicyYamlCopiedRepl + managedCluster + ".yaml")
352+
Eventually(func() interface{} {
353+
replicatedPlc = utils.GetWithTimeout(
354+
clientHubDynamic,
355+
gvrPolicy,
356+
testNamespace+"."+case9PolicyNameCopy,
357+
managedCluster,
358+
true,
359+
defaultTimeoutSeconds,
360+
)
361+
362+
return replicatedPlc.Object["spec"]
363+
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(yamlPlc.Object["spec"]))
364+
})
365+
366+
It("should reconcile when the secret referenced in the template is updated", func() {
367+
By("Updating the secret " + case9SecretName)
368+
newToken := "THVrZS4gSSBhbSB5b3VyIGZhdGhlci4="
369+
patch := []byte(`{"data": {"token": "` + newToken + `"}}`)
370+
_, err := clientHub.CoreV1().Secrets(testNamespace).Patch(
371+
context.TODO(), case9SecretName, types.StrategicMergePatchType, patch, metav1.PatchOptions{},
372+
)
373+
Expect(err).To(BeNil())
374+
375+
By("Verifying the replicated policy was updated")
376+
expected := "$ocm_encrypted:dbHPzG98PxV7RXcAx25mMGPBAUbfjJTEMyFc7kE2W7U3FW5+X31LkidHu/25ic4m"
377+
Eventually(func() string {
378+
replicatedPlc := utils.GetWithTimeout(
379+
clientHubDynamic,
380+
gvrPolicy,
381+
testNamespace+"."+case9PolicyNameCopy,
382+
managedCluster,
383+
true,
384+
defaultTimeoutSeconds,
385+
)
386+
387+
templates, _, _ := unstructured.NestedSlice(replicatedPlc.Object, "spec", "policy-templates")
388+
if len(templates) < 1 {
389+
return ""
390+
}
391+
392+
template, ok := templates[0].(map[string]interface{})
393+
if !ok {
394+
return ""
395+
}
396+
397+
objectTemplates, _, _ := unstructured.NestedSlice(
398+
template, "objectDefinition", "spec", "object-templates",
399+
)
400+
if len(objectTemplates) < 1 {
401+
return ""
402+
}
403+
404+
objectTemplate, ok := objectTemplates[0].(map[string]interface{})
405+
if !ok {
406+
return ""
407+
}
408+
409+
secretValue, _, _ := unstructured.NestedString(
410+
objectTemplate, "objectDefinition", "data", "token",
411+
)
412+
413+
return secretValue
414+
}, defaultTimeoutSeconds, 1).Should(Equal(expected))
415+
})
416+
417+
It("should clean up the encryption key", func() {
418+
utils.Kubectl("delete", "secret",
419+
case9EncryptionSecretName,
420+
"-n", managedCluster)
421+
utils.GetWithTimeout(
422+
clientHubDynamic, gvrSecret, case9EncryptionSecretName, managedCluster,
423+
false, defaultTimeoutSeconds,
424+
)
425+
})
426+
427+
It("should clean up", func() {
428+
utils.Kubectl("delete", "-f", case9PolicyYamlCopy, "-n", testNamespace)
429+
opt := metav1.ListOptions{}
430+
utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, false, defaultTimeoutSeconds)
431+
})
432+
}
433+
})
434+
})
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
apiVersion: policy.open-cluster-management.io/v1
2+
kind: Policy
3+
metadata:
4+
name: case9-test-policy-copy
5+
spec:
6+
remediationAction: inform
7+
disabled: false
8+
policy-templates:
9+
- objectDefinition:
10+
apiVersion: policy.open-cluster-management.io/v1
11+
kind: ConfigurationPolicy
12+
metadata:
13+
name: case9-test-configpolicy
14+
spec:
15+
remediationAction: inform
16+
namespaceSelector:
17+
exclude: ["kube-*"]
18+
include: ["default"]
19+
object-templates:
20+
- complianceType: musthave
21+
objectDefinition:
22+
kind: ConfigMap
23+
apiVersion: v1
24+
metadata:
25+
name: case9-test-configmap
26+
namespace: test
27+
data: '{{hub copySecretData "policy-propagator-test" "case9-secret" hub}}'
28+
- objectDefinition:
29+
apiVersion: policy.open-cluster-management.io/v1
30+
kind: ConfigurationPolicy
31+
metadata:
32+
name: case9-test-configpolicy
33+
spec:
34+
remediationAction: inform
35+
namespaceSelector:
36+
exclude: ["kube-*"]
37+
include: ["default"]
38+
object-templates:
39+
- complianceType: mustnothave
40+
objectDefinition:
41+
kind: ConfigMap
42+
apiVersion: v1
43+
metadata:
44+
name: case9-test-configmap2
45+
namespace: test
46+
data:
47+
# Configuration values can be set as key-value properties
48+
thisOtherThing: |-
49+
{{hub printf "%s" .ManagedClusterName | protect hub}}
50+
---
51+
apiVersion: policy.open-cluster-management.io/v1
52+
kind: PlacementBinding
53+
metadata:
54+
name: case9-test-policy-copy-pb
55+
placementRef:
56+
apiGroup: apps.open-cluster-management.io
57+
kind: PlacementRule
58+
name: case9-test-policy-copy-plr
59+
subjects:
60+
- apiGroup: policy.open-cluster-management.io
61+
kind: Policy
62+
name: case9-test-policy-copy
63+
---
64+
apiVersion: apps.open-cluster-management.io/v1
65+
kind: PlacementRule
66+
metadata:
67+
name: case9-test-policy-copy-plr
68+
spec:
69+
clusterConditions:
70+
- status: "True"
71+
type: ManagedClusterConditionAvailable
72+
clusterSelector:
73+
matchExpressions:
74+
[]
75+
---
76+
apiVersion: v1
77+
kind: ConfigMap
78+
metadata:
79+
name: case9-config
80+
data:
81+
managed1-vlanid: "123"
82+
managed2-vlanid: "456"
83+
---
84+
apiVersion: v1
85+
kind: Secret
86+
metadata:
87+
name: case9-secret
88+
data:
89+
token: RG8uCk9yIGRvIG5vdC4KVGhlcmUgaXMgbm8gdHJ5Lgo=
90+
password: cGFzc3dvcmQK
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
apiVersion: policy.open-cluster-management.io/v1
2+
kind: Policy
3+
metadata:
4+
annotations:
5+
"policy.open-cluster-management.io/encryption-iv": "7cznVUq5SXEE4RMZNkGOrQ=="
6+
name: case9-test-policy
7+
spec:
8+
remediationAction: inform
9+
disabled: false
10+
policy-templates:
11+
- objectDefinition:
12+
apiVersion: policy.open-cluster-management.io/v1
13+
kind: ConfigurationPolicy
14+
metadata:
15+
annotations:
16+
"policy.open-cluster-management.io/encryption-iv": "7cznVUq5SXEE4RMZNkGOrQ=="
17+
name: case9-test-configpolicy
18+
spec:
19+
remediationAction: inform
20+
namespaceSelector:
21+
exclude: ["kube-*"]
22+
include: ["default"]
23+
object-templates:
24+
- complianceType: musthave
25+
objectDefinition:
26+
kind: ConfigMap
27+
apiVersion: v1
28+
metadata:
29+
name: case9-test-configmap
30+
namespace: test
31+
data:
32+
token: $ocm_encrypted:5n8twYYcFOIYqFznODvRPlMsZ9iGWUoyIDWml4HTPkrG5JX2/TLF63sfvDZD9fvP
33+
password: $ocm_encrypted:RX6KfjpLBTFhlAFIzm0kKA==
34+
- objectDefinition:
35+
apiVersion: policy.open-cluster-management.io/v1
36+
kind: ConfigurationPolicy
37+
metadata:
38+
annotations:
39+
"policy.open-cluster-management.io/encryption-iv": "7cznVUq5SXEE4RMZNkGOrQ=="
40+
name: case9-test-configpolicy
41+
spec:
42+
remediationAction: inform
43+
namespaceSelector:
44+
exclude: ["kube-*"]
45+
include: ["default"]
46+
object-templates:
47+
- complianceType: mustnothave
48+
objectDefinition:
49+
kind: ConfigMap
50+
apiVersion: v1
51+
metadata:
52+
name: case9-test-configmap2
53+
namespace: test
54+
data:
55+
thisOtherThing: $ocm_encrypted:1HozXUTNSEo5uNOKK0ninA==
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
apiVersion: policy.open-cluster-management.io/v1
2+
kind: Policy
3+
metadata:
4+
annotations:
5+
"policy.open-cluster-management.io/encryption-iv": "7cznVUq5SXEE4RMZNkGOrQ=="
6+
name: case9-test-policy
7+
spec:
8+
remediationAction: inform
9+
disabled: false
10+
policy-templates:
11+
- objectDefinition:
12+
apiVersion: policy.open-cluster-management.io/v1
13+
kind: ConfigurationPolicy
14+
metadata:
15+
annotations:
16+
"policy.open-cluster-management.io/encryption-iv": "7cznVUq5SXEE4RMZNkGOrQ=="
17+
name: case9-test-configpolicy
18+
spec:
19+
remediationAction: inform
20+
namespaceSelector:
21+
exclude: ["kube-*"]
22+
include: ["default"]
23+
object-templates:
24+
- complianceType: musthave
25+
objectDefinition:
26+
kind: ConfigMap
27+
apiVersion: v1
28+
metadata:
29+
name: case9-test-configmap
30+
namespace: test
31+
data:
32+
token: $ocm_encrypted:5n8twYYcFOIYqFznODvRPlMsZ9iGWUoyIDWml4HTPkrG5JX2/TLF63sfvDZD9fvP
33+
password: $ocm_encrypted:RX6KfjpLBTFhlAFIzm0kKA==
34+
- objectDefinition:
35+
apiVersion: policy.open-cluster-management.io/v1
36+
kind: ConfigurationPolicy
37+
metadata:
38+
annotations:
39+
"policy.open-cluster-management.io/encryption-iv": "7cznVUq5SXEE4RMZNkGOrQ=="
40+
name: case9-test-configpolicy
41+
spec:
42+
remediationAction: inform
43+
namespaceSelector:
44+
exclude: ["kube-*"]
45+
include: ["default"]
46+
object-templates:
47+
- complianceType: mustnothave
48+
objectDefinition:
49+
kind: ConfigMap
50+
apiVersion: v1
51+
metadata:
52+
name: case9-test-configmap2
53+
namespace: test
54+
data:
55+
thisOtherThing: $ocm_encrypted:oW1OaQWTqTspUDlgLFelRQ==

0 commit comments

Comments
 (0)