mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-10 18:06:55 +00:00
Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com> Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com>
317 lines
12 KiB
Go
317 lines
12 KiB
Go
package generate
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/kyverno/kyverno/test/e2e"
|
|
. "github.com/onsi/gomega"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"sigs.k8s.io/yaml"
|
|
)
|
|
|
|
var (
|
|
// Cluster Policy GVR
|
|
clPolGVR = e2e.GetGVR("kyverno.io", "v1", "clusterpolicies")
|
|
|
|
// Namespace GVR
|
|
nsGVR = e2e.GetGVR("", "v1", "namespaces")
|
|
|
|
// ClusterRole GVR
|
|
crGVR = e2e.GetGVR("rbac.authorization.k8s.io", "v1", "clusterroles")
|
|
|
|
// ClusterRoleBinding GVR
|
|
crbGVR = e2e.GetGVR("rbac.authorization.k8s.io", "v1", "clusterrolebindings")
|
|
|
|
// Role GVR
|
|
rGVR = e2e.GetGVR("rbac.authorization.k8s.io", "v1", "roles")
|
|
|
|
// RoleBinding GVR
|
|
rbGVR = e2e.GetGVR("rbac.authorization.k8s.io", "v1", "rolebindings")
|
|
|
|
// ConfigMap GVR
|
|
cmGVR = e2e.GetGVR("", "v1", "configmaps")
|
|
|
|
// Secret GVR
|
|
secretGVR = e2e.GetGVR("", "v1", "secrets")
|
|
|
|
// NetworkPolicy GVR
|
|
npGVR = e2e.GetGVR("networking.k8s.io", "v1", "networkpolicies")
|
|
)
|
|
|
|
type testCase struct {
|
|
// TestName - Name of the Test
|
|
TestName string
|
|
// ClusterPolicy - ClusterPolicy yaml file
|
|
ClusterPolicy resource
|
|
// SourceResources - Source resources yaml files
|
|
SourceResources []resource
|
|
// TriggerResource - Trigger resource yaml files
|
|
TriggerResource resource
|
|
// ExpectedResources - Expected resources to pass the test
|
|
ExpectedResources []expectedResource
|
|
// Steps - Test case steps
|
|
Steps []testCaseStep
|
|
}
|
|
|
|
// roleTests is E2E Test Config for Role and RoleBinding
|
|
// TODO:- Clone for Role and RoleBinding
|
|
var roleTests = []testCase{
|
|
{
|
|
TestName: "test-role-rolebinding-without-clone",
|
|
ClusterPolicy: clusterPolicy(roleRoleBindingYamlWithSync),
|
|
TriggerResource: namespace(namespaceYaml),
|
|
ExpectedResources: expectations(
|
|
expectation(idRole("test", "ns-role")),
|
|
expectation(idRoleBinding("test", "ns-role-binding")),
|
|
),
|
|
},
|
|
{
|
|
TestName: "test-role-rolebinding-withsync-without-clone",
|
|
ClusterPolicy: clusterPolicy(roleRoleBindingYamlWithSync),
|
|
TriggerResource: namespace(namespaceYaml),
|
|
ExpectedResources: expectations(
|
|
expectation(idRole("test", "ns-role")),
|
|
expectation(idRoleBinding("test", "ns-role-binding")),
|
|
),
|
|
},
|
|
{
|
|
TestName: "test-role-rolebinding-with-clone",
|
|
ClusterPolicy: clusterPolicy(roleRoleBindingYamlWithClone),
|
|
SourceResources: resources(
|
|
role("default", sourceRoleYaml),
|
|
roleBinding("default", sourceRoleBindingYaml),
|
|
),
|
|
TriggerResource: namespace(namespaceYaml),
|
|
ExpectedResources: expectations(
|
|
expectation(idRole("test", "ns-role")),
|
|
expectation(idRoleBinding("test", "ns-role-binding")),
|
|
),
|
|
},
|
|
}
|
|
|
|
// clusterRoleTests - E2E Test Config for ClusterRole and ClusterRoleBinding
|
|
var clusterRoleTests = []testCase{
|
|
{
|
|
TestName: "test-clusterrole-clusterrolebinding-without-clone",
|
|
ClusterPolicy: clusterPolicy(genClusterRoleYamlWithSync),
|
|
TriggerResource: namespace(namespaceYaml),
|
|
ExpectedResources: expectations(
|
|
expectation(idClusterRole("ns-cluster-role")),
|
|
expectation(idClusterRoleBinding("ns-cluster-role-binding")),
|
|
),
|
|
},
|
|
{
|
|
TestName: "test-clusterrole-clusterrolebinding-with-sync-without-clone",
|
|
ClusterPolicy: clusterPolicy(genClusterRoleYamlWithSync),
|
|
TriggerResource: namespace(namespaceYaml),
|
|
ExpectedResources: expectations(
|
|
expectation(idClusterRole("ns-cluster-role")),
|
|
expectation(idClusterRoleBinding("ns-cluster-role-binding")),
|
|
),
|
|
},
|
|
{
|
|
TestName: "test-clusterrole-clusterrolebinding-with-sync-with-clone",
|
|
ClusterPolicy: clusterPolicy(clusterRoleRoleBindingYamlWithClone),
|
|
SourceResources: resources(
|
|
clusterRole(baseClusterRoleData),
|
|
clusterRoleBinding(baseClusterRoleBindingData),
|
|
),
|
|
TriggerResource: namespace(namespaceYaml),
|
|
ExpectedResources: expectations(
|
|
expectation(idClusterRole("cloned-cluster-role")),
|
|
expectation(idClusterRoleBinding("cloned-cluster-role-binding")),
|
|
),
|
|
},
|
|
}
|
|
|
|
// networkPolicyGenerateTests - E2E Test Config for networkPolicyGenerateTests
|
|
var networkPolicyGenerateTests = []testCase{
|
|
{
|
|
TestName: "test-generate-policy-for-namespace-with-label",
|
|
ClusterPolicy: clusterPolicy(genNetworkPolicyYaml),
|
|
TriggerResource: namespace(namespaceWithLabelYaml),
|
|
ExpectedResources: expectations(
|
|
expectation(idNetworkPolicy("test", "allow-dns")),
|
|
),
|
|
},
|
|
}
|
|
|
|
var generateNetworkPolicyOnNamespaceWithoutLabelTests = []testCase{
|
|
{
|
|
TestName: "test-generate-policy-for-namespace-label-actions",
|
|
ClusterPolicy: clusterPolicy(genNetworkPolicyYaml),
|
|
TriggerResource: namespace(namespaceYaml),
|
|
ExpectedResources: expectations(
|
|
expectation(idNetworkPolicy("test", "allow-dns")),
|
|
),
|
|
Steps: []testCaseStep{
|
|
stepResourceNotFound(npGVR, "test", "allow-dns"),
|
|
stepUpateResource(nsGVR, "", "test", func(resource *unstructured.Unstructured) error {
|
|
element, _, err := unstructured.NestedMap(resource.UnstructuredContent(), "metadata", "labels")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
element["security"] = "standard"
|
|
return unstructured.SetNestedMap(resource.UnstructuredContent(), element, "metadata", "labels")
|
|
}),
|
|
stepExpectResource(npGVR, "test", "allow-dns"),
|
|
stepUpateResource(clPolGVR, "", "add-networkpolicy", func(resource *unstructured.Unstructured) error {
|
|
return yaml.Unmarshal(updatGenNetworkPolicyYaml, resource)
|
|
}),
|
|
stepWaitResource(npGVR, "test", "allow-dns", time.Second, 30, func(resource *unstructured.Unstructured) bool {
|
|
element, found, err := unstructured.NestedMap(resource.UnstructuredContent(), "spec")
|
|
if err != nil || !found {
|
|
return false
|
|
}
|
|
return loopElement(false, element)
|
|
}),
|
|
},
|
|
},
|
|
}
|
|
|
|
// NetworkPolicyGenerateTests - E2E Test Config for NetworkPolicyGenerateTests
|
|
var generateSynchronizeFlagTests = []testCase{
|
|
{
|
|
TestName: "test-generate-policy-for-namespace-with-label",
|
|
ClusterPolicy: clusterPolicy(genNetworkPolicyYaml),
|
|
TriggerResource: namespace(namespaceWithLabelYaml),
|
|
// expectation is resource should no longer exists once deleted
|
|
// if sync is set to false
|
|
|
|
Steps: []testCaseStep{
|
|
stepBy("When synchronize flag is set to true in the policy and someone deletes the generated resource, kyverno generates back the resource"),
|
|
stepDeleteResource(npGVR, "test", "allow-dns"),
|
|
stepExpectResource(npGVR, "test", "allow-dns"),
|
|
stepBy("Change synchronize to false in the policy, the label in generated resource should be updated to policy.kyverno.io/synchronize: disable"),
|
|
stepUpateResource(clPolGVR, "", "add-networkpolicy", func(resource *unstructured.Unstructured) error {
|
|
return yaml.Unmarshal(updateSynchronizeInGeneratePolicyYaml, resource)
|
|
}),
|
|
stepWaitResource(npGVR, "test", "allow-dns", time.Second, 30, func(resource *unstructured.Unstructured) bool {
|
|
labels := resource.GetLabels()
|
|
return labels["policy.kyverno.io/synchronize"] == "disable"
|
|
}),
|
|
stepBy("With synchronize is false, one should be able to delete the generated resource"),
|
|
stepDeleteResource(npGVR, "test", "allow-dns"),
|
|
stepResourceNotFound(npGVR, "test", "allow-dns"),
|
|
},
|
|
},
|
|
}
|
|
|
|
// ClusterRoleTests - E2E Test Config for ClusterRole and ClusterRoleBinding
|
|
var sourceResourceUpdateReplicationTests = []testCase{
|
|
{
|
|
TestName: "test-clone-source-resource-update-replication",
|
|
ClusterPolicy: clusterPolicy(genCloneConfigMapPolicyYaml),
|
|
SourceResources: resources(
|
|
configMap("default", cloneSourceResource),
|
|
),
|
|
TriggerResource: namespace(namespaceYaml),
|
|
ExpectedResources: expectations(
|
|
expectation(idConfigMap("test", "game-demo")),
|
|
),
|
|
Steps: []testCaseStep{
|
|
stepBy("When a source clone resource is updated, the same changes should be replicated in the generated resource"),
|
|
stepUpateResource(cmGVR, "default", "game-demo", func(resource *unstructured.Unstructured) error {
|
|
element, _, err := unstructured.NestedMap(resource.UnstructuredContent(), "data")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
element["initial_lives"] = "5"
|
|
return unstructured.SetNestedMap(resource.UnstructuredContent(), element, "data")
|
|
}),
|
|
stepWaitResource(cmGVR, "test", "game-demo", time.Second, 15, func(resource *unstructured.Unstructured) bool {
|
|
element, found, err := unstructured.NestedMap(resource.UnstructuredContent(), "data")
|
|
if err != nil || !found {
|
|
return false
|
|
}
|
|
return element["initial_lives"] == "5"
|
|
}),
|
|
stepBy("When a generated resource is edited with some conflicting changes (with respect to the clone source resource or generate data), kyverno will regenerate the resource"),
|
|
stepUpateResource(cmGVR, "test", "game-demo", func(resource *unstructured.Unstructured) error {
|
|
element, _, err := unstructured.NestedMap(resource.UnstructuredContent(), "data")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
element["initial_lives"] = "15"
|
|
return unstructured.SetNestedMap(resource.UnstructuredContent(), element, "data")
|
|
}),
|
|
stepWaitResource(cmGVR, "test", "game-demo", time.Second, 30, func(resource *unstructured.Unstructured) bool {
|
|
element, found, err := unstructured.NestedMap(resource.UnstructuredContent(), "data")
|
|
if err != nil || !found {
|
|
return false
|
|
}
|
|
return element["initial_lives"] == "5"
|
|
}),
|
|
},
|
|
},
|
|
}
|
|
|
|
var generatePolicyDeletionforCloneTests = []testCase{
|
|
{
|
|
TestName: "test-clone-source-resource-update-replication",
|
|
ClusterPolicy: clusterPolicy(genCloneConfigMapPolicyYaml),
|
|
SourceResources: resources(
|
|
configMap("default", cloneSourceResource),
|
|
),
|
|
TriggerResource: namespace(namespaceYaml),
|
|
ExpectedResources: expectations(
|
|
expectation(idConfigMap("test", "game-demo")),
|
|
),
|
|
Steps: []testCaseStep{
|
|
stepBy("delete policy -> generated resource still exists"),
|
|
stepDeleteResource(clPolGVR, "", "generate-policy"),
|
|
stepExpectResource(cmGVR, "test", "game-demo"),
|
|
stepBy("update source -> generated resource not updated"),
|
|
stepUpateResource(cmGVR, "default", "game-demo", func(resource *unstructured.Unstructured) error {
|
|
element, _, err := unstructured.NestedMap(resource.UnstructuredContent(), "data")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
element["initial_lives"] = "5"
|
|
return unstructured.SetNestedMap(resource.UnstructuredContent(), element, "data")
|
|
}),
|
|
stepExpectResource(cmGVR, "test", "game-demo", func(resource *unstructured.Unstructured) {
|
|
element, _, err := unstructured.NestedMap(resource.UnstructuredContent(), "data")
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(element["initial_lives"]).To(Equal("2"))
|
|
}),
|
|
stepBy("deleted source -> generated resource not deleted"),
|
|
stepDeleteResource(cmGVR, "default", "game-demo"),
|
|
stepExpectResource(cmGVR, "test", "game-demo"),
|
|
},
|
|
},
|
|
}
|
|
|
|
var generatePolicyMultipleCloneTests = []testCase{
|
|
{
|
|
TestName: "test-multiple-clone-resources",
|
|
ClusterPolicy: clusterPolicy(genMultipleClonePolicyYaml),
|
|
SourceResources: resources(
|
|
configMap("default", cloneSourceResource),
|
|
secret("default", cloneSecretSourceResource),
|
|
),
|
|
TriggerResource: namespace(namespaceYaml),
|
|
ExpectedResources: expectations(
|
|
expectation(idConfigMap("test", "game-demo")),
|
|
expectation(idSecret("test", "secret-basic-auth")),
|
|
),
|
|
Steps: []testCaseStep{
|
|
stepExpectResource(cmGVR, "test", "game-demo"),
|
|
stepBy("verify generated resource data in configMap"),
|
|
stepExpectResource(cmGVR, "test", "game-demo", func(resource *unstructured.Unstructured) {
|
|
element, _, err := unstructured.NestedMap(resource.UnstructuredContent(), "data")
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(element["initial_lives"]).To(Equal("2"))
|
|
}),
|
|
|
|
stepBy("verify generated resource data in secret"),
|
|
stepExpectResource(secretGVR, "test", "secret-basic-auth"),
|
|
|
|
stepBy("deleted source -> generated resource not deleted"),
|
|
stepDeleteResource(cmGVR, "default", "game-demo"),
|
|
stepDeleteResource(secretGVR, "default", "secret-basic-auth"),
|
|
stepExpectResource(cmGVR, "test", "game-demo"),
|
|
stepExpectResource(secretGVR, "test", "secret-basic-auth"),
|
|
},
|
|
},
|
|
}
|