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:
parent
de2fcc8b7b
commit
c0875f16e6
5 changed files with 32 additions and 30 deletions
|
@ -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},
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue