Skip to content

Commit

Permalink
Fix spec fetching for Compliance API
Browse files Browse the repository at this point in the history
This was also incorrectly setting the replicated policy annotations on
the policy template's annotations.

Co-authored-by: Dale Haiducek <[email protected]>
Signed-off-by: mprahl <[email protected]>
(cherry picked from commit 4f01a51)
  • Loading branch information
mprahl authored and Magic Mirror committed Feb 7, 2024
1 parent 33963b0 commit 13c364d
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 20 deletions.
6 changes: 4 additions & 2 deletions controllers/complianceeventsapi/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ func PolicyFromUnstructured(obj unstructured.Unstructured) *Policy {

policy.Name = obj.GetName()

spec, ok, _ := unstructured.NestedStringMap(obj.Object, "spec")
spec, ok, _ := unstructured.NestedMap(obj.Object, "spec")
if ok {
typedSpec := JSONMap{}

Expand All @@ -402,7 +402,9 @@ func PolicyFromUnstructured(obj unstructured.Unstructured) *Policy {
}

if severity, ok := spec["severity"]; ok {
policy.Severity = &severity
if sevString, ok := severity.(string); ok {
policy.Severity = &sevString
}
}

return policy
Expand Down
18 changes: 12 additions & 6 deletions controllers/propagator/replicatedpolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,7 @@ func (r *ReplicatedPolicyReconciler) setDBAnnotations(
}
} else {
annotations[ParentPolicyIDAnnotation] = strconv.FormatInt(int64(parentPolicyID), 10)
replicatedPolicy.SetAnnotations(annotations)
}

for i, plcTemplate := range replicatedPolicy.Spec.PolicyTemplates {
Expand All @@ -546,18 +547,23 @@ func (r *ReplicatedPolicyReconciler) setDBAnnotations(
}

requeueForDB = true
annotations := plcTmplUnstruct.GetAnnotations()
tmplAnnotations := plcTmplUnstruct.GetAnnotations()

if annotations[PolicyIDAnnotation] == "" {
if tmplAnnotations[PolicyIDAnnotation] == "" {
continue
}

// Remove it if the user accidentally provided the annotation
delete(annotations, PolicyIDAnnotation)
plcTmplUnstruct.SetAnnotations(annotations)
delete(tmplAnnotations, PolicyIDAnnotation)
plcTmplUnstruct.SetAnnotations(tmplAnnotations)
} else {
annotations[PolicyIDAnnotation] = strconv.FormatInt(int64(policyID), 10)
plcTmplUnstruct.SetAnnotations(annotations)
tmplAnnotations := plcTmplUnstruct.GetAnnotations()
if tmplAnnotations == nil {
tmplAnnotations = map[string]string{}
}

tmplAnnotations[PolicyIDAnnotation] = strconv.FormatInt(int64(policyID), 10)
plcTmplUnstruct.SetAnnotations(tmplAnnotations)
}

updatedTemplate, err := plcTmplUnstruct.MarshalJSON()
Expand Down
8 changes: 8 additions & 0 deletions controllers/propagator/replicatedpolicy_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ func TestSetDBAnnotationsNoDB(t *testing.T) {
t.Fatalf("Expected the policy ID of 56 but got: %s", templateAnnotations[PolicyIDAnnotation])
}

if len(templateAnnotations) != 1 {
t.Fatalf("Expected 1 policy annotation but got: %d", len(templateAnnotations))
}

// Test a cache hit from the last run using the policies from the first run
reconciler.setDBAnnotations(context.TODO(), rootPolicy, replicatedPolicy, existingReplicatedPolicy)

Expand All @@ -142,4 +146,8 @@ func TestSetDBAnnotationsNoDB(t *testing.T) {
if templateAnnotations[PolicyIDAnnotation] != "56" {
t.Fatalf("Expected the policy ID of 56 but got: %s", templateAnnotations[PolicyIDAnnotation])
}

if len(templateAnnotations) != 1 {
t.Fatalf("Expected 1 policy annotation but got: %d", len(templateAnnotations))
}
}
5 changes: 4 additions & 1 deletion test/e2e/case14_root_policy_metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ var _ = Describe("Test root policy metrics", Ordered, func() {
Expect(plc).ToNot(BeNil())

yamlPlc := utils.ParseYaml(case9ReplicatedPolicyYamlM1)
Eventually(func() interface{} {
Eventually(func(g Gomega) interface{} {
replicatedPlc := utils.GetWithTimeout(
clientHubDynamic,
gvrPolicy,
Expand All @@ -74,6 +74,9 @@ var _ = Describe("Test root policy metrics", Ordered, func() {
defaultTimeoutSeconds,
)

err := utils.RemovePolicyTemplateDBAnnotations(replicatedPlc)
g.Expect(err).ToNot(HaveOccurred())

return replicatedPlc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(yamlPlc.Object["spec"]))
})
Expand Down
10 changes: 8 additions & 2 deletions test/e2e/case1_propagation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ var _ = Describe("Test policy propagation", func() {
context.TODO(), rootPlc, metav1.UpdateOptions{},
)
Expect(err).ToNot(HaveOccurred())
Eventually(func() interface{} {
Eventually(func(g Gomega) interface{} {
replicatedPlc := utils.GetWithTimeout(
clientHubDynamic,
gvrPolicy,
Expand All @@ -498,6 +498,9 @@ var _ = Describe("Test policy propagation", func() {
defaultTimeoutSeconds,
)

err := utils.RemovePolicyTemplateDBAnnotations(replicatedPlc)
g.Expect(err).ToNot(HaveOccurred())

return replicatedPlc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(rootPlc.Object["spec"]))
})
Expand Down Expand Up @@ -560,7 +563,7 @@ var _ = Describe("Test policy propagation", func() {
)
Expect(rootPlc).NotTo(BeNil())
yamlPlc := utils.ParseYaml("../resources/case1_propagation/case1-test-policy2.yaml")
Eventually(func() interface{} {
Eventually(func(g Gomega) interface{} {
replicatedPlc := utils.GetWithTimeout(
clientHubDynamic,
gvrPolicy,
Expand All @@ -570,6 +573,9 @@ var _ = Describe("Test policy propagation", func() {
defaultTimeoutSeconds,
)

err := utils.RemovePolicyTemplateDBAnnotations(replicatedPlc)
g.Expect(err).ToNot(HaveOccurred())

return replicatedPlc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(yamlPlc.Object["spec"]))
})
Expand Down
4 changes: 3 additions & 1 deletion test/e2e/case20_compliance_api_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ func bringDownDBConnection(ctx context.Context) {
g.Expect(err).ToNot(HaveOccurred())

resp, err := httpClient.Do(req)
g.Expect(err).ToNot(HaveOccurred())
if err != nil {
return
}

defer resp.Body.Close()

Expand Down
5 changes: 4 additions & 1 deletion test/e2e/case3_mutation_recovery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,14 @@ var _ = Describe("Test unexpected policy mutation", func() {
rootPlc := utils.GetWithTimeout(
clientHubDynamic, gvrPolicy, case3PolicyName, testNamespace, true, defaultTimeoutSeconds,
)
Eventually(func() interface{} {
Eventually(func(g Gomega) interface{} {
plc = utils.GetWithTimeout(
clientHubDynamic, gvrPolicy, testNamespace+"."+case3PolicyName, "managed2", true, defaultTimeoutSeconds,
)

err := utils.RemovePolicyTemplateDBAnnotations(plc)
g.Expect(err).ToNot(HaveOccurred())

return plc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(rootPlc.Object["spec"]))
})
Expand Down
10 changes: 8 additions & 2 deletions test/e2e/case6_placement_propagation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ var _ = Describe("Test policy propagation", func() {
context.TODO(), rootPlc, metav1.UpdateOptions{},
)
Expect(err).ToNot(HaveOccurred())
Eventually(func() interface{} {
Eventually(func(g Gomega) interface{} {
replicatedPlc := utils.GetWithTimeout(
clientHubDynamic,
gvrPolicy,
Expand All @@ -437,6 +437,9 @@ var _ = Describe("Test policy propagation", func() {
defaultTimeoutSeconds,
)

err := utils.RemovePolicyTemplateDBAnnotations(replicatedPlc)
g.Expect(err).ToNot(HaveOccurred())

return replicatedPlc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(rootPlc.Object["spec"]))
})
Expand Down Expand Up @@ -508,7 +511,7 @@ var _ = Describe("Test policy propagation", func() {
)
Expect(rootPlc).NotTo(BeNil())
yamlPlc := utils.ParseYaml("../resources/case6_placement_propagation/case6-test-policy2.yaml")
Eventually(func() interface{} {
Eventually(func(g Gomega) interface{} {
replicatedPlc := utils.GetWithTimeout(
clientHubDynamic,
gvrPolicy,
Expand All @@ -518,6 +521,9 @@ var _ = Describe("Test policy propagation", func() {
defaultTimeoutSeconds,
)

err := utils.RemovePolicyTemplateDBAnnotations(replicatedPlc)
g.Expect(err).ToNot(HaveOccurred())

return replicatedPlc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(yamlPlc.Object["spec"]))
})
Expand Down
25 changes: 20 additions & 5 deletions test/e2e/case9_templates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ var _ = Describe("Test policy templates", func() {
Expect(plc).ToNot(BeNil())

yamlPlc := utils.ParseYaml(case9ReplicatedPolicyYamlM1)
Eventually(func() interface{} {
Eventually(func(g Gomega) interface{} {
replicatedPlc := utils.GetWithTimeout(
clientHubDynamic,
gvrPolicy,
Expand All @@ -77,6 +77,9 @@ var _ = Describe("Test policy templates", func() {
defaultTimeoutSeconds,
)

err := utils.RemovePolicyTemplateDBAnnotations(replicatedPlc)
g.Expect(err).ToNot(HaveOccurred())

return replicatedPlc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(yamlPlc.Object["spec"]))
})
Expand All @@ -87,7 +90,7 @@ var _ = Describe("Test policy templates", func() {

By("Verifying the policy is updated")
yamlPlc := utils.ParseYaml(case9ReplicatedPolicyYamlM1Update)
Eventually(func() interface{} {
Eventually(func(g Gomega) interface{} {
replicatedPlc := utils.GetWithTimeout(
clientHubDynamic,
gvrPolicy,
Expand All @@ -97,6 +100,9 @@ var _ = Describe("Test policy templates", func() {
defaultTimeoutSeconds,
)

err := utils.RemovePolicyTemplateDBAnnotations(replicatedPlc)
g.Expect(err).ToNot(HaveOccurred())

return replicatedPlc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(yamlPlc.Object["spec"]))
})
Expand All @@ -118,7 +124,7 @@ var _ = Describe("Test policy templates", func() {
Expect(plc).ToNot(BeNil())

yamlPlc := utils.ParseYaml(case9ReplicatedPolicyYamlM2)
Eventually(func() interface{} {
Eventually(func(g Gomega) interface{} {
replicatedPlc := utils.GetWithTimeout(
clientHubDynamic,
gvrPolicy,
Expand All @@ -128,6 +134,9 @@ var _ = Describe("Test policy templates", func() {
defaultTimeoutSeconds,
)

err := utils.RemovePolicyTemplateDBAnnotations(replicatedPlc)
g.Expect(err).ToNot(HaveOccurred())

return replicatedPlc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(yamlPlc.Object["spec"]))
})
Expand Down Expand Up @@ -210,7 +219,7 @@ var _ = Describe("Test encrypted policy templates", func() {

By("Verifying the replicated policy against a snapshot")
yamlPlc := utils.ParseYaml(case9PolicyYamlEncryptedRepl + managedCluster + ".yaml")
Eventually(func() interface{} {
Eventually(func(g Gomega) interface{} {
replicatedPlc = utils.GetWithTimeout(
clientHubDynamic,
gvrPolicy,
Expand All @@ -220,6 +229,9 @@ var _ = Describe("Test encrypted policy templates", func() {
defaultTimeoutSeconds,
)

err := utils.RemovePolicyTemplateDBAnnotations(replicatedPlc)
g.Expect(err).ToNot(HaveOccurred())

return replicatedPlc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(yamlPlc.Object["spec"]))
})
Expand Down Expand Up @@ -361,7 +373,7 @@ var _ = Describe("Test encrypted policy templates with secret copy", func() {

By("Verifying the replicated policy against a snapshot")
yamlPlc := utils.ParseYaml(case9PolicyYamlCopiedRepl + managedCluster + ".yaml")
Eventually(func() interface{} {
Eventually(func(g Gomega) interface{} {
replicatedPlc = utils.GetWithTimeout(
clientHubDynamic,
gvrPolicy,
Expand All @@ -371,6 +383,9 @@ var _ = Describe("Test encrypted policy templates with secret copy", func() {
defaultTimeoutSeconds,
)

err := utils.RemovePolicyTemplateDBAnnotations(replicatedPlc)
g.Expect(err).ToNot(HaveOccurred())

return replicatedPlc.Object["spec"]
}, defaultTimeoutSeconds, 1).Should(utils.SemanticEqual(yamlPlc.Object["spec"]))
})
Expand Down
52 changes: 52 additions & 0 deletions test/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
"k8s.io/client-go/kubernetes"
clusterv1beta1 "open-cluster-management.io/api/cluster/v1beta1"
appsv1 "open-cluster-management.io/multicloud-operators-subscription/pkg/apis/apps/placementrule/v1"

"open-cluster-management.io/governance-policy-propagator/controllers/propagator"
)

// GeneratePlrStatus generate plr status with given clusters
Expand Down Expand Up @@ -54,6 +56,56 @@ func GeneratePldStatus(
return &clusterv1beta1.PlacementDecisionStatus{Decisions: plrDecision}
}

func RemovePolicyTemplateDBAnnotations(plc *unstructured.Unstructured) error {
// Remove the database annotation since this can be an inconsistent value
templates, _, _ := unstructured.NestedSlice(plc.Object, "spec", "policy-templates")

updated := false

for i, template := range templates {
template := template.(map[string]interface{})

annotations, ok, _ := unstructured.NestedMap(
template, "objectDefinition", "metadata", "annotations",
)
if !ok {
continue
}

annotationVal, ok := annotations[propagator.PolicyIDAnnotation].(string)
if !ok {
continue
}

if annotationVal != "" {
delete(annotations, propagator.PolicyIDAnnotation)

if len(annotations) == 0 {
unstructured.RemoveNestedField(template, "objectDefinition", "metadata", "annotations")
} else {
err := unstructured.SetNestedField(
template, annotations, "objectDefinition", "metadata", "annotations",
)
if err != nil {
return err
}
}

templates[i] = template
updated = true
}
}

if updated {
err := unstructured.SetNestedField(plc.Object, templates, "spec", "policy-templates")
if err != nil {
return err
}
}

return nil
}

// Pause sleep for given seconds
func Pause(s uint) {
if s < 1 {
Expand Down

0 comments on commit 13c364d

Please sign in to comment.