mirror of
https://github.com/kyverno/kyverno.git
synced 2025-01-20 18:52:16 +00:00
* support for deprecated API's * add testcase * update condition * fix logic
This commit is contained in:
parent
f43d73adf2
commit
fbcc329680
9 changed files with 119 additions and 15 deletions
|
@ -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]
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
16
test/cli/test/depecated_apis/kyverno-test.yaml
Normal file
16
test/cli/test/depecated_apis/kyverno-test.yaml
Normal 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
|
34
test/cli/test/depecated_apis/policy.yaml
Normal file
34
test/cli/test/depecated_apis/policy.yaml
Normal 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: {}
|
38
test/cli/test/depecated_apis/resources.yaml
Normal file
38
test/cli/test/depecated_apis/resources.yaml
Normal 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
|
Loading…
Add table
Reference in a new issue