1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-05 07:26:55 +00:00

fix: range through all resources to build webhook (#10748)

* fix: range through all resources to build webhook

Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>

* chore: add tests

Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>

* chore: correct conformance

Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>

* chore: correct conformance pod all subresources

Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>

* fix: append resource when operations and scope is same

Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>

* fix: correct tests

Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>

* fix: chainsaw tests

Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>

* fix: flaky test

Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>

* chore: remove debug lines

Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>

---------

Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>
Co-authored-by: anushkamittal20 <anumittal4641@gmail.com>
Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
Anushka Mittal 2024-09-05 17:12:40 +05:30 committed by GitHub
parent bc0f83b175
commit 37ab9ba824
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 99 additions and 41 deletions

View file

@ -52,6 +52,42 @@ func TestAddOperationsForValidatingWebhookConfMultiplePolicies(t *testing.T) {
expectedResult: map[string][]admissionregistrationv1.OperationType{
"ConfigMap": {"CREATE", "UPDATE", "DELETE", "CONNECT"},
},
}, {
name: "test-2",
policies: []kyverno.ClusterPolicy{
{
Spec: kyverno.Spec{
Rules: []kyverno.Rule{
{
MatchResources: kyverno.MatchResources{
ResourceDescription: kyverno.ResourceDescription{
Kinds: []string{"Role"},
Operations: []kyverno.AdmissionOperation{"DELETE"},
},
},
},
},
},
},
{
Spec: kyverno.Spec{
Rules: []kyverno.Rule{
{
MatchResources: kyverno.MatchResources{
ResourceDescription: kyverno.ResourceDescription{
Kinds: []string{"Secrets"},
Operations: []kyverno.AdmissionOperation{"CONNECT"},
},
},
},
},
},
},
},
expectedResult: map[string][]admissionregistrationv1.OperationType{
"Role": {"DELETE"},
"Secrets": {"CONNECT"},
},
},
}

View file

@ -2,6 +2,7 @@ package webhook
import (
"cmp"
"reflect"
"slices"
"strings"
@ -75,30 +76,37 @@ func (wh *webhook) buildRulesWithOperations(final map[string][]admissionregistra
rules := make([]admissionregistrationv1.RuleWithOperations, 0, len(wh.rules))
for gv, resources := range wh.rules {
firstResource := sets.List(resources)[0]
// if we have pods, we add pods/ephemeralcontainers by default
if (gv.Group == "" || gv.Group == "*") && (gv.Version == "v1" || gv.Version == "*") && (resources.Has("pods") || resources.Has("*")) {
resources.Insert("pods/ephemeralcontainers")
ruleforset := make([]admissionregistrationv1.RuleWithOperations, 0, len(resources))
for res := range resources {
resource := sets.New(res)
// if we have pods, we add pods/ephemeralcontainers by default
if (gv.Group == "" || gv.Group == "*") && (gv.Version == "v1" || gv.Version == "*") && (resource.Has("pods") || resource.Has("*")) {
resource.Insert("pods/ephemeralcontainers")
}
operations := findKeyContainingSubstring(final, res, defaultOpn)
if len(operations) == 0 {
continue
}
slices.SortFunc(operations, func(a, b admissionregistrationv1.OperationType) int {
return cmp.Compare(a, b)
})
var added bool
ruleforset, added = appendResourceInRule(resource, operations, ruleforset)
if !added {
ruleforset = append(ruleforset, admissionregistrationv1.RuleWithOperations{
Rule: admissionregistrationv1.Rule{
APIGroups: []string{gv.Group},
APIVersions: []string{gv.Version},
Resources: sets.List(resource),
Scope: ptr.To(gv.scopeType),
},
Operations: operations,
})
}
}
operations := findKeyContainingSubstring(final, firstResource, defaultOpn)
if len(operations) == 0 {
continue
}
slices.SortFunc(operations, func(a, b admissionregistrationv1.OperationType) int {
return cmp.Compare(a, b)
})
rules = append(rules, admissionregistrationv1.RuleWithOperations{
Rule: admissionregistrationv1.Rule{
APIGroups: []string{gv.Group},
APIVersions: []string{gv.Version},
Resources: sets.List(resources),
Scope: ptr.To(gv.scopeType),
},
Operations: operations,
})
rules = append(rules, ruleforset...)
}
less := func(a []string, b []string) (int, bool) {
if x := cmp.Compare(len(a), len(b)); x != 0 {
@ -129,6 +137,16 @@ func (wh *webhook) buildRulesWithOperations(final map[string][]admissionregistra
return rules
}
func appendResourceInRule(resource sets.Set[string], operations []admissionregistrationv1.OperationType, ruleforset []admissionregistrationv1.RuleWithOperations) ([]admissionregistrationv1.RuleWithOperations, bool) {
for i, rule := range ruleforset {
if reflect.DeepEqual(rule.Operations, operations) {
ruleforset[i].Rule.Resources = append(rule.Rule.Resources, resource.UnsortedList()...)
return ruleforset, true
}
}
return ruleforset, false
}
func scanResourceFilterForResources(resFilter kyvernov1.ResourceFilters) []string {
var resources []string
for _, rf := range resFilter {

View file

@ -374,12 +374,6 @@ func TestBuildRulesWithOperations(t *testing.T) {
{
name: "Test Case 1",
rules: map[groupVersionScope]sets.Set[string]{
groupVersionScope{
GroupVersion: corev1.SchemeGroupVersion,
scopeType: admissionregistrationv1.AllScopes,
}: {
"namespaces": sets.Empty{},
},
groupVersionScope{
GroupVersion: corev1.SchemeGroupVersion,
scopeType: admissionregistrationv1.NamespacedScope,
@ -389,16 +383,24 @@ func TestBuildRulesWithOperations(t *testing.T) {
},
},
mapResourceToOpnType: map[string][]admissionregistrationv1.OperationType{
"Namespace": {},
"Pod": {webhookCreate, webhookUpdate},
"Pod": {webhookCreate, webhookUpdate},
"ConfigMaps": {webhookCreate},
},
expectedResult: []admissionregistrationv1.RuleWithOperations{
{
Operations: []admissionregistrationv1.OperationType{webhookCreate},
Rule: admissionregistrationv1.Rule{
APIGroups: []string{""},
APIVersions: []string{"v1"},
Resources: []string{"configmaps"},
Scope: ptr.To(admissionregistrationv1.NamespacedScope),
},
}, {
Operations: []admissionregistrationv1.OperationType{webhookCreate, webhookUpdate},
Rule: admissionregistrationv1.Rule{
APIGroups: []string{""},
APIVersions: []string{"v1"},
Resources: []string{"configmaps", "pods", "pods/ephemeralcontainers"},
Resources: []string{"pods", "pods/ephemeralcontainers"},
Scope: ptr.To(admissionregistrationv1.NamespacedScope),
},
},

View file

@ -16,13 +16,14 @@ webhooks:
- DELETE
- UPDATE
resources:
- pods/attach
- pods/binding
- pods/ephemeralcontainers
- pods/eviction
- pods/exec
- pods/log
- pods/portforward
- pods/proxy
- pods/status
(contains(@,'pods/status')): true
(contains(@,'pods/log')): true
(contains(@,'pods/attach')): true
(contains(@,'pods/ephemeralcontainers')): true
(contains(@,'pods/eviction')): true
(contains(@,'pods/exec')): true
(contains(@,'pods/portforward')): true
(contains(@,'pods/binding')): true
(contains(@,'pods/proxy')): true
scope: 'Namespaced'

View file

@ -20,3 +20,4 @@ webhooks:
- 'configmaps'
- 'secrets'
scope: 'Namespaced'