1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-01-20 18:52:16 +00:00

support for deprecated API's (#3439) (#3453)

* support for deprecated API's

* add testcase

* update condition

* fix logic
This commit is contained in:
Vyankatesh Kudtarkar 2022-03-23 13:40:20 +05:30 committed by GitHub
parent f43d73adf2
commit fbcc329680
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 119 additions and 15 deletions

View file

@ -87,6 +87,9 @@ func GetKindFromGVK(str string) (apiVersion string, kind string) {
if strings.Count(str, "/") == 1 {
return splitString[0], splitString[1]
}
if splitString[1] == "*" {
return "", splitString[2]
}
return splitString[0] + "/" + splitString[1], splitString[2]
}

View file

@ -48,7 +48,7 @@ func checkKind(kinds []string, resource unstructured.Unstructured) bool {
return true
}
} else {
if resource.GroupVersionKind().Group == SplitGVK[0] && resource.GroupVersionKind().Kind == strings.Title(SplitGVK[2]) && (resource.GroupVersionKind().Version == SplitGVK[1] || resource.GroupVersionKind().Version == "*") {
if resource.GroupVersionKind().Group == SplitGVK[0] && resource.GroupVersionKind().Kind == strings.Title(SplitGVK[2]) && (resource.GroupVersionKind().Version == SplitGVK[1] || SplitGVK[1] == "*") {
return true
}
}

View file

@ -2,6 +2,7 @@ package policy
import (
"errors"
"strings"
"sync"
"time"
@ -199,19 +200,21 @@ func buildKey(policy, pv, kind, ns, name, rv string) string {
return policy + "/" + pv + "/" + kind + "/" + ns + "/" + name + "/" + rv
}
func (pc *PolicyController) processExistingKinds(kind []string, policy *kyverno.ClusterPolicy, rule kyverno.Rule, logger logr.Logger) {
func (pc *PolicyController) processExistingKinds(kinds []string, policy *kyverno.ClusterPolicy, rule kyverno.Rule, logger logr.Logger) {
for _, k := range kind {
logger = logger.WithValues("rule", rule.Name, "kind", k)
_, err := pc.rm.GetScope(k)
for _, kind := range kinds {
logger = logger.WithValues("rule", rule.Name, "kind", kind)
_, err := pc.rm.GetScope(kind)
if err != nil {
gv, k := common.GetKindFromGVK(k)
resourceSchema, _, err := pc.client.DiscoveryClient.FindResource(gv, k)
if err != nil {
logger.Error(err, "failed to find resource", "kind", k)
continue
gv, k := common.GetKindFromGVK(kind)
if !strings.Contains(k, "*") {
resourceSchema, _, err := pc.client.DiscoveryClient.FindResource(gv, k)
if err != nil {
logger.Error(err, "failed to find resource", "kind", k)
continue
}
pc.rm.RegisterScope(k, resourceSchema.Namespaced)
}
pc.rm.RegisterScope(k, resourceSchema.Namespaced)
}
// this tracker would help to ensure that even for multiple namespaces, duplicate metric are not generated
@ -219,10 +222,10 @@ func (pc *PolicyController) processExistingKinds(kind []string, policy *kyverno.
if policy.Namespace != "" {
ns := policy.Namespace
pc.applyAndReportPerNamespace(policy, k, ns, rule, logger.WithValues("kind", k).WithValues("ns", ns), &metricRegisteredTracker)
pc.applyAndReportPerNamespace(policy, kind, ns, rule, logger.WithValues("kind", kind).WithValues("ns", ns), &metricRegisteredTracker)
continue
}
pc.applyAndReportPerNamespace(policy, k, "", rule, logger.WithValues("kind", k), &metricRegisteredTracker)
pc.applyAndReportPerNamespace(policy, kind, "", rule, logger.WithValues("kind", kind), &metricRegisteredTracker)
}
}

View file

@ -1499,7 +1499,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) && !strings.Contains(kind, "*") {
_, _, err := client.DiscoveryClient.FindResource(gv, k)
if err != nil {
return fmt.Errorf("unable to convert GVK to GVR, %s, err: %s", kinds, err)

View file

@ -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 ContainsPod(s, kind)
}
// ContainsNamepace check if namespace satisfies any list of pattern(regex)
func ContainsNamepace(patterns []string, ns string) bool {
return contains(patterns, ns, compareNamespaces)

View file

@ -736,7 +736,11 @@ func (m *webhookConfigManager) mergeWebhook(dst *webhook, policy *kyverno.Cluste
m.log.Error(err, "unable to convert GVK to GVR", "GVK", gvk)
continue
}
gvrList = append(gvrList, gvr)
if strings.Contains(gvk, "*") {
gvrList = append(gvrList, schema.GroupVersionResource{Group: gvr.Group, Version: "*", Resource: gvr.Resource})
} else {
gvrList = append(gvrList, gvr)
}
}
}
}

View file

@ -0,0 +1,16 @@
name: test-simple
policies:
- policy.yaml
resources:
- resources.yaml
results:
- policy: check-deprecated-api
rule: validate-v1-25-removal
resource: hello
kind: CronJob
status: skip
- policy: check-deprecated-api
rule: validate-v1-25-removal
resource: hello-fail
kind: CronJob
status: fail

View file

@ -0,0 +1,34 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-deprecated-api
annotations:
policies.kyverno.io/title: Check deprecated APIs
policies.kyverno.io/category: Best Practices
policies.kyverno.io/subject: Kubernetes APIs
policies.kyverno.io/description: >-
Kubernetes APIs are sometimes deprecated and removed after a few releases.
As a best practice, older API versions should be replaced with newer versions.
This policy validates for APIs that are deprecated or scheduled for removal.
Note that checking for some of these resources may require modifying the Kyverno
ConfigMap to remove filters.
spec:
validationFailureAction: enforce
background: true
rules:
- name: validate-v1-25-removal
match:
resources:
kinds:
- batch/*/CronJob
preconditions:
all:
- key: "{{request.object.apiVersion}}"
operator: In
value:
- batch/v1beta1
validate:
message: >-
{{ request.object.apiVersion }}/{{ request.object.kind }} is deprecated and will be removed in v1.25.
See: https://kubernetes.io/docs/reference/using-api/deprecation-guide/
deny: {}

View file

@ -0,0 +1,38 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello-fail
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure