1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-06 16:06:56 +00:00
kyverno/pkg/controllers/webhook/utils.go
Vyom Yadav c0875f16e6
fix: Configure webhook to add ephemeralcontainers for policies matching on Pod (#5886)
Signed-off-by: Vyom-Yadav <jackhammervyom@gmail.com>

Signed-off-by: Vyom-Yadav <jackhammervyom@gmail.com>
Co-authored-by: shuting <shuting@nirmata.com>
2023-01-06 13:40:35 +00:00

132 lines
3.7 KiB
Go

package webhook
import (
"strings"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"golang.org/x/exp/slices"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
)
// webhook is the instance that aggregates the GVK of existing policies
// based on kind, failurePolicy and webhookTimeout
type webhook struct {
maxWebhookTimeout int32
failurePolicy admissionregistrationv1.FailurePolicyType
rules map[schema.GroupVersionResource]struct{}
}
func newWebhook(timeout int32, failurePolicy admissionregistrationv1.FailurePolicyType) *webhook {
return &webhook{
maxWebhookTimeout: timeout,
failurePolicy: failurePolicy,
rules: map[schema.GroupVersionResource]struct{}{},
}
}
func (wh *webhook) buildRulesWithOperations(ops ...admissionregistrationv1.OperationType) []admissionregistrationv1.RuleWithOperations {
var rules []admissionregistrationv1.RuleWithOperations
for gvr := range wh.rules {
resources := sets.New(gvr.Resource)
ephemeralContainersGVR := schema.GroupVersionResource{Resource: "pods/ephemeralcontainers", Group: "", Version: "v1"}
_, rulesContainEphemeralContainers := wh.rules[ephemeralContainersGVR]
if resources.Has("pods") && !rulesContainEphemeralContainers {
resources.Insert("pods/ephemeralcontainers")
}
rules = append(rules, admissionregistrationv1.RuleWithOperations{
Rule: admissionregistrationv1.Rule{
APIGroups: []string{gvr.Group},
APIVersions: []string{gvr.Version},
Resources: sets.List(resources),
},
Operations: ops,
})
}
less := func(a []string, b []string) (bool, bool) {
if len(a) != len(b) {
return len(a) < len(b), true
}
for i := range a {
if a[i] != b[i] {
return a[i] < b[i], true
}
}
return false, false
}
slices.SortFunc(rules, func(a admissionregistrationv1.RuleWithOperations, b admissionregistrationv1.RuleWithOperations) bool {
if less, match := less(a.APIGroups, b.APIGroups); match {
return less
}
if less, match := less(a.APIVersions, b.APIVersions); match {
return less
}
if less, match := less(a.Resources, b.Resources); match {
return less
}
return false
})
return rules
}
func (wh *webhook) set(gvr schema.GroupVersionResource) {
wh.rules[gvr] = struct{}{}
}
func (wh *webhook) isEmpty() bool {
return len(wh.rules) == 0
}
func (wh *webhook) setWildcard() {
wh.rules = map[schema.GroupVersionResource]struct{}{
{Group: "*", Version: "*", Resource: "*/*"}: {},
}
}
func hasWildcard(policies ...kyvernov1.PolicyInterface) bool {
for _, policy := range policies {
spec := policy.GetSpec()
for _, rule := range spec.Rules {
if kinds := rule.MatchResources.GetKinds(); slices.Contains(kinds, "*") {
return true
}
}
}
return false
}
func objectMeta(name string, owner ...metav1.OwnerReference) metav1.ObjectMeta {
return metav1.ObjectMeta{
Name: name,
Labels: map[string]string{
managedByLabel: kyvernov1.ValueKyvernoApp,
},
OwnerReferences: owner,
}
}
func setRuleCount(rules []kyvernov1.Rule, status *kyvernov1.PolicyStatus) {
validateCount, generateCount, mutateCount, verifyImagesCount := 0, 0, 0, 0
for _, rule := range rules {
if !strings.HasPrefix(rule.Name, "autogen-") {
if rule.HasGenerate() {
generateCount += 1
}
if rule.HasValidate() {
validateCount += 1
}
if rule.HasMutate() {
mutateCount += 1
}
if rule.HasVerifyImages() {
verifyImagesCount += 1
}
}
}
status.RuleCount.Validate = validateCount
status.RuleCount.Generate = generateCount
status.RuleCount.Mutate = mutateCount
status.RuleCount.VerifyImages = verifyImagesCount
}