From b3a53f06581ab243f6a04ed6f0acbed949898a1a Mon Sep 17 00:00:00 2001 From: Vyankatesh Kudtarkar Date: Fri, 11 Mar 2022 15:09:32 +0530 Subject: [PATCH] fix PodExecOptions issue (#3373) * fix PodExecOptions issue * add note * update comment --- pkg/autogen/rule.go | 4 ++-- pkg/autogen/utils.go | 6 ++--- pkg/policy/validate.go | 2 +- pkg/policy/validate_test.go | 48 +++++++++++++++++++++++++++++++++++++ pkg/utils/util.go | 8 ++++++- 5 files changed, 61 insertions(+), 7 deletions(-) diff --git a/pkg/autogen/rule.go b/pkg/autogen/rule.go index e74b8d4ab7..746bb9e11f 100644 --- a/pkg/autogen/rule.go +++ b/pkg/autogen/rule.go @@ -77,8 +77,8 @@ func generateRuleForControllers(rule kyverno.Rule, controllers string, log logr. matchResourceDescriptionsKinds := rule.MatchKinds() excludeResourceDescriptionsKinds := rule.ExcludeKinds() - if !utils.ContainsPod(matchResourceDescriptionsKinds, "Pod") || - (len(excludeResourceDescriptionsKinds) != 0 && !utils.ContainsPod(excludeResourceDescriptionsKinds, "Pod")) { + if !utils.ContainsKind(matchResourceDescriptionsKinds, "Pod") || + (len(excludeResourceDescriptionsKinds) != 0 && !utils.ContainsKind(excludeResourceDescriptionsKinds, "Pod")) { return nil } diff --git a/pkg/autogen/utils.go b/pkg/autogen/utils.go index e6a02be609..4dc08a4599 100644 --- a/pkg/autogen/utils.go +++ b/pkg/autogen/utils.go @@ -8,7 +8,7 @@ import ( ) func isKindOtherthanPod(kinds []string) bool { - if len(kinds) > 1 && utils.ContainsPod(kinds, "Pod") { + if len(kinds) > 1 && utils.ContainsKind(kinds, "Pod") { return true } return false @@ -39,7 +39,7 @@ func validateAnyPattern(anyPatterns []interface{}) []interface{} { func getAnyAllAutogenRule(v kyverno.ResourceFilters, controllers string) kyverno.ResourceFilters { anyKind := v.DeepCopy() for i, value := range v { - if utils.ContainsPod(value.Kinds, "Pod") { + if utils.ContainsKind(value.Kinds, "Pod") { anyKind[i].Kinds = strings.Split(controllers, ",") } } @@ -65,7 +65,7 @@ func stripCronJob(controllers string) string { func cronJobAnyAllAutogenRule(v kyverno.ResourceFilters) kyverno.ResourceFilters { anyKind := v.DeepCopy() for i, value := range v { - if utils.ContainsPod(value.Kinds, "Job") { + if utils.ContainsKind(value.Kinds, "Job") { anyKind[i].Kinds = []string{PodControllerCronJob} } } diff --git a/pkg/policy/validate.go b/pkg/policy/validate.go index 2193db76ec..741c22041c 100644 --- a/pkg/policy/validate.go +++ b/pkg/policy/validate.go @@ -1506,7 +1506,7 @@ func validateKinds(kinds []string, mock bool, client *dclient.Client, p kyverno. return fmt.Errorf("kind and match resource kind should not be the same") } - if !mock { + if !mock && !utils.SkipSubResources(k) { _, _, err := client.DiscoveryClient.FindResource(gv, k) if err != nil { return fmt.Errorf("unable to convert GVK to GVR, %s, err: %s", kinds, err) diff --git a/pkg/policy/validate_test.go b/pkg/policy/validate_test.go index aa96eecb9e..f8b84ef4c8 100644 --- a/pkg/policy/validate_test.go +++ b/pkg/policy/validate_test.go @@ -1558,3 +1558,51 @@ func Test_patchesJson6902_Policy(t *testing.T) { err = Validate(policy, nil, true, openAPIController) assert.NilError(t, err) } + +func Test_deny_exec(t *testing.T) { + var err error + rawPolicy := []byte(`{ + "apiVersion": "kyverno.io/v1", + "kind": "ClusterPolicy", + "metadata": { + "name": "deny-exec-to-pod" + }, + "spec": { + "validationFailureAction": "enforce", + "background": false, + "schemaValidation": false, + "rules": [ + { + "name": "deny-pod-exec", + "match": { + "resources": { + "kinds": [ + "PodExecOptions" + ] + } + }, + "preconditions": { + "all": [ + { + "key": "{{ request.operation }}", + "operator": "Equals", + "value": "CONNECT" + } + ] + }, + "validate": { + "message": "Containers can't be exec'd into in production.", + "deny": {} + } + } + ] + } + }`) + var policy *kyverno.ClusterPolicy + err = json.Unmarshal(rawPolicy, &policy) + assert.NilError(t, err) + + openAPIController, _ := openapi.NewOpenAPIController() + err = Validate(policy, nil, true, openAPIController) + assert.NilError(t, err) +} diff --git a/pkg/utils/util.go b/pkg/utils/util.go index 37a2b0e224..18b5a8baa6 100644 --- a/pkg/utils/util.go +++ b/pkg/utils/util.go @@ -36,7 +36,7 @@ func contains(list []string, element string, fn func(string, string) bool) bool return false } -func ContainsPod(list []string, element string) bool { +func ContainsKind(list []string, element string) bool { for _, e := range list { _, k := common.GetKindFromGVK(e) if k == element { @@ -46,6 +46,12 @@ func ContainsPod(list []string, element string) bool { return false } +// SkipSubResources check to skip list of resources which don't have group. +func SkipSubResources(kind string) bool { + s := []string{"PodExecOptions", "PodAttachOptions", "PodProxyOptions", "ServiceProxyOptions", "NodeProxyOptions"} + return ContainsKind(s, kind) +} + // ContainsNamepace check if namespace satisfies any list of pattern(regex) func ContainsNamepace(patterns []string, ns string) bool { return contains(patterns, ns, compareNamespaces)