mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
Add e2e test for mutation (#1761)
Signed-off-by: MarcelMue <marcel.mueller1@rwth-aachen.de> Signed-off-by: Marcel Mueller <marcel.mueller1@rwth-aachen.de>
This commit is contained in:
parent
f3ca1d78f1
commit
9a6f7043b0
6 changed files with 242 additions and 27 deletions
17
Makefile
17
Makefile
|
@ -35,7 +35,7 @@ build: kyverno
|
|||
PWD := $(CURDIR)
|
||||
|
||||
##################################
|
||||
# INIT CONTAINER
|
||||
# INIT CONTAINER
|
||||
##################################
|
||||
INITC_PATH := cmd/initContainer
|
||||
INITC_IMAGE := kyvernopre
|
||||
|
@ -117,7 +117,7 @@ docker-build-cli-amd64:
|
|||
docker-push-cli:
|
||||
@docker buildx build --file $(PWD)/$(CLI_PATH)/Dockerfile --progress plane --push --platform linux/arm64,linux/amd64 --tag $(REPO)/$(KYVERNO_CLI_IMAGE):$(IMAGE_TAG) . --build-arg LD_FLAGS=$(LD_FLAGS)
|
||||
@docker buildx build --file $(PWD)/$(CLI_PATH)/Dockerfile --progress plane --push --platform linux/arm64,linux/amd64 --tag $(REPO)/$(KYVERNO_CLI_IMAGE):latest . --build-arg LD_FLAGS=$(LD_FLAGS)
|
||||
|
||||
|
||||
##################################
|
||||
docker-publish-all: docker-publish-initContainer docker-publish-kyverno docker-publish-cli
|
||||
|
||||
|
@ -137,7 +137,7 @@ create-e2e-infrastruture:
|
|||
##################################
|
||||
|
||||
##################################
|
||||
# Testing & Code-Coverage
|
||||
# Testing & Code-Coverage
|
||||
##################################
|
||||
|
||||
## variables
|
||||
|
@ -153,7 +153,7 @@ $(GO_ACC):
|
|||
go get -v github.com/ory/go-acc
|
||||
$(eval export PATH=$(GO_ACC):$(PATH))
|
||||
# go test provides code coverage per packages only.
|
||||
# go-acc merges the result for pks so that it be used by
|
||||
# go-acc merges the result for pks so that it be used by
|
||||
# go tool cover for reporting
|
||||
|
||||
# go get downloads and installs the binary
|
||||
|
@ -171,7 +171,8 @@ code-cov-report: $(CODE_COVERAGE_FILE_TXT)
|
|||
# Test E2E
|
||||
test-e2e:
|
||||
$(eval export E2E="ok")
|
||||
go test ./test/e2e/... -v
|
||||
go test ./test/e2e/mutate -v
|
||||
go test ./test/e2e/generate -v
|
||||
$(eval export E2E="")
|
||||
|
||||
#Test TestCmd Policy
|
||||
|
@ -183,9 +184,9 @@ run_testcmd_policy:
|
|||
godownloader:
|
||||
godownloader .goreleaser.yml --repo kyverno/kyverno -o ./scripts/install-cli.sh --source="raw"
|
||||
|
||||
# kustomize-crd will create install.yaml
|
||||
# kustomize-crd will create install.yaml
|
||||
kustomize-crd:
|
||||
# Create CRD for helm deployment Helm
|
||||
# Create CRD for helm deployment Helm
|
||||
kustomize build ./definitions/crds > ./charts/kyverno/crds/crds.yaml
|
||||
# Generate install.yaml that have all resources for kyverno
|
||||
kustomize build ./definitions > ./definitions/install.yaml
|
||||
|
@ -204,7 +205,7 @@ kyverno-crd: controller-gen
|
|||
report-crd: controller-gen
|
||||
$(CONTROLLER_GEN) crd paths=./pkg/api/policyreport/v1alpha1 output:dir=./definitions/crds
|
||||
|
||||
# install the right version of controller-gen
|
||||
# install the right version of controller-gen
|
||||
install-controller-gen:
|
||||
@{ \
|
||||
set -e ;\
|
||||
|
|
|
@ -3,26 +3,29 @@ package generate
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/kyverno/kyverno/test/e2e"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var (
|
||||
// Cluster Polict GVR
|
||||
clPolGVR = GetGVR("kyverno.io", "v1", "clusterpolicies")
|
||||
clPolGVR = e2e.GetGVR("kyverno.io", "v1", "clusterpolicies")
|
||||
// Namespace GVR
|
||||
nsGVR = GetGVR("", "v1", "namespaces")
|
||||
nsGVR = e2e.GetGVR("", "v1", "namespaces")
|
||||
// ClusterRole GVR
|
||||
crGVR = GetGVR("rbac.authorization.k8s.io", "v1", "clusterroles")
|
||||
crGVR = e2e.GetGVR("rbac.authorization.k8s.io", "v1", "clusterroles")
|
||||
// ClusterRoleBinding GVR
|
||||
crbGVR = GetGVR("rbac.authorization.k8s.io", "v1", "clusterrolebindings")
|
||||
crbGVR = e2e.GetGVR("rbac.authorization.k8s.io", "v1", "clusterrolebindings")
|
||||
// Role GVR
|
||||
rGVR = GetGVR("rbac.authorization.k8s.io", "v1", "roles")
|
||||
rGVR = e2e.GetGVR("rbac.authorization.k8s.io", "v1", "roles")
|
||||
// RoleBinding GVR
|
||||
rbGVR = GetGVR("rbac.authorization.k8s.io", "v1", "rolebindings")
|
||||
rbGVR = e2e.GetGVR("rbac.authorization.k8s.io", "v1", "rolebindings")
|
||||
|
||||
// ClusterPolicy Namespace
|
||||
clPolNS = ""
|
||||
|
@ -37,7 +40,7 @@ func Test_ClusterRole_ClusterRoleBinding_Sets(t *testing.T) {
|
|||
t.Skip("Skipping E2E Test")
|
||||
}
|
||||
// Generate E2E Client ==================
|
||||
e2eClient, err := NewE2EClient()
|
||||
e2eClient, err := e2e.NewE2EClient()
|
||||
Expect(err).To(BeNil())
|
||||
// ======================================
|
||||
|
||||
|
@ -65,7 +68,7 @@ func Test_ClusterRole_ClusterRoleBinding_Sets(t *testing.T) {
|
|||
e2eClient.DeleteClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
|
||||
// Wait Till Deletion of Namespace
|
||||
GetWithRetry(time.Duration(1), 15, func() error {
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
if err != nil {
|
||||
return nil
|
||||
|
@ -100,7 +103,7 @@ func Test_ClusterRole_ClusterRoleBinding_Sets(t *testing.T) {
|
|||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// Wait Till Creation of Namespace
|
||||
GetWithRetry(time.Duration(1), 15, func() error {
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -112,7 +115,7 @@ func Test_ClusterRole_ClusterRoleBinding_Sets(t *testing.T) {
|
|||
// ======== Verify ClusterRole Creation =====
|
||||
By("Verifying ClusterRole")
|
||||
// Wait Till Creation of ClusterRole
|
||||
GetWithRetry(time.Duration(1), 15, func() error {
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetClusteredResource(crGVR, tests.ClusterRoleName)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -136,7 +139,7 @@ func Test_ClusterRole_ClusterRoleBinding_Sets(t *testing.T) {
|
|||
// Clear Namespace
|
||||
e2eClient.DeleteClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
// Wait Till Deletion of Namespace
|
||||
GetWithRetry(time.Duration(1), 15, func() error {
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
if err != nil {
|
||||
return nil
|
||||
|
@ -154,7 +157,7 @@ func Test_Role_RoleBinding_Sets(t *testing.T) {
|
|||
t.Skip("Skipping E2E Test")
|
||||
}
|
||||
// Generate E2E Client ==================
|
||||
e2eClient, err := NewE2EClient()
|
||||
e2eClient, err := e2e.NewE2EClient()
|
||||
Expect(err).To(BeNil())
|
||||
// ======================================
|
||||
|
||||
|
@ -179,7 +182,7 @@ func Test_Role_RoleBinding_Sets(t *testing.T) {
|
|||
}
|
||||
|
||||
// Wait Till Deletion of Namespace
|
||||
GetWithRetry(time.Duration(1), 15, func() error {
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
if err != nil {
|
||||
return nil
|
||||
|
@ -210,7 +213,7 @@ func Test_Role_RoleBinding_Sets(t *testing.T) {
|
|||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// Wait Till Creation of Namespace
|
||||
GetWithRetry(time.Duration(1), 15, func() error {
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -222,7 +225,7 @@ func Test_Role_RoleBinding_Sets(t *testing.T) {
|
|||
// ======== Verify Role Creation =====
|
||||
By(fmt.Sprintf("Verifying Role in the Namespace : %s", tests.ResourceNamespace))
|
||||
// Wait Till Creation of Role
|
||||
GetWithRetry(time.Duration(1), 15, func() error {
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetNamespacedResource(rGVR, tests.ResourceNamespace, tests.RoleName)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -255,7 +258,7 @@ func Test_Role_RoleBinding_Sets(t *testing.T) {
|
|||
// Clear Namespace
|
||||
e2eClient.DeleteClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
// Wait Till Deletion of Namespace
|
||||
GetWithRetry(time.Duration(1), 15, func() error {
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetClusteredResource(nsGVR, tests.ResourceNamespace)
|
||||
if err != nil {
|
||||
return nil
|
||||
|
|
18
test/e2e/mutate/config.go
Normal file
18
test/e2e/mutate/config.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package mutate
|
||||
|
||||
// MutateTests is E2E Test Config for mutation
|
||||
var MutateTests = []struct {
|
||||
//TestName - Name of the Test
|
||||
TestName string
|
||||
// Data - The Yaml file of the ClusterPolicy
|
||||
Data []byte
|
||||
}{
|
||||
{
|
||||
TestName: "test-mutate-with-context",
|
||||
Data: configMapMutationYaml,
|
||||
},
|
||||
{
|
||||
TestName: "test-mutate-with-logic-in-context",
|
||||
Data: configMapMutationWithContextLogicYaml,
|
||||
},
|
||||
}
|
109
test/e2e/mutate/mutate_test.go
Normal file
109
test/e2e/mutate/mutate_test.go
Normal file
|
@ -0,0 +1,109 @@
|
|||
package mutate
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/kyverno/kyverno/test/e2e"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var (
|
||||
// Cluster Polict GVR
|
||||
clPolGVR = e2e.GetGVR("kyverno.io", "v1", "clusterpolicies")
|
||||
// Namespace GVR
|
||||
nsGVR = e2e.GetGVR("", "v1", "namespaces")
|
||||
// ConfigMap GVR
|
||||
cmGVR = e2e.GetGVR("", "v1", "configmaps")
|
||||
|
||||
// ClusterPolicy Namespace
|
||||
clPolNS = ""
|
||||
// Namespace Name
|
||||
// Hardcoded in YAML Definition
|
||||
nspace = "test-mutate"
|
||||
)
|
||||
|
||||
func Test_Mutate_Sets(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())
|
||||
|
||||
for _, tests := range MutateTests {
|
||||
By(fmt.Sprintf("Test to mutate objects : %s", tests.TestName))
|
||||
|
||||
// Clean up Resources
|
||||
By(fmt.Sprintf("Cleaning Cluster Policies"))
|
||||
e2eClient.CleanClusterPolicies(clPolGVR)
|
||||
// Clear Namespace
|
||||
By(fmt.Sprintf("Deleting Namespace : %s", nspace))
|
||||
e2eClient.DeleteClusteredResource(nsGVR, nspace)
|
||||
|
||||
// Wait Till Deletion of Namespace
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetClusteredResource(nsGVR, nspace)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return errors.New("Deleting Namespace")
|
||||
})
|
||||
|
||||
// Create Namespace
|
||||
By(fmt.Sprintf("Creating Namespace %s", clPolNS))
|
||||
_, err = e2eClient.CreateClusteredResourceYaml(nsGVR, namespaceYaml)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// Create source CM
|
||||
By(fmt.Sprintf("\nCreating source ConfigMap in %s", nspace))
|
||||
_, err = e2eClient.CreateNamespacedResourceYaml(cmGVR, nspace, sourceConfigMapYaml)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// Create CM Policy
|
||||
By(fmt.Sprintf("\nCreating Mutate ConfigMap Policy in %s", clPolNS))
|
||||
_, err = e2eClient.CreateNamespacedResourceYaml(clPolGVR, clPolNS, tests.Data)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// Create target CM
|
||||
By(fmt.Sprintf("\nCreating target ConfigMap in %s", nspace))
|
||||
_, err = e2eClient.CreateNamespacedResourceYaml(cmGVR, nspace, targetConfigMapYaml)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// Verify created ConfigMap
|
||||
By(fmt.Sprintf("Verifying ConfigMap in the Namespace : %s", nspace))
|
||||
// Wait Till Creation of ConfigMap
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetNamespacedResource(cmGVR, nspace, "target")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
cmRes, err := e2eClient.GetNamespacedResource(cmGVR, nspace, "target")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(cmRes.GetLabels()["kyverno.key/copy-me"]).To(Equal("sample-value"))
|
||||
|
||||
//CleanUp Resources
|
||||
e2eClient.CleanClusterPolicies(clPolGVR)
|
||||
|
||||
// Clear Namespace
|
||||
e2eClient.DeleteClusteredResource(nsGVR, nspace)
|
||||
// Wait Till Deletion of Namespace
|
||||
e2e.GetWithRetry(time.Duration(1), 15, func() error {
|
||||
_, err := e2eClient.GetClusteredResource(nsGVR, nspace)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return errors.New("Deleting Namespace")
|
||||
})
|
||||
|
||||
By(fmt.Sprintf("Test %s Completed \n\n\n", tests.TestName))
|
||||
}
|
||||
|
||||
}
|
84
test/e2e/mutate/resources.go
Normal file
84
test/e2e/mutate/resources.go
Normal file
|
@ -0,0 +1,84 @@
|
|||
package mutate
|
||||
|
||||
// Namespace Description
|
||||
var namespaceYaml = []byte(`
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: test-mutate
|
||||
`)
|
||||
|
||||
// Cluster Policy to copy the copy me label from one configmap to the target
|
||||
var configMapMutationYaml = []byte(`
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: "mutate-policy"
|
||||
spec:
|
||||
rules:
|
||||
- name: "gen-role"
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- ConfigMap
|
||||
context:
|
||||
- name: labelValue
|
||||
apiCall:
|
||||
urlPath: "/api/v1/namespaces/{{ request.object.metadata.namespace }}/configmaps"
|
||||
jmesPath: "items[*]"
|
||||
mutate:
|
||||
patchStrategicMerge:
|
||||
metadata:
|
||||
labels:
|
||||
+(kyverno.key/copy-me): "{{ labelValue[?metadata.name == 'source'].metadata.labels.\"kyverno.key/copy-me\" | [0] }}"
|
||||
`)
|
||||
|
||||
var configMapMutationWithContextLogicYaml = []byte(`
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: "mutate-policy"
|
||||
spec:
|
||||
rules:
|
||||
- name: "gen-role"
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- ConfigMap
|
||||
context:
|
||||
- name: labelValue
|
||||
apiCall:
|
||||
urlPath: "/api/v1/namespaces/{{ request.object.metadata.namespace }}/configmaps"
|
||||
jmesPath: "items[?metadata.name == 'source'].metadata.labels.\"kyverno.key/copy-me\" | [0]"
|
||||
mutate:
|
||||
patchStrategicMerge:
|
||||
metadata:
|
||||
labels:
|
||||
+(kyverno.key/copy-me): "{{ labelValue }}"
|
||||
`)
|
||||
|
||||
// Source ConfigMap from which data is taken to copy
|
||||
var sourceConfigMapYaml = []byte(`
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: source
|
||||
namespace: test-mutate
|
||||
labels:
|
||||
kyverno.key/copy-me: sample-value
|
||||
data:
|
||||
data.yaml: |
|
||||
some: data
|
||||
`)
|
||||
|
||||
// Target ConfigMap which is mutated
|
||||
var targetConfigMapYaml = []byte(`
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: target
|
||||
namespace: test-mutate
|
||||
data:
|
||||
data.yaml: |
|
||||
some: data
|
||||
`)
|
|
@ -1,4 +1,4 @@
|
|||
package generate
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
Loading…
Add table
Reference in a new issue