1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-15 17:51:20 +00:00
kyverno/pkg/controllers/webhook/utils_test.go
Anushka Mittal cfc9683033
Changes to dynamically configure webhooks (#8437)
* Changes to dynamically configure webhooks

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Add unit tests

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Add kuttl tests

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Refactoring

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Correct unit test

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Change way of webhooks configured

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Correct tests with new changes

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Add delete operation by default

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Correct tests with new changes

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Correct order for operations

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Add corrections

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Add mutatingwebhookconfiguration test

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Correct unit test

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Added policy.yaml in mutate webhook test

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Add corrections in kuttl test and code

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Change name of test

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Changes to update webhooks manifest

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Add corrections for dynamic-op-mutate kuttl test

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Add minor changes; remove unnecessary file

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Correct adding operations for MutatingWebhookConf

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* dynamic op mutate and validate added

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Resolve conflicts

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Filter rules for mutatingwebhookconf correctly

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* replace TestStep with Test in chainsaw tests

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* converted to new chainsaw-test format

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* minor corrections

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* remove isMutationEmpty()

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* initial changes for dynamic opn enhancements

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* rename variables

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* resolve lint errors

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* refactor code

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* add changes for exclude operations

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* add conformance tests

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* add unit tests

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* corrections in conformance tests

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* modification in unit tests

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* correction in conformance tests

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* Update .vscode/launch.json

Signed-off-by: shuting <shuting@nirmata.com>

* update variable usage

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

* remove testresults

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>

---------

Signed-off-by: anushkamittal2001 <anushka@nirmata.com>
Signed-off-by: shuting <shuting@nirmata.com>
Co-authored-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>
Co-authored-by: shuting <shuting@nirmata.com>
Co-authored-by: Jim Bugwadia <jim@nirmata.com>
Co-authored-by: Vishal Choudhary <vishal.choudhary@nirmata.com>
Co-authored-by: shuting <shutting06@gmail.com>
2024-01-31 15:46:53 +00:00

364 lines
10 KiB
Go

package webhook
import (
"encoding/json"
"reflect"
"sort"
"testing"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
v1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/autogen"
"gotest.tools/assert"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func Test_webhook_isEmpty(t *testing.T) {
empty := newWebhook(DefaultWebhookTimeout, admissionregistrationv1.Ignore, []admissionregistrationv1.MatchCondition{})
assert.Equal(t, empty.isEmpty(), true)
notEmpty := newWebhook(DefaultWebhookTimeout, admissionregistrationv1.Ignore, []admissionregistrationv1.MatchCondition{})
notEmpty.set(GroupVersionResourceScope{
GroupVersionResource: schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"},
Scope: admissionregistrationv1.NamespacedScope,
})
assert.Equal(t, notEmpty.isEmpty(), false)
}
var policy = `
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "disallow-unsigned-images"
},
"spec": {
"validationFailureAction": "enforce",
"background": false,
"rules": [
{
"name": "replace-image-registry",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"mutate": {
"foreach": [
{
"list": "request.object.spec.containers",
"patchStrategicMerge": {
"spec": {
"containers": [
{
"name": "{{ element.name }}",
"image": "{{ regex_replace_all_literal('.*(.*)/', '{{element.image}}', 'pratikrshah/' )}}"
}
]
}
}
}
]
}
},
{
"name": "disallow-unsigned-images-rule",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"verifyImages": [
{
"imageReferences": [
"*"
],
"verifyDigest": false,
"required": null,
"mutateDigest": false,
"attestors": [
{
"count": 1,
"entries": [
{
"keys": {
"publicKeys": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHsra9WSDxt9qv84KF4McNVCGjMFq\ne96mWCQxGimL9Ltj6F3iXmlo8sUalKfJ7SBXpy8hwyBfXBBAmCalsp5xEw==\n-----END PUBLIC KEY-----"
}
}
]
}
]
}
]
},
{
"name": "check-image",
"match": {
"any": [
{
"resources": {
"kinds": [
"Pod"
]
}
}
]
},
"context": [
{
"name": "keys",
"configMap": {
"name": "keys",
"namespace": "default"
}
}
],
"verifyImages": [
{
"imageReferences": [
"ghcr.io/myorg/myimage*"
],
"required": true,
"attestors": [
{
"count": 1,
"entries": [
{
"keys": {
"publicKeys": "{{ keys.data.production }}"
}
}
]
}
]
}
]
}
]
}
}
`
func Test_RuleCount(t *testing.T) {
var cpol kyverno.ClusterPolicy
err := json.Unmarshal([]byte(policy), &cpol)
assert.NilError(t, err)
status := cpol.GetStatus()
rules := autogen.ComputeRules(&cpol)
setRuleCount(rules, status)
assert.Equal(t, status.RuleCount.Validate, 0)
assert.Equal(t, status.RuleCount.Generate, 0)
assert.Equal(t, status.RuleCount.Mutate, 1)
assert.Equal(t, status.RuleCount.VerifyImages, 2)
}
func TestGetMinimumOperations(t *testing.T) {
testCases := []struct {
name string
inputMap map[string]bool
expectedResult []admissionregistrationv1.OperationType
}{
{
name: "Test Case 1",
inputMap: map[string]bool{
webhookCreate: true,
webhookUpdate: false,
webhookDelete: true,
},
expectedResult: []admissionregistrationv1.OperationType{webhookCreate, webhookDelete},
},
{
name: "Test Case 2",
inputMap: map[string]bool{
webhookCreate: false,
webhookUpdate: false,
webhookDelete: false,
webhookConnect: true,
},
expectedResult: []admissionregistrationv1.OperationType{webhookConnect},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
result := getMinimumOperations(testCase.inputMap)
sort.Slice(result, func(i, j int) bool {
return result[i] < result[j]
})
sort.Slice(testCase.expectedResult, func(i, j int) bool {
return testCase.expectedResult[i] < testCase.expectedResult[j]
})
if !reflect.DeepEqual(result, testCase.expectedResult) {
t.Errorf("Expected %v, but got %v", testCase.expectedResult, result)
}
})
}
}
func TestComputeOperationsForMutatingWebhookConf(t *testing.T) {
testCases := []struct {
name string
rules []kyverno.Rule
expectedResult map[string]bool
}{
{
name: "Test Case 1",
rules: []kyverno.Rule{
{
Mutation: kyverno.Mutation{
PatchesJSON6902: "add",
},
MatchResources: kyverno.MatchResources{
ResourceDescription: kyverno.ResourceDescription{
Operations: []v1.AdmissionOperation{webhookCreate},
},
},
},
},
expectedResult: map[string]bool{
webhookCreate: true,
},
},
{
name: "Test Case 2",
rules: []kyverno.Rule{
{
Mutation: kyverno.Mutation{
PatchesJSON6902: "add",
},
MatchResources: kyverno.MatchResources{},
ExcludeResources: kyverno.MatchResources{},
},
{
Mutation: kyverno.Mutation{
PatchesJSON6902: "add",
},
MatchResources: kyverno.MatchResources{},
ExcludeResources: kyverno.MatchResources{},
},
},
expectedResult: map[string]bool{
webhookCreate: true,
webhookUpdate: true,
},
},
{
name: "Test Case 2",
rules: []kyverno.Rule{
{
Mutation: kyverno.Mutation{
PatchesJSON6902: "add",
},
MatchResources: kyverno.MatchResources{},
ExcludeResources: kyverno.MatchResources{
ResourceDescription: kyverno.ResourceDescription{
Operations: []v1.AdmissionOperation{webhookCreate},
},
},
},
},
expectedResult: map[string]bool{
webhookCreate: false,
webhookUpdate: true,
},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
var result map[string]bool
for _, r := range testCase.rules {
result = computeOperationsForMutatingWebhookConf(r, make(map[string]bool))
}
if !reflect.DeepEqual(result, testCase.expectedResult) {
t.Errorf("Expected %v, but got %v", testCase.expectedResult, result)
}
})
}
}
func TestComputeOperationsForValidatingWebhookConf(t *testing.T) {
testCases := []struct {
name string
rules []kyverno.Rule
expectedResult map[string]bool
}{
{
name: "Test Case 1",
rules: []kyverno.Rule{
{
MatchResources: kyverno.MatchResources{
ResourceDescription: kyverno.ResourceDescription{
Operations: []v1.AdmissionOperation{webhookCreate},
},
},
},
},
expectedResult: map[string]bool{
webhookCreate: true,
},
},
{
name: "Test Case 2",
rules: []kyverno.Rule{
{
MatchResources: kyverno.MatchResources{},
ExcludeResources: kyverno.MatchResources{},
},
},
expectedResult: map[string]bool{
webhookCreate: true,
webhookUpdate: true,
webhookConnect: true,
webhookDelete: true,
},
},
{
name: "Test Case 3",
rules: []kyverno.Rule{
{
MatchResources: kyverno.MatchResources{
ResourceDescription: kyverno.ResourceDescription{
Operations: []v1.AdmissionOperation{webhookCreate, webhookUpdate},
},
},
ExcludeResources: kyverno.MatchResources{
ResourceDescription: kyverno.ResourceDescription{
Operations: []v1.AdmissionOperation{webhookDelete},
},
},
},
},
expectedResult: map[string]bool{
webhookCreate: true,
webhookUpdate: true,
webhookDelete: false,
},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
var result map[string]bool
for _, r := range testCase.rules {
result = computeOperationsForValidatingWebhookConf(r, make(map[string]bool))
}
if !reflect.DeepEqual(result, testCase.expectedResult) {
t.Errorf("Expected %v, but got %v", testCase.expectedResult, result)
}
})
}
}