2021-04-23 01:15:45 +05:30
|
|
|
package validate
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
|
2021-10-29 18:13:20 +02:00
|
|
|
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
2021-04-23 01:15:45 +05:30
|
|
|
"gotest.tools/assert"
|
|
|
|
)
|
|
|
|
|
|
|
|
func Test_validateUsingPolicyCRD(t *testing.T) {
|
|
|
|
type TestCase struct {
|
|
|
|
rawPolicy []byte
|
|
|
|
errorDetail string
|
2021-05-07 22:55:26 +05:30
|
|
|
detail string
|
2021-04-23 01:15:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
testcases := []TestCase{
|
|
|
|
{
|
|
|
|
rawPolicy: []byte(`
|
|
|
|
{
|
|
|
|
"apiVersion": "kyverno.io/v1",
|
|
|
|
"kind": "ClusterPolicy",
|
|
|
|
"metadata": {
|
|
|
|
"name": "add-requests"
|
|
|
|
},
|
|
|
|
"spec": {
|
|
|
|
"rules": [
|
|
|
|
{
|
|
|
|
"name": "Set memory and/or cpu requests for all pods in namespaces labeled 'myprivatelabel'",
|
|
|
|
"match": {
|
|
|
|
"resources": {
|
|
|
|
"kinds": [
|
|
|
|
"Pod"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"mutate": {
|
|
|
|
"overlay": {
|
|
|
|
"spec": {
|
|
|
|
"containers": [
|
|
|
|
{
|
|
|
|
"(name)": "*",
|
|
|
|
"resources": {
|
|
|
|
"requests": {
|
|
|
|
"cpu": "1000m"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`),
|
2022-01-27 21:13:23 -08:00
|
|
|
errorDetail: "spec.rules[0].name in body should be at most 63 chars long",
|
2021-05-07 22:55:26 +05:30
|
|
|
detail: "Test: char count for rule name",
|
2021-04-23 01:15:45 +05:30
|
|
|
},
|
2021-05-07 22:55:26 +05:30
|
|
|
|
2021-04-23 01:15:45 +05:30
|
|
|
{
|
|
|
|
rawPolicy: []byte(`
|
|
|
|
{
|
|
|
|
"apiVersion": "kyverno.io/v1",
|
|
|
|
"kind": "ClusterPolicy",
|
|
|
|
"metadata": {
|
|
|
|
"name": "min-replicas-clusterpolicy"
|
|
|
|
},
|
|
|
|
"spec": {
|
|
|
|
"validationFailureAction": "audit",
|
|
|
|
"rules": [
|
|
|
|
{
|
|
|
|
"name": "check-min-replicas",
|
|
|
|
"match": {
|
|
|
|
"resources": {
|
|
|
|
"kinds": [
|
|
|
|
"Deployment"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"validate": {
|
|
|
|
"message": "should have at least 2 replicas",
|
|
|
|
"pattern": {
|
|
|
|
"spec": {
|
|
|
|
"replicas": 2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`),
|
|
|
|
errorDetail: "",
|
2021-05-07 22:55:26 +05:30
|
|
|
detail: "Test: basic vaild policy",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
rawPolicy: []byte(`
|
|
|
|
{
|
|
|
|
"apiVersion": "kyverno.io/v1",
|
|
|
|
"kind": "ClusterPolicy",
|
|
|
|
"metadata": {
|
|
|
|
"name": "disallow-singleton"
|
|
|
|
},
|
|
|
|
"spec": {
|
|
|
|
"validationFailureAction": "audit",
|
|
|
|
"rules": [
|
|
|
|
{
|
|
|
|
"name": "validate-replicas",
|
|
|
|
"match": {
|
|
|
|
"resources": {
|
|
|
|
"kinds": [
|
|
|
|
"Deployment"
|
|
|
|
],
|
|
|
|
"annotations": {
|
|
|
|
"singleton": "true"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"validate": {
|
|
|
|
"message": "Replicasets require at least 2 replicas.",
|
|
|
|
"pattern": {
|
|
|
|
"spec": {
|
|
|
|
"replicas": ">1"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`),
|
|
|
|
errorDetail: "",
|
|
|
|
detail: "Test: schema validation for spec.rules.match.resources.annotations",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
rawPolicy: []byte(`
|
|
|
|
{
|
|
|
|
"apiVersion": "kyverno.io/v1",
|
|
|
|
"kind": "ClusterPolicy",
|
|
|
|
"metadata": {
|
|
|
|
"name": "disallow-singleton"
|
|
|
|
},
|
|
|
|
"spec": {
|
|
|
|
"validationFailureAction": "audit",
|
|
|
|
"rules": [
|
|
|
|
{
|
|
|
|
"name": "validate-replicas",
|
|
|
|
"match": {
|
|
|
|
"resources": {
|
|
|
|
"kinds": [
|
|
|
|
"Deployment"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"exclude": {
|
|
|
|
"resources": {
|
|
|
|
"annotations": {
|
|
|
|
"singleton": "true"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"validate": {
|
|
|
|
"message": "Replicasets require at least 2 replicas.",
|
|
|
|
"pattern": {
|
|
|
|
"spec": {
|
|
|
|
"replicas": ">1"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`),
|
|
|
|
errorDetail: "",
|
|
|
|
detail: "Test: schema validation for spec.rules.exclude.resources.annotations",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
rawPolicy: []byte(`
|
|
|
|
{
|
|
|
|
"apiVersion": "kyverno.io/v1",
|
|
|
|
"kind": "ClusterPolicy",
|
|
|
|
"metadata": {
|
|
|
|
"name": "enforce-pod-name"
|
|
|
|
},
|
|
|
|
"spec": {
|
|
|
|
"validationFailureAction": "audit",
|
|
|
|
"background": true,
|
|
|
|
"rules": [
|
|
|
|
{
|
|
|
|
"name": "validate-name",
|
|
|
|
"match": {
|
|
|
|
"resources": {
|
|
|
|
"kinds": [
|
|
|
|
"Pod"
|
|
|
|
],
|
|
|
|
"namespaceSelector": {
|
|
|
|
"matchLabels": {
|
|
|
|
"app-namespace": "true"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"validate": {
|
|
|
|
"message": "The Pod must end with -nginx",
|
|
|
|
"pattern": {
|
|
|
|
"metadata": {
|
|
|
|
"name": "*-nginx"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`),
|
|
|
|
errorDetail: "",
|
|
|
|
detail: "Test: schema validation for spec.rules.match.resources.namespaceSelector.matchLabels",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
rawPolicy: []byte(`
|
|
|
|
{
|
|
|
|
"apiVersion": "kyverno.io/v1",
|
|
|
|
"kind": "ClusterPolicy",
|
|
|
|
"metadata": {
|
|
|
|
"name": "enforce-pod-name"
|
|
|
|
},
|
|
|
|
"spec": {
|
|
|
|
"validationFailureAction": "audit",
|
|
|
|
"background": true,
|
|
|
|
"rules": [
|
|
|
|
{
|
|
|
|
"name": "validate-name",
|
|
|
|
"match": {
|
|
|
|
"resources": {
|
|
|
|
"kinds": [
|
|
|
|
"Pod"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"exclude": {
|
|
|
|
"resources": {
|
|
|
|
"namespaceSelector": {
|
|
|
|
"matchLabels": {
|
|
|
|
"app-namespace": "true"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"validate": {
|
|
|
|
"message": "The Pod must end with -nginx",
|
|
|
|
"pattern": {
|
|
|
|
"metadata": {
|
|
|
|
"name": "*-nginx"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`),
|
|
|
|
errorDetail: "",
|
|
|
|
detail: "Test: schema validation for spec.rules.exclude.resources.namespaceSelector.matchLabels",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
rawPolicy: []byte(`
|
|
|
|
{
|
|
|
|
"apiVersion": "kyverno.io/v1",
|
|
|
|
"kind": "ClusterPolicy",
|
|
|
|
"metadata": {
|
|
|
|
"name": "enforce-pod-name"
|
|
|
|
},
|
|
|
|
"spec": {
|
|
|
|
"validationFailureAction": "audit",
|
|
|
|
"background": true,
|
|
|
|
"rules": [
|
|
|
|
{
|
|
|
|
"name": "validate-name",
|
|
|
|
"match": {
|
|
|
|
"resources": {
|
|
|
|
"kinds": [
|
|
|
|
"Pod"
|
|
|
|
],
|
|
|
|
"selector": {
|
|
|
|
"matchLabels": {
|
|
|
|
"app-namespace": "true"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"validate": {
|
|
|
|
"message": "The Pod must end with -nginx",
|
|
|
|
"pattern": {
|
|
|
|
"metadata": {
|
|
|
|
"name": "*-nginx"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`),
|
|
|
|
errorDetail: "",
|
|
|
|
detail: "Test: schema validation for spec.rules.match.resources.selector.matchLabels",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
rawPolicy: []byte(`
|
|
|
|
{
|
|
|
|
"apiVersion": "kyverno.io/v1",
|
|
|
|
"kind": "ClusterPolicy",
|
|
|
|
"metadata": {
|
|
|
|
"name": "enforce-pod-name"
|
|
|
|
},
|
|
|
|
"spec": {
|
|
|
|
"validationFailureAction": "audit",
|
|
|
|
"background": true,
|
|
|
|
"rules": [
|
|
|
|
{
|
|
|
|
"name": "validate-name",
|
|
|
|
"match": {
|
|
|
|
"resources": {
|
|
|
|
"kinds": [
|
|
|
|
"Pod"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"exclude": {
|
|
|
|
"resources": {
|
|
|
|
"selector": {
|
|
|
|
"matchLabels": {
|
|
|
|
"app-namespace": "true"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"validate": {
|
|
|
|
"message": "The Pod must end with -nginx",
|
|
|
|
"pattern": {
|
|
|
|
"metadata": {
|
|
|
|
"name": "*-nginx"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`),
|
|
|
|
errorDetail: "",
|
|
|
|
detail: "Test: schema validation for spec.rules.exclude.resources.selector.matchLabels",
|
2021-04-23 01:15:45 +05:30
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
v1crd, err := getPolicyCRD()
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
var policy kyverno.ClusterPolicy
|
|
|
|
for _, tc := range testcases {
|
|
|
|
err = json.Unmarshal(tc.rawPolicy, &policy)
|
|
|
|
assert.NilError(t, err)
|
|
|
|
|
|
|
|
_, errorList := validatePolicyAccordingToPolicyCRD(&policy, v1crd)
|
2021-05-07 22:55:26 +05:30
|
|
|
fmt.Println(tc.detail)
|
2021-04-23 01:15:45 +05:30
|
|
|
for _, e := range errorList {
|
|
|
|
assert.Assert(t, tc.errorDetail == e.Detail)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|