1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-13 19:28:55 +00:00

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>
This commit is contained in:
Vyom Yadav 2023-01-06 19:10:35 +05:30 committed by GitHub
parent de2fcc8b7b
commit c0875f16e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 30 deletions

View file

@ -31,6 +31,11 @@ func (wh *webhook) buildRulesWithOperations(ops ...admissionregistrationv1.Opera
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},

View file

@ -116,7 +116,8 @@ func doesResourceMatchConditionBlock(subresourceGVKToAPIResource map[string]*met
var errs []error
if len(conditionBlock.Kinds) > 0 {
if !matched.CheckKind(subresourceGVKToAPIResource, conditionBlock.Kinds, resource.GroupVersionKind(), subresourceInAdmnReview) {
// Matching on ephemeralcontainers even when they are not explicitly specified for backward compatibility.
if !matched.CheckKind(subresourceGVKToAPIResource, conditionBlock.Kinds, resource.GroupVersionKind(), subresourceInAdmnReview, true) {
errs = append(errs, fmt.Errorf("kind does not match %v", conditionBlock.Kinds))
}
}

View file

@ -407,7 +407,6 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b
}
checkForScaleSubresource(validationJson, allKinds, &warnings)
checkForStatusSubresource(validationJson, allKinds, &warnings)
checkForEphemeralContainersSubresource(validationJson, allKinds, &warnings)
}
if rule.HasMutate() {
@ -421,7 +420,6 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b
}
checkForScaleSubresource(mutationJson, allKinds, &warnings)
checkForStatusSubresource(mutationJson, allKinds, &warnings)
checkForEphemeralContainersSubresource(mutationJson, allKinds, &warnings)
}
}
if !mock && (spec.SchemaValidation == nil || *spec.SchemaValidation) {
@ -1338,15 +1336,3 @@ func checkForStatusSubresource(ruleTypeJson []byte, allKinds []string, warnings
*warnings = append(*warnings, msg)
}
}
func checkForEphemeralContainersSubresource(ruleTypeJson []byte, allKinds []string, warnings *[]string) {
if strings.Contains(string(ruleTypeJson), "ephemeralcontainers") {
for _, kind := range allKinds {
if strings.Contains(strings.ToLower(kind), "ephemeralcontainers") {
return
}
}
msg := "You are matching on ephemeralcontainers but not including the ephemeralcontainers subresource in the policy."
*warnings = append(*warnings, msg)
}
}

View file

@ -109,7 +109,8 @@ func checkResourceDescription(
) []error {
var errs []error
if len(conditionBlock.Kinds) > 0 {
if !CheckKind(subresourceGVKToAPIResource, conditionBlock.Kinds, resource.GroupVersionKind(), subresourceInAdmnReview) {
// Matching on ephemeralcontainers even when they are not explicitly specified is only applicable to policies.
if !CheckKind(subresourceGVKToAPIResource, conditionBlock.Kinds, resource.GroupVersionKind(), subresourceInAdmnReview, false) {
errs = append(errs, fmt.Errorf("kind does not match %v", conditionBlock.Kinds))
}
}
@ -167,7 +168,10 @@ func checkResourceDescription(
return errs
}
func CheckKind(subresourceGVKToAPIResource map[string]*metav1.APIResource, kinds []string, gvk schema.GroupVersionKind, subresourceInAdmnReview string) bool {
// CheckKind checks if the resource kind matches the kinds in the policy. If the policy matches on subresources, then those resources are
// present in the subresourceGVKToAPIResource map. Set allowEphemeralContainers to true to allow ephemeral containers to be matched even when the
// policy does not explicitly match on ephemeral containers and only matches on pods.
func CheckKind(subresourceGVKToAPIResource map[string]*metav1.APIResource, kinds []string, gvk schema.GroupVersionKind, subresourceInAdmnReview string, allowEphemeralContainers bool) bool {
title := cases.Title(language.Und, cases.NoLower)
result := false
for _, k := range kinds {
@ -177,7 +181,9 @@ func CheckKind(subresourceGVKToAPIResource map[string]*metav1.APIResource, kinds
if ok {
result = apiResource.Group == gvk.Group && (apiResource.Version == gvk.Version || strings.Contains(gv, "*")) && apiResource.Kind == gvk.Kind
} else { // if the kind is not found in the subresourceGVKToAPIResource, then it is not a subresource
result = title.String(kind) == gvk.Kind && subresourceInAdmnReview == ""
result = title.String(kind) == gvk.Kind &&
(subresourceInAdmnReview == "" ||
(allowEphemeralContainers && subresourceInAdmnReview == "ephemeralcontainers"))
if gv != "" {
result = result && kubeutils.GroupVersionMatches(gv, gvk.GroupVersion().String())
}

View file

@ -10,27 +10,31 @@ import (
func Test_CheckKind(t *testing.T) {
subresourceGVKToAPIResource := make(map[string]*metav1.APIResource)
match := CheckKind(subresourceGVKToAPIResource, []string{"*"}, schema.GroupVersionKind{Kind: "Deployment", Group: "", Version: "v1"}, "")
match := CheckKind(subresourceGVKToAPIResource, []string{"*"}, schema.GroupVersionKind{Kind: "Deployment", Group: "", Version: "v1"}, "", false)
assert.Equal(t, match, true)
match = CheckKind(subresourceGVKToAPIResource, []string{"Pod"}, schema.GroupVersionKind{Kind: "Pod", Group: "", Version: "v1"}, "")
match = CheckKind(subresourceGVKToAPIResource, []string{"Pod"}, schema.GroupVersionKind{Kind: "Pod", Group: "", Version: "v1"}, "", false)
assert.Equal(t, match, true)
match = CheckKind(subresourceGVKToAPIResource, []string{"v1/Pod"}, schema.GroupVersionKind{Kind: "Pod", Group: "", Version: "v1"}, "")
match = CheckKind(subresourceGVKToAPIResource, []string{"v1/Pod"}, schema.GroupVersionKind{Kind: "Pod", Group: "", Version: "v1"}, "", false)
assert.Equal(t, match, true)
match = CheckKind(subresourceGVKToAPIResource, []string{"tekton.dev/v1beta1/TaskRun"}, schema.GroupVersionKind{Kind: "TaskRun", Group: "tekton.dev", Version: "v1beta1"}, "")
match = CheckKind(subresourceGVKToAPIResource, []string{"tekton.dev/v1beta1/TaskRun"}, schema.GroupVersionKind{Kind: "TaskRun", Group: "tekton.dev", Version: "v1beta1"}, "", false)
assert.Equal(t, match, true)
match = CheckKind(subresourceGVKToAPIResource, []string{"tekton.dev/*/TaskRun"}, schema.GroupVersionKind{Kind: "TaskRun", Group: "tekton.dev", Version: "v1alpha1"}, "")
match = CheckKind(subresourceGVKToAPIResource, []string{"tekton.dev/*/TaskRun"}, schema.GroupVersionKind{Kind: "TaskRun", Group: "tekton.dev", Version: "v1alpha1"}, "", false)
assert.Equal(t, match, true)
// Though both 'pods', 'pods/status' have same kind i.e. 'Pod' but they are different resources, 'subresourceInAdmnReview' is used in determining that.
match = CheckKind(subresourceGVKToAPIResource, []string{"v1/Pod"}, schema.GroupVersionKind{Kind: "Pod", Group: "", Version: "v1"}, "status")
match = CheckKind(subresourceGVKToAPIResource, []string{"v1/Pod"}, schema.GroupVersionKind{Kind: "Pod", Group: "", Version: "v1"}, "status", false)
assert.Equal(t, match, false)
// Though both 'pods', 'pods/status' have same kind i.e. 'Pod' but they are different resources, 'subresourceInAdmnReview' is used in determining that.
match = CheckKind(subresourceGVKToAPIResource, []string{"v1/Pod"}, schema.GroupVersionKind{Kind: "Pod", Group: "", Version: "v1"}, "ephemeralcontainers")
// Though both 'pods', 'pods/ephemeralcontainers' have same kind i.e. 'Pod' but they are different resources, allowEphemeralContainers governs how to match this case.
match = CheckKind(subresourceGVKToAPIResource, []string{"v1/Pod"}, schema.GroupVersionKind{Kind: "Pod", Group: "", Version: "v1"}, "ephemeralcontainers", true)
assert.Equal(t, match, true)
// Though both 'pods', 'pods/ephemeralcontainers' have same kind i.e. 'Pod' but they are different resources, allowEphemeralContainers governs how to match this case.
match = CheckKind(subresourceGVKToAPIResource, []string{"v1/Pod"}, schema.GroupVersionKind{Kind: "Pod", Group: "", Version: "v1"}, "ephemeralcontainers", false)
assert.Equal(t, match, false)
subresourceGVKToAPIResource["networking.k8s.io/v1/NetworkPolicy/status"] = &metav1.APIResource{
@ -60,15 +64,15 @@ func Test_CheckKind(t *testing.T) {
Version: "v1",
}
match = CheckKind(subresourceGVKToAPIResource, []string{"networking.k8s.io/v1/NetworkPolicy/status"}, schema.GroupVersionKind{Kind: "NetworkPolicy", Group: "networking.k8s.io", Version: "v1"}, "status")
match = CheckKind(subresourceGVKToAPIResource, []string{"networking.k8s.io/v1/NetworkPolicy/status"}, schema.GroupVersionKind{Kind: "NetworkPolicy", Group: "networking.k8s.io", Version: "v1"}, "status", false)
assert.Equal(t, match, true)
match = CheckKind(subresourceGVKToAPIResource, []string{"v1/Pod.status"}, schema.GroupVersionKind{Kind: "Pod", Group: "", Version: "v1"}, "status")
match = CheckKind(subresourceGVKToAPIResource, []string{"v1/Pod.status"}, schema.GroupVersionKind{Kind: "Pod", Group: "", Version: "v1"}, "status", false)
assert.Equal(t, match, true)
match = CheckKind(subresourceGVKToAPIResource, []string{"*/Pod.eviction"}, schema.GroupVersionKind{Kind: "Eviction", Group: "policy", Version: "v1"}, "eviction")
match = CheckKind(subresourceGVKToAPIResource, []string{"*/Pod.eviction"}, schema.GroupVersionKind{Kind: "Eviction", Group: "policy", Version: "v1"}, "eviction", false)
assert.Equal(t, match, true)
match = CheckKind(subresourceGVKToAPIResource, []string{"v1alpha1/Pod.eviction"}, schema.GroupVersionKind{Kind: "Eviction", Group: "policy", Version: "v1"}, "eviction")
match = CheckKind(subresourceGVKToAPIResource, []string{"v1alpha1/Pod.eviction"}, schema.GroupVersionKind{Kind: "Eviction", Group: "policy", Version: "v1"}, "eviction", false)
assert.Equal(t, match, false)
}