mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
1947/e2e generate policy (#1951)
* fixed generate flow Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * added test for generate policy with clone Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * small conflict fix Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * print logs for e2e Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * changing log level Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * added wait while creating policy Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * remove log level from e2e Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * added a clusterpolicy check while creating a namespaced resource in e2e tests Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * updated the github_action name for e2e tests Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * changing waiting time to 1 sec Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * remove log Signed-off-by: Shuting Zhao <shutting06@gmail.com> Co-authored-by: Shuting Zhao <shutting06@gmail.com>
This commit is contained in:
parent
10e23da431
commit
e227636271
5 changed files with 275 additions and 2 deletions
3
.github/workflows/e2e.yaml
vendored
3
.github/workflows/e2e.yaml
vendored
|
@ -1,4 +1,4 @@
|
|||
name: build
|
||||
name: e2e
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
|
@ -82,6 +82,7 @@ jobs:
|
|||
kubectl get pods -n kyverno
|
||||
${GITHUB_WORKSPACE}/scripts/verify-deployment.sh -n kyverno kyverno
|
||||
sleep 20
|
||||
|
||||
echo ">>> Expose the Kyverno's service's metric server to the host"
|
||||
kubectl port-forward svc/kyverno-svc -n kyverno 8000:8000 &
|
||||
echo ">>> Run Kyverno e2e test"
|
||||
|
|
|
@ -232,3 +232,34 @@ var GenerateSynchronizeFlagTests = []struct {
|
|||
UpdateData: updateSynchronizeInGeneratePolicyYaml,
|
||||
},
|
||||
}
|
||||
|
||||
// ClusterRoleTests - E2E Test Config for ClusterRole and ClusterRoleBinding
|
||||
var SourceResourceUpdateReplicationTests = []struct {
|
||||
//TestName - Name of the Test
|
||||
TestName string
|
||||
// ClusterRoleName - Name of the ClusterRole to be Created
|
||||
ResourceNamespace string
|
||||
// Clone - Set Clone Value
|
||||
Clone bool
|
||||
// CloneNamespace - Namespace where Roles are Cloned
|
||||
CloneNamespace string
|
||||
// Sync - Set Synchronize
|
||||
Sync bool
|
||||
// Data - The Yaml file of the ClusterPolicy - ([]byte{})
|
||||
Data []byte
|
||||
// ConfigMapName - name of configMap
|
||||
ConfigMapName string
|
||||
// CloneSourceConfigMapData - Source ConfigMap Yaml
|
||||
CloneSourceConfigMapData []byte
|
||||
}{
|
||||
{
|
||||
TestName: "test-clone-source-resource-update-replication",
|
||||
ResourceNamespace: "test",
|
||||
Clone: true,
|
||||
Sync: true,
|
||||
Data: genCloneConfigMapPolicyYaml,
|
||||
ConfigMapName: "game-demo",
|
||||
CloneNamespace: "default",
|
||||
CloneSourceConfigMapData: cloneSourceResource,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ var (
|
|||
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")
|
||||
// NetworkPolicy GVR
|
||||
npGVR = e2e.GetGVR("networking.k8s.io", "v1", "networkpolicies")
|
||||
|
||||
|
@ -737,3 +739,201 @@ func Test_Generate_Synchronize_Flag(t *testing.T) {
|
|||
By(fmt.Sprintf("Test %s Completed \n\n\n", test.TestName))
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Source_Resource_Update_Replication(t *testing.T) {
|
||||
RegisterTestingT(t)
|
||||
if os.Getenv("E2E") == "" {
|
||||
t.Skip("Skipping E2E Test")
|
||||
}
|
||||
// Generate E2E Client ==================
|
||||
e2eClient, err := e2e.NewE2EClient()
|
||||
Expect(err).To(BeNil())
|
||||
// ======================================
|
||||
|
||||
// ====== Range Over RuleTest ==================
|
||||
for _, tests := range SourceResourceUpdateReplicationTests {
|
||||
By(fmt.Sprintf("Test to check replication of clone source resource: %s", tests.TestName))
|
||||
By(fmt.Sprintf("synchronize = %v\t clone = %v", tests.Sync, tests.Clone))
|
||||
|
||||
// ======= CleanUp Resources =====
|
||||
By("Cleaning Cluster Policies")
|
||||
e2eClient.CleanClusterPolicies(clPolGVR)
|
||||
// Clear Namespace
|
||||
By(fmt.Sprintf("Deleting Namespace : %s", tests.ResourceNamespace))
|
||||
e2eClient.DeleteClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
// If Clone is true Clear Source Resource and Recreate
|
||||
if tests.Clone {
|
||||
By(fmt.Sprintf("Clone = true, Deleting Source Resource from Clone Namespace : %s", tests.CloneNamespace))
|
||||
// Delete ConfigMap to be cloned
|
||||
e2eClient.DeleteNamespacedResource(cmGVR, tests.CloneNamespace, tests.ConfigMapName)
|
||||
}
|
||||
|
||||
// Wait Till Deletion of Namespace
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return errors.New("Deleting Namespace")
|
||||
})
|
||||
// ====================================
|
||||
|
||||
// === If Clone is true Create Source Resources ==
|
||||
if tests.Clone {
|
||||
By(fmt.Sprintf("Clone = true, Creating Cloner Resources in Namespace : %s", tests.CloneNamespace))
|
||||
_, err := e2eClient.CreateNamespacedResourceYaml(cmGVR, tests.CloneNamespace, tests.CloneSourceConfigMapData)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
// ================================================
|
||||
|
||||
// ======== Create Generate Policy =============
|
||||
By(fmt.Sprintf("\nCreating Generate Policy in %s", clPolNS))
|
||||
_, err = e2eClient.CreateNamespacedResourceYaml(clPolGVR, clPolNS, tests.Data)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
// ============================================
|
||||
|
||||
// ======= Create Namespace ==================
|
||||
By(fmt.Sprintf("Creating Namespace which triggers generate %s", clPolNS))
|
||||
_, err = e2eClient.CreateClusteredResourceYaml(nsGVR, namespaceYaml)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// Wait Till Creation of Namespace
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
// ===========================================
|
||||
|
||||
// ======== Verify Configmap Creation =====
|
||||
By(fmt.Sprintf("Verifying Configmap in the Namespace : %s", tests.ResourceNamespace))
|
||||
// Wait Till Creation of Configmap
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetNamespacedResource(cmGVR, tests.ResourceNamespace, tests.ConfigMapName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
// test: when a source clone resource is updated, the same changes should be replicated in the generated resource
|
||||
// ======= Update Configmap in default Namespace ========
|
||||
By(fmt.Sprintf("Updating Source Resource(Configmap) in Clone Namespace : %s", tests.CloneNamespace))
|
||||
|
||||
// Get the configmap from default namespace
|
||||
sourceRes, err := e2eClient.GetNamespacedResource(cmGVR, tests.CloneNamespace, tests.ConfigMapName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(sourceRes.GetName()).To(Equal(tests.ConfigMapName))
|
||||
|
||||
element, _, err := unstructured.NestedMap(sourceRes.UnstructuredContent(), "data")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
element["initial_lives"] = "5"
|
||||
|
||||
unstructured.SetNestedMap(sourceRes.UnstructuredContent(), element, "data")
|
||||
_, err = e2eClient.UpdateNamespacedResource(cmGVR, tests.CloneNamespace, sourceRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
// ============================================
|
||||
|
||||
// ======= Verifying Configmap Data Replication in Namespace ========
|
||||
By(fmt.Sprintf("Verifying Configmap Data Replication in the Namespace : %s", tests.ResourceNamespace))
|
||||
e2e.GetWithRetry(time.Duration(2), 15, func() error {
|
||||
// get updated configmap in test namespace
|
||||
updatedGenRes, err := e2eClient.GetNamespacedResource(cmGVR, tests.ResourceNamespace, tests.ConfigMapName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// compare updated configmapdata
|
||||
element, _, err := unstructured.NestedMap(updatedGenRes.UnstructuredContent(), "data")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if element["initial_lives"] != "5" {
|
||||
return errors.New("not updated")
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
updatedGenRes, err := e2eClient.GetNamespacedResource(cmGVR, tests.ResourceNamespace, tests.ConfigMapName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
element, _, err = unstructured.NestedMap(updatedGenRes.UnstructuredContent(), "data")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(element["initial_lives"]).To(Equal("5"))
|
||||
// ============================================
|
||||
|
||||
// test: 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
|
||||
// ======= Update Configmap in test Namespace ========
|
||||
By(fmt.Sprintf("Updating Generated ConfigMap in Resource Namespace : %s", tests.ResourceNamespace))
|
||||
|
||||
// Get the configmap from test namespace
|
||||
genRes, err := e2eClient.GetNamespacedResource(cmGVR, tests.ResourceNamespace, tests.ConfigMapName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(genRes.GetName()).To(Equal(tests.ConfigMapName))
|
||||
|
||||
element, _, err = unstructured.NestedMap(genRes.UnstructuredContent(), "data")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
element["initial_lives"] = "15"
|
||||
|
||||
unstructured.SetNestedMap(genRes.UnstructuredContent(), element, "data")
|
||||
_, err = e2eClient.UpdateNamespacedResource(cmGVR, tests.ResourceNamespace, genRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
// ============================================
|
||||
|
||||
// ======= Verifying Configmap Data in Namespace ========
|
||||
By(fmt.Sprintf("Verifying Configmap Data in the Namespace : %s", tests.ResourceNamespace))
|
||||
e2e.GetWithRetry(time.Duration(2), 15, func() error {
|
||||
// get updated configmap in test namespace
|
||||
updatedGenRes, err := e2eClient.GetNamespacedResource(cmGVR, tests.ResourceNamespace, tests.ConfigMapName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// compare updated configmapdata
|
||||
element, _, err := unstructured.NestedMap(updatedGenRes.UnstructuredContent(), "data")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if element["initial_lives"] != "5" {
|
||||
return errors.New("not updated")
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
updatedGenRes, err = e2eClient.GetNamespacedResource(cmGVR, tests.ResourceNamespace, tests.ConfigMapName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
element, _, err = unstructured.NestedMap(updatedGenRes.UnstructuredContent(), "data")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(element["initial_lives"]).To(Equal("5"))
|
||||
// ============================================
|
||||
|
||||
// ======= CleanUp Resources =====
|
||||
e2eClient.CleanClusterPolicies(clPolGVR)
|
||||
|
||||
// === If Clone is true Delete Source Resources ==
|
||||
if tests.Clone {
|
||||
By(fmt.Sprintf("Clone = true, Deleting Cloner Resources in Namespace : %s", tests.CloneNamespace))
|
||||
e2eClient.DeleteNamespacedResource(cmGVR, tests.CloneNamespace, tests.ConfigMapName)
|
||||
}
|
||||
// ================================================
|
||||
|
||||
// Clear Namespace
|
||||
e2eClient.DeleteClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
// Wait Till Deletion of Namespace
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return errors.New("Deleting Namespace")
|
||||
})
|
||||
// ====================================
|
||||
|
||||
By(fmt.Sprintf("Test %s Completed \n\n\n", tests.TestName))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -372,3 +372,41 @@ spec:
|
|||
policyTypes:
|
||||
- Egress
|
||||
`)
|
||||
|
||||
var cloneSourceResource = []byte(`
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: game-demo
|
||||
data:
|
||||
initial_lives: "2"
|
||||
`)
|
||||
|
||||
var genCloneConfigMapPolicyYaml = []byte(`
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: generate-policy
|
||||
spec:
|
||||
rules:
|
||||
- name: copy-game-demo
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Namespace
|
||||
exclude:
|
||||
resources:
|
||||
namespaces:
|
||||
- kube-system
|
||||
- default
|
||||
- kube-public
|
||||
- kyverno
|
||||
generate:
|
||||
kind: ConfigMap
|
||||
name: game-demo
|
||||
namespace: "{{request.object.metadata.name}}"
|
||||
synchronize: true
|
||||
clone:
|
||||
namespace: default
|
||||
name: game-demo
|
||||
`)
|
||||
|
|
|
@ -122,6 +122,9 @@ func (e2e *E2EClient) CreateNamespacedResourceYaml(gvr schema.GroupVersionResour
|
|||
return nil, err
|
||||
}
|
||||
result, err := e2e.Client.Resource(gvr).Namespace(namespace).Create(context.TODO(), &resource, metav1.CreateOptions{})
|
||||
if gvr.Resource == "clusterpolicies" {
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
|
@ -163,7 +166,7 @@ func (e2e *E2EClient) UpdateNamespacedResourceYaml(gvr schema.GroupVersionResour
|
|||
return result, err
|
||||
}
|
||||
|
||||
// CreateNamespacedResource ...
|
||||
// UpdateNamespacedResource ...
|
||||
func (e2e *E2EClient) UpdateNamespacedResource(gvr schema.GroupVersionResource, namespace string, resourceData *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
return e2e.Client.Resource(gvr).Namespace(namespace).Update(context.TODO(), resourceData, metav1.UpdateOptions{})
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue