1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00
kyverno/pkg/controllers/validatingadmissionpolicy-generate/policycheck_test.go

488 lines
9.1 KiB
Go
Raw Normal View History

feat: generate validating admission policies and their bindings from Kyverno policies (#7840) * feat: generate validating admission policies and their bindings from Kyverno policies Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: add generate VAPs feature flag Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: use container flags instead of feature flags Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: limit VAP generation to cluster policies Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: add policy checks for generating VAPs Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * chore: rename package Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: translate match/exclude resources in Kyverno policies to their alternatives in validating admission policies Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: add vap info in kyverno policy status Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: delete the translation of Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: add kuttl tests Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: add generateValidatingAdmissionPolicy feature flag in the helm chart Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * chore: update codegen Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: add validating admission policy kuttl tests in the workflow Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: check K8s server version Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix lint issue Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: remove the kind config of VAPs Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> --------- Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
2023-08-31 10:25:21 +00:00
package validatingadmissionpolicygenerate
import (
"encoding/json"
"testing"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml"
"gotest.tools/assert"
)
func Test_Check_Resources(t *testing.T) {
testCases := []struct {
name string
resource []byte
expected bool
}{
{
name: "resource-with-namespaces",
resource: []byte(`
{
"kinds": [
"Service"
],
"namespaces": [
"prod"
],
"operations": [
"CREATE"
]
}
`),
expected: false,
},
{
name: "resource-with-annotations",
resource: []byte(`
{
"annotations": {
"imageregistry": "https://hub.docker.com/"
},
"kinds": [
"Pod"
],
"operations": [
"CREATE",
"UPDATE"
]
}
`),
expected: false,
},
{
name: "resource-with-object-selector",
resource: []byte(`
{
"kinds": [
"Pod"
],
"operations": [
"CREATE",
"UPDATE"
],
"selector": {
"matchLabels": {
"app": "critical"
}
}
}
`),
expected: true,
},
{
name: "resource-with-namespace-selector",
resource: []byte(`
{
"kinds": [
"Pod"
],
"operations": [
"CREATE",
"UPDATE"
],
"namespaceSelector": {
"matchLabels": {
"app": "critical"
}
}
}
`),
expected: true,
},
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
var res kyvernov1.ResourceDescription
err := json.Unmarshal(test.resource, &res)
assert.NilError(t, err)
out, _ := checkResources(res)
assert.Equal(t, out, test.expected)
})
}
}
func Test_Can_Generate_ValidatingAdmissionPolicy(t *testing.T) {
testCases := []struct {
name string
policy []byte
expected bool
}{
{
name: "policy-with-two-rules",
policy: []byte(`
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "disallow-latest-tag"
},
"spec": {
"rules": [
{
"name": "require-image-tag",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"cel": {
"expressions": [
{
"expression": "object.spec.containers.all(container, !container.image.matches('^[a-zA-Z]+:[0-9]*$'))"
}
]
}
}
},
{
"name": "validate-image-tag",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"cel": {
"expressions": [
{
"expression": "object.spec.containers.all(container, !container.image.contains('latest'))"
}
]
}
}
}
]
}
}
`),
expected: false,
},
{
name: "policy-with-mutate-rule",
policy: []byte(`
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "set-image-pull-policy"
},
"spec": {
"rules": [
{
"name": "set-image-pull-policy",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"mutate": {
"patchStrategicMerge": {
"spec": {
"containers": [
{
"(image)": "*:latest",
"imagePullPolicy": "IfNotPresent"
}
]
}
}
}
}
]
}
}
`),
expected: false,
},
{
name: "policy-with-non-CEL-validate-rule",
policy: []byte(`
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "require-ns-purpose-label"
},
"spec": {
"validationFailureAction": "Enforce",
"rules": [
{
"name": "require-ns-purpose-label",
"match": {
"any": [
{
"resources": {
"kinds": [
"Namespace"
]
}
}
]
},
"validate": {
"pattern": {
"metadata": {
"labels": {
"purpose": "production"
}
}
}
}
}
]
}
}
`),
expected: false,
},
{
name: "policy-with-multiple-validationFailureActionOverrides",
policy: []byte(`
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "disallow-host-path"
},
"spec": {
"validationFailureAction": "Enforce",
"validationFailureActionOverrides": [
{
"action": "Enforce",
"namespaces": [
"default"
]
},
{
"action": "Audit",
"namespaces": [
"test"
]
}
],
"rules": [
{
"name": "host-path",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"cel": {
"expressions": [
{
"expression": "!has(object.spec.volumes) || object.spec.volumes.all(volume, !has(volume.hostPath))"
}
]
}
}
}
]
}
}
`),
expected: false,
},
{
name: "policy-with-namespace-in-validationFailureActionOverrides",
policy: []byte(`
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "disallow-host-path"
},
"spec": {
"validationFailureAction": "Enforce",
"validationFailureActionOverrides": [
{
"action": "Enforce",
"namespaces": [
"test-ns"
]
}
],
"rules": [
{
"name": "host-path",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"validate": {
"cel": {
"expressions": [
{
"expression": "!has(object.spec.volumes) || object.spec.volumes.all(volume, !has(volume.hostPath))"
}
]
}
}
}
]
}
}
`),
expected: false,
},
{
name: "policy-with-subjects-and-clusterroles",
policy: []byte(`
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "disallow-host-path"
},
"spec": {
"validationFailureAction": "Enforce",
"rules": [
{
"name": "host-path",
"match": {
"any": [
{
"resources": {
"kinds": [
"Deployment"
],
"operations": [
"CREATE",
"UPDATE"
]
},
"subjects": [
{
"kind": "User",
"name": "mary@somecorp.com"
}
],
"clusterRoles": [
"cluster-admin"
]
}
]
},
"validate": {
"cel": {
"expressions": [
{
"expression": "!has(object.spec.volumes) || object.spec.volumes.all(volume, !has(volume.hostPath))"
}
]
}
}
}
]
}
}
`),
expected: false,
},
{
name: "policy-with-object-selector",
policy: []byte(`
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "disallow-host-path"
},
"spec": {
"validationFailureAction": "Enforce",
"rules": [
{
"name": "host-path",
"match": {
"any": [
{
"resources": {
"kinds": [
"Deployment"
],
"operations": [
"CREATE",
"UPDATE"
],
"selector": {
"matchLabels": {
"app": "mongodb"
},
"matchExpressions": [
{
"key": "tier",
"operator": "In",
"values": [
"database"
]
}
]
}
}
}
]
},
"validate": {
"cel": {
"expressions": [
{
"expression": "!has(object.spec.volumes) || object.spec.volumes.all(volume, !has(volume.hostPath))"
}
]
}
}
}
]
}
}
`),
expected: true,
},
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
policies, _, _, err := yamlutils.GetPolicy([]byte(test.policy))
feat: generate validating admission policies and their bindings from Kyverno policies (#7840) * feat: generate validating admission policies and their bindings from Kyverno policies Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: add generate VAPs feature flag Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: use container flags instead of feature flags Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: limit VAP generation to cluster policies Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: add policy checks for generating VAPs Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * chore: rename package Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: translate match/exclude resources in Kyverno policies to their alternatives in validating admission policies Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: add vap info in kyverno policy status Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: delete the translation of Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: add kuttl tests Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: add generateValidatingAdmissionPolicy feature flag in the helm chart Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * chore: update codegen Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * feat: add validating admission policy kuttl tests in the workflow Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: check K8s server version Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix lint issue Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: remove the kind config of VAPs Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> --------- Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
2023-08-31 10:25:21 +00:00
assert.NilError(t, err)
assert.Equal(t, 1, len(policies))
out, _ := canGenerateVAP(policies[0].GetSpec())
assert.Equal(t, out, test.expected)
})
}
}