From b70748b1ac975b4573678740c1b2c8bef4eef4d2 Mon Sep 17 00:00:00 2001 From: Yi Rae Kim Date: Fri, 31 Mar 2023 02:33:37 -0400 Subject: [PATCH] Fix status history toggling (#111) Description of problem: When Pod security policy is created and the status is changed from inform to enforce, the status is toggling. Not able to enforce pod security policy. How to fix Set default value when Kube API value omitted ref: https://issues.redhat.com/browse/ACM-3109 Signed-off-by: Yi Rae Kim --- .../configurationpolicy_controller_test.go | 97 +++++++++++ controllers/configurationpolicy_utils.go | 22 ++- controllers/configurationpolicy_utils_test.go | 31 ++++ policy-security.yml | 0 test/e2e/case12_list_compare_test.go | 22 +-- test/e2e/case20_delete_objects_test.go | 3 +- test/e2e/case25_related_object_metric_test.go | 5 +- test/e2e/case26_user_error_metric_test.go | 35 ++-- test/e2e/case28_evauluation_metric_test.go | 1 - test/e2e/case31_policy_history_test.go | 155 ++++++++++++++++++ test/e2e/case8_status_check_test.go | 1 - .../pod-config-policy-number.yaml | 36 ++++ .../pod-config-policy.yaml | 36 ++++ .../pod-policy-number.yaml | 39 +++++ .../case31_policy_history/pod-policy.yaml | 39 +++++ 15 files changed, 484 insertions(+), 38 deletions(-) create mode 100644 policy-security.yml create mode 100644 test/e2e/case31_policy_history_test.go create mode 100644 test/resources/case31_policy_history/pod-config-policy-number.yaml create mode 100644 test/resources/case31_policy_history/pod-config-policy.yaml create mode 100644 test/resources/case31_policy_history/pod-policy-number.yaml create mode 100644 test/resources/case31_policy_history/pod-policy.yaml diff --git a/controllers/configurationpolicy_controller_test.go b/controllers/configurationpolicy_controller_test.go index d68f9dd4..d58f5bf6 100644 --- a/controllers/configurationpolicy_controller_test.go +++ b/controllers/configurationpolicy_controller_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes/scheme" @@ -754,3 +755,99 @@ func TestShouldEvaluatePolicy(t *testing.T) { ) } } + +func TestShouldHandleSingleKeyFalse(t *testing.T) { + t.Parallel() + + var unstruct unstructured.Unstructured + var unstructObj unstructured.Unstructured + + var update, skip bool + + type ExpectResult struct { + key string + expect bool + } + + type TestSingleKey struct { + input map[string]interface{} + fromAPI map[string]interface{} + expectResult ExpectResult + } + + tests := []TestSingleKey{ + { + input: map[string]interface{}{ + "hostIPC": false, + "container": "test", + }, + fromAPI: map[string]interface{}{ + "container": "test", + }, + expectResult: ExpectResult{ + "hostIPC", + false, + }, + }, + { + input: map[string]interface{}{ + "container": map[string]interface{}{ + "image": "nginx1.7.9", + "name": "nginx", + "hostIPC": false, + }, + }, + fromAPI: map[string]interface{}{ + "container": map[string]interface{}{ + "image": "nginx1.7.9", + "name": "nginx", + }, + }, + expectResult: ExpectResult{ + "container", + false, + }, + }, + { + input: map[string]interface{}{ + "hostIPC": true, + "container": "test", + }, + fromAPI: map[string]interface{}{ + "container": "test", + }, + expectResult: ExpectResult{ + "hostIPC", + true, + }, + }, + { + input: map[string]interface{}{ + "container": map[string]interface{}{ + "image": "nginx1.7.9", + "name": "nginx", + "hostIPC": true, + }, + }, + fromAPI: map[string]interface{}{ + "container": map[string]interface{}{ + "image": "nginx1.7.9", + "name": "nginx", + }, + }, + expectResult: ExpectResult{ + "container", + true, + }, + }, + } + + for _, test := range tests { + unstruct.Object = test.input + unstructObj.Object = test.fromAPI + key := test.expectResult.key + _, update, _, skip = handleSingleKey(key, unstruct, &unstructObj, "musthave") + assert.Equal(t, update, test.expectResult.expect) + assert.False(t, skip) + } +} diff --git a/controllers/configurationpolicy_utils.go b/controllers/configurationpolicy_utils.go index da5e4bb6..f4a9179f 100644 --- a/controllers/configurationpolicy_utils.go +++ b/controllers/configurationpolicy_utils.go @@ -119,6 +119,16 @@ func equalObjWithSort(mergedObj interface{}, oldObj interface{}) (areEqual bool) return false } default: + // NOTE: when type is string, int, bool + var oVal interface{} + + if oldObj == nil && mergedObj != nil { + ref := reflect.ValueOf(mergedObj) + oVal = reflect.Zero(ref.Type()).Interface() + + return fmt.Sprint(oVal) == fmt.Sprint(mergedObj) + } + if !reflect.DeepEqual(fmt.Sprint(mergedObj), fmt.Sprint(oldObj)) { return false } @@ -175,8 +185,12 @@ func checkFieldsWithSort(mergedObj map[string]interface{}, oldObj map[string]int // extra check to see if value is a byte value mQty, err := apiRes.ParseQuantity(mVal) if err != nil { + oVal := oldObj[i] + if oVal == nil { + oVal = "" + } // An error indicates the value is a regular string, so check equality normally - if fmt.Sprint(oldObj[i]) != fmt.Sprint(mVal) { + if fmt.Sprint(oVal) != fmt.Sprint(mVal) { return false } } else { @@ -194,6 +208,12 @@ func checkFieldsWithSort(mergedObj map[string]interface{}, oldObj map[string]int default: // if field is not an object, just do a basic compare to check for a match oVal := oldObj[i] + // When oVal value omitted because of omitempty + if oVal == nil && mVal != nil { + ref := reflect.ValueOf(mVal) + oVal = reflect.Zero(ref.Type()).Interface() + } + if fmt.Sprint(oVal) != fmt.Sprint(mVal) { return false } diff --git a/controllers/configurationpolicy_utils_test.go b/controllers/configurationpolicy_utils_test.go index 07b92051..371757fe 100644 --- a/controllers/configurationpolicy_utils_test.go +++ b/controllers/configurationpolicy_utils_test.go @@ -118,3 +118,34 @@ func TestCheckFieldsWithSort(t *testing.T) { assert.True(t, checkFieldsWithSort(mergedObj, oldObj)) } + +func TestEqualObjWithSort(t *testing.T) { + t.Parallel() + + oldObj := map[string]interface{}{ + "nonResourceURLs": []string{"/version", "/healthz"}, + "verbs": []string{"get"}, + } + mergedObj := map[string]interface{}{ + "nonResourceURLs": []string{"/version", "/healthz"}, + "verbs": []string{"get"}, + "apiGroups": []interface{}{}, + "resources": []interface{}{}, + } + + assert.True(t, equalObjWithSort(mergedObj, oldObj)) + assert.False(t, equalObjWithSort(mergedObj, nil)) + + oldObj = map[string]interface{}{ + "nonResourceURLs": []string{"/version", "/healthz"}, + "verbs": []string{"get"}, + } + mergedObj = map[string]interface{}{ + "nonResourceURLs": []string{"/version", "/healthz"}, + "verbs": []string{"post"}, + "apiGroups": []interface{}{}, + "resources": []interface{}{}, + } + + assert.False(t, equalObjWithSort(mergedObj, oldObj)) +} diff --git a/policy-security.yml b/policy-security.yml new file mode 100644 index 00000000..e69de29b diff --git a/test/e2e/case12_list_compare_test.go b/test/e2e/case12_list_compare_test.go index 301e785a..e0bcae5b 100644 --- a/test/e2e/case12_list_compare_test.go +++ b/test/e2e/case12_list_compare_test.go @@ -356,7 +356,17 @@ var _ = Describe("Test list handling for musthave", func() { deleteConfigPolicies(policies) }) }) - Describe("Create a statefulset object with a byte quantity field on managed cluster in ns:"+testNamespace, func() { + Describe("Create a statefulset object with a byte quantity field "+ + "on managed cluster in ns:"+testNamespace, Ordered, func() { + cleanup := func() { + // Delete the policies and ignore any errors (in case it was deleted previously) + policies := []string{ + case12ByteCreate, + case12ByteInform, + } + + deleteConfigPolicies(policies) + } It("should only add the list item with the rounded byte value once", func() { By("Creating " + case12ByteCreate + " and " + case12ByteInform + " on managed") utils.Kubectl("apply", "-f", case12ByteCreateYaml, "-n", testNamespace) @@ -389,14 +399,6 @@ var _ = Describe("Test list handling for musthave", func() { return utils.GetComplianceState(managedPlc) }, defaultTimeoutSeconds, 1).Should(Equal("Compliant")) }) - - It("Cleans up", func() { - policies := []string{ - case12ByteCreate, - case12ByteInform, - } - - deleteConfigPolicies(policies) - }) + AfterAll(cleanup) }) }) diff --git a/test/e2e/case20_delete_objects_test.go b/test/e2e/case20_delete_objects_test.go index 2115a06a..6a01a26c 100644 --- a/test/e2e/case20_delete_objects_test.go +++ b/test/e2e/case20_delete_objects_test.go @@ -527,7 +527,8 @@ var _ = Describe("Test objects that should be deleted are actually being deleted return nil }, defaultTimeoutSeconds, 1).Should(BeNil()) }) - It("deletes the pod after the policy is deleted", func() { + AfterAll(func() { + By("deletes the pod after the policy is deleted") deleteConfigPolicies([]string{case20ConfigPolicyNameCreate}) Eventually(func() interface{} { pod := utils.GetWithTimeout(clientManagedDynamic, gvrPod, diff --git a/test/e2e/case25_related_object_metric_test.go b/test/e2e/case25_related_object_metric_test.go index b455eed1..a263e045 100644 --- a/test/e2e/case25_related_object_metric_test.go +++ b/test/e2e/case25_related_object_metric_test.go @@ -56,7 +56,7 @@ var _ = Describe("Test related object metrics", Ordered, func() { // Delete the policies and ignore any errors (in case it was deleted previously) cmd := exec.Command("kubectl", "delete", "-f", policyYaml, - "-n", testNamespace) + "-n", testNamespace, "--ignore-not-found") _, _ = cmd.CombinedOutput() opt := metav1.ListOptions{} utils.ListWithTimeout( @@ -66,13 +66,10 @@ var _ = Describe("Test related object metrics", Ordered, func() { } It("should clean up", cleanup) - It("should have no common related object metrics after clean up", func() { By("Checking metric endpoint for related object gauges") Eventually(func() interface{} { return utils.GetMetrics("common_related_objects") }, defaultTimeoutSeconds, 1).Should(Equal([]string{})) }) - - AfterAll(cleanup) }) diff --git a/test/e2e/case26_user_error_metric_test.go b/test/e2e/case26_user_error_metric_test.go index 594c3880..344a5567 100644 --- a/test/e2e/case26_user_error_metric_test.go +++ b/test/e2e/case26_user_error_metric_test.go @@ -15,6 +15,21 @@ var _ = Describe("Test related object metrics", Ordered, func() { policy1Name = "case26-test-policy-1" policyYaml = "../resources/case26_user_error_metric/case26-missing-crd.yaml" ) + cleanup := func() { + // Delete the policies and ignore any errors (in case it was deleted previously) + cmd := exec.Command("kubectl", "delete", + "-f", policyYaml, + "-n", testNamespace, "--ignore-not-found") + _, _ = cmd.CombinedOutput() + opt := metav1.ListOptions{} + utils.ListWithTimeout( + clientManagedDynamic, gvrConfigPolicy, opt, 0, false, defaultTimeoutSeconds) + By("Checking metric endpoint for related object gauges") + Eventually(func() interface{} { + return utils.GetMetrics("policy_user_errors") + }, defaultTimeoutSeconds, 1).Should(Equal([]string{})) + } + It("should create policy", func() { By("Creating " + policyYaml) utils.Kubectl("apply", @@ -36,25 +51,5 @@ var _ = Describe("Test related object metrics", Ordered, func() { }, defaultTimeoutSeconds, 1).Should(Equal([]string{"policies", "counter", "1"})) }) - cleanup := func() { - // Delete the policies and ignore any errors (in case it was deleted previously) - cmd := exec.Command("kubectl", "delete", - "-f", policyYaml, - "-n", testNamespace) - _, _ = cmd.CombinedOutput() - opt := metav1.ListOptions{} - utils.ListWithTimeout( - clientManagedDynamic, gvrConfigPolicy, opt, 0, false, defaultTimeoutSeconds) - } - - It("should clean up", cleanup) - - It("should have no common related object metrics after clean up", func() { - By("Checking metric endpoint for related object gauges") - Eventually(func() interface{} { - return utils.GetMetrics("policy_user_errors") - }, defaultTimeoutSeconds, 1).Should(Equal([]string{})) - }) - AfterAll(cleanup) }) diff --git a/test/e2e/case28_evauluation_metric_test.go b/test/e2e/case28_evauluation_metric_test.go index cc32f789..f4ba2d76 100644 --- a/test/e2e/case28_evauluation_metric_test.go +++ b/test/e2e/case28_evauluation_metric_test.go @@ -102,7 +102,6 @@ var _ = Describe("Test config policy evaluation metrics", Ordered, func() { opt := metav1.ListOptions{} utils.ListWithTimeout( clientManagedDynamic, gvrConfigPolicy, opt, 0, false, defaultTimeoutSeconds) - Eventually(func() interface{} { return utils.GetMetrics( "config_policy_evaluation_total", fmt.Sprintf(`name=\"%s\"`, policyName)) diff --git a/test/e2e/case31_policy_history_test.go b/test/e2e/case31_policy_history_test.go new file mode 100644 index 00000000..e83a19f5 --- /dev/null +++ b/test/e2e/case31_policy_history_test.go @@ -0,0 +1,155 @@ +// Copyright (c) 2021 Red Hat, Inc. +// Copyright Contributors to the Open Cluster Management project + +package e2e + +import ( + "context" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "open-cluster-management.io/config-policy-controller/test/utils" +) + +const ( + case31Policy = "../resources/case31_policy_history/pod-policy.yaml" + case31ConfigPolicy = "../resources/case31_policy_history/pod-config-policy.yaml" + case31PolicyName = "test-policy-security" + case31ConfigPolicyName = "config-policy-pod" + case31PolicyNumber = "../resources/case31_policy_history/pod-policy-number.yaml" + case31ConfigPolicyNumber = "../resources/case31_policy_history/pod-config-policy-number.yaml" + case31PolicyNumberName = "test-policy-security-number" + case31ConfigPolicyNumberName = "config-policy-pod-number" +) + +var _ = Describe("Test policy history message when KubeAPI return "+ + "omits values in the returned object", Ordered, func() { + Describe("status toggling should not be generated When Policy include default value,", Ordered, func() { + It("creates the policyconfiguration "+case31Policy, func() { + utils.Kubectl("apply", "-f", case31Policy, "-n", "managed") + }) + + It("verifies the policy "+case31PolicyName+" in "+testNamespace, func() { + By("bind policy and configurationpolicy") + parent := utils.GetWithTimeout(clientManagedDynamic, gvrPolicy, + case31PolicyName, testNamespace, true, defaultTimeoutSeconds) + Expect(parent).NotTo(BeNil()) + + plcDef := utils.ParseYaml(case31ConfigPolicy) + ownerRefs := plcDef.GetOwnerReferences() + ownerRefs[0].UID = parent.GetUID() + plcDef.SetOwnerReferences(ownerRefs) + _, err := clientManagedDynamic.Resource(gvrConfigPolicy).Namespace(testNamespace). + Create(context.TODO(), plcDef, metav1.CreateOptions{}) + Expect(err).To(BeNil()) + + By("check configurationpolicy exist") + plc := utils.GetWithTimeout(clientManagedDynamic, gvrConfigPolicy, + case31ConfigPolicyName, testNamespace, true, defaultTimeoutSeconds) + Expect(plc).NotTo(BeNil()) + }) + + It("check history toggling", func() { + By("wait until pod is up") + Eventually(func() interface{} { + managedPlc := utils.GetWithTimeout(clientManagedDynamic, gvrConfigPolicy, + case31ConfigPolicyName, testNamespace, true, defaultTimeoutSeconds) + + return utils.GetComplianceState(managedPlc) + }, defaultTimeoutSeconds, 1).Should(Equal("Compliant")) + + By("check events") + Consistently(func() int { + eventlen := len(utils.GetMatchingEvents(clientManaged, testNamespace, + case31ConfigPolicyName, case31ConfigPolicyName, "NonCompliant;", defaultTimeoutSeconds)) + + return eventlen + }, 30, 5).Should(BeNumerically("<", 2)) + + Consistently(func() int { + eventlen := len(utils.GetMatchingEvents(clientManaged, testNamespace, + case31PolicyName, case31ConfigPolicyName, "NonCompliant;", defaultTimeoutSeconds)) + + return eventlen + }, 30, 5).Should(BeNumerically("<", 3)) + }) + AfterAll(func() { + utils.Kubectl("delete", "policy", case31PolicyName, "-n", + "managed", "--ignore-not-found") + configlPlc := utils.GetWithTimeout(clientManagedDynamic, gvrConfigPolicy, + case31ConfigPolicyName, "managed", false, defaultTimeoutSeconds, + ) + utils.Kubectl("delete", "event", + "--field-selector=involvedObject.name="+case31PolicyName, "-n", "managed") + utils.Kubectl("delete", "event", + "--field-selector=involvedObject.name="+case31ConfigPolicyName, "-n", "managed") + ExpectWithOffset(1, configlPlc).To(BeNil()) + }) + }) + Describe("status should not toggle When Policy include default value of number", Ordered, func() { + It("creates the policyconfiguration "+case31PolicyNumber, func() { + utils.Kubectl("apply", "-f", case31PolicyNumber, "-n", "managed") + }) + + It("verifies the policy "+case31PolicyNumberName+" in "+testNamespace, func() { + By("bind policy and configurationpolicy") + parent := utils.GetWithTimeout(clientManagedDynamic, gvrPolicy, + case31PolicyNumberName, testNamespace, true, defaultTimeoutSeconds) + Expect(parent).NotTo(BeNil()) + + plcDef := utils.ParseYaml(case31ConfigPolicyNumber) + ownerRefs := plcDef.GetOwnerReferences() + ownerRefs[0].UID = parent.GetUID() + plcDef.SetOwnerReferences(ownerRefs) + _, err := clientManagedDynamic.Resource(gvrConfigPolicy).Namespace(testNamespace). + Create(context.TODO(), plcDef, metav1.CreateOptions{}) + Expect(err).To(BeNil()) + + By("check configurationpolicy exist") + plc := utils.GetWithTimeout(clientManagedDynamic, gvrConfigPolicy, + case31ConfigPolicyNumberName, testNamespace, true, defaultTimeoutSeconds) + Expect(plc).NotTo(BeNil()) + }) + + It("check history toggling", func() { + By("wait until pod is up") + Eventually(func() interface{} { + managedPlc := utils.GetWithTimeout(clientManagedDynamic, gvrConfigPolicy, + case31ConfigPolicyNumberName, testNamespace, true, defaultTimeoutSeconds) + + return utils.GetComplianceState(managedPlc) + }, defaultTimeoutSeconds, 1).Should(Equal("Compliant")) + + By("check events") + Consistently(func() int { + eventLen := len(utils.GetMatchingEvents(clientManaged, testNamespace, case31ConfigPolicyNumberName, + case31ConfigPolicyNumberName, "NonCompliant;", defaultTimeoutSeconds)) + + return eventLen + }, 30, 5).Should(BeNumerically("<", 2)) + + // NOTE: pick policy event, these event's reason include ConfigPolicyName + Consistently(func() int { + eventLen := len(utils.GetMatchingEvents(clientManaged, testNamespace, + case31PolicyNumberName, case31ConfigPolicyNumberName, "NonCompliant;", defaultTimeoutSeconds)) + + return eventLen + }, 30, 5).Should(BeNumerically("<", 3)) + }) + AfterAll(func() { + utils.Kubectl("delete", "policy", case31PolicyNumberName, "-n", + "managed", "--ignore-not-found") + configlPlc := utils.GetWithTimeout(clientManagedDynamic, gvrConfigPolicy, + case31ConfigPolicyName, "managed", false, defaultTimeoutSeconds, + ) + utils.Kubectl("delete", "event", + "--field-selector=involvedObject.name="+case31PolicyNumberName, "-n", "managed") + utils.Kubectl("delete", "event", + "--field-selector=involvedObject.name="+case31ConfigPolicyNumberName, "-n", "managed") + + ExpectWithOffset(1, configlPlc).To(BeNil()) + }) + }) +}) diff --git a/test/e2e/case8_status_check_test.go b/test/e2e/case8_status_check_test.go index 4ac3993e..1e41fd99 100644 --- a/test/e2e/case8_status_check_test.go +++ b/test/e2e/case8_status_check_test.go @@ -144,7 +144,6 @@ var _ = Describe("Test pod obj template handling", func() { policies := []string{ case8ConfigPolicyStatusPod, } - deleteConfigPolicies(policies) }) }) diff --git a/test/resources/case31_policy_history/pod-config-policy-number.yaml b/test/resources/case31_policy_history/pod-config-policy-number.yaml new file mode 100644 index 00000000..b12f1f5c --- /dev/null +++ b/test/resources/case31_policy_history/pod-config-policy-number.yaml @@ -0,0 +1,36 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: ConfigurationPolicy +metadata: + name: config-policy-pod-number + labels: + policy.open-cluster-management.io/policy: test-policy-security + ownerReferences: + - apiVersion: policy.open-cluster-management.io/v1 + blockOwnerDeletion: false + controller: true + kind: Policy + name: test-policy-security-number + uid: 08bae967-4262-498a-84e9-d1f0e321b41e +spec: + pruneObjectBehavior: DeleteAll + remediationAction: enforce + namespaceSelector: + exclude: + - kube-* + include: + - default + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Pod + metadata: + name: case31-pod-policy-number + spec: + priority: 0 + containers: + - image: nginx:1.7.9 + imagePullPolicy: Never + name: nginx + ports: + - containerPort: 80 \ No newline at end of file diff --git a/test/resources/case31_policy_history/pod-config-policy.yaml b/test/resources/case31_policy_history/pod-config-policy.yaml new file mode 100644 index 00000000..4b51897c --- /dev/null +++ b/test/resources/case31_policy_history/pod-config-policy.yaml @@ -0,0 +1,36 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: ConfigurationPolicy +metadata: + name: config-policy-pod + labels: + policy.open-cluster-management.io/policy: test-policy-security + ownerReferences: + - apiVersion: policy.open-cluster-management.io/v1 + blockOwnerDeletion: false + controller: true + kind: Policy + name: test-policy-security + uid: 08bae967-4262-498a-84e9-d1f0e321b41e +spec: + pruneObjectBehavior: DeleteAll + remediationAction: enforce + namespaceSelector: + exclude: + - kube-* + include: + - default + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Pod + metadata: + name: case31-pod-policy + spec: + hostIPC: false + containers: + - image: nginx:1.7.9 + imagePullPolicy: Never + name: nginx + ports: + - containerPort: 80 \ No newline at end of file diff --git a/test/resources/case31_policy_history/pod-policy-number.yaml b/test/resources/case31_policy_history/pod-policy-number.yaml new file mode 100644 index 00000000..5e2e4e6a --- /dev/null +++ b/test/resources/case31_policy_history/pod-policy-number.yaml @@ -0,0 +1,39 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: Policy +metadata: + name: test-policy-security-number + annotations: + policy.open-cluster.management.io/standards: NIST-CSF + policy.open-cluster.management.io/categories: PR.PT Protective Technology + policy.open-cluster.management.io/controls: PR.PT-3 Least Functionality +spec: + remediationAction: enforce + disabled: false + policy-templates: + - objectDefinition: + apiVersion: policy.open-cluster-management.io/v1 + kind: ConfigurationPolicy + metadata: + name: config-policy-pod-number + spec: + remediationAction: enforce + namespaceSelector: + exclude: + - kube-* + include: + - default + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Pod + metadata: + name: case31-pod-policy-number + spec: + priority: 0 + containers: + - image: nginx:1.7.9 + imagePullPolicy: Never + name: nginx + ports: + - containerPort: 80 \ No newline at end of file diff --git a/test/resources/case31_policy_history/pod-policy.yaml b/test/resources/case31_policy_history/pod-policy.yaml new file mode 100644 index 00000000..362c3530 --- /dev/null +++ b/test/resources/case31_policy_history/pod-policy.yaml @@ -0,0 +1,39 @@ +apiVersion: policy.open-cluster-management.io/v1 +kind: Policy +metadata: + name: test-policy-security + annotations: + policy.open-cluster.management.io/standards: NIST-CSF + policy.open-cluster.management.io/categories: PR.PT Protective Technology + policy.open-cluster.management.io/controls: PR.PT-3 Least Functionality +spec: + remediationAction: enforce + disabled: false + policy-templates: + - objectDefinition: + apiVersion: policy.open-cluster-management.io/v1 + kind: ConfigurationPolicy + metadata: + name: config-policy-pod + spec: + remediationAction: enforce + namespaceSelector: + exclude: + - kube-* + include: + - default + object-templates: + - complianceType: musthave + objectDefinition: + apiVersion: v1 + kind: Pod + metadata: + name: case31-pod-policy + spec: + hostIPC: false + containers: + - image: nginx:1.7.9 + imagePullPolicy: Never + name: nginx + ports: + - containerPort: 80 \ No newline at end of file