mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-05 15:37:19 +00:00
support for deprecated API's (#3439)
* support for deprecated API's * add testcase * update condition * fix logic
This commit is contained in:
parent
1b10f18086
commit
e268be9e88
8 changed files with 113 additions and 15 deletions
|
@ -87,6 +87,9 @@ func GetKindFromGVK(str string) (apiVersion string, kind string) {
|
||||||
if strings.Count(str, "/") == 1 {
|
if strings.Count(str, "/") == 1 {
|
||||||
return splitString[0], splitString[1]
|
return splitString[0], splitString[1]
|
||||||
}
|
}
|
||||||
|
if splitString[1] == "*" {
|
||||||
|
return "", splitString[2]
|
||||||
|
}
|
||||||
return splitString[0] + "/" + splitString[1], splitString[2]
|
return splitString[0] + "/" + splitString[1], splitString[2]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ func checkKind(kinds []string, resource unstructured.Unstructured) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package policy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -199,19 +200,21 @@ func buildKey(policy, pv, kind, ns, name, rv string) string {
|
||||||
return policy + "/" + pv + "/" + kind + "/" + ns + "/" + name + "/" + rv
|
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 {
|
for _, kind := range kinds {
|
||||||
logger = logger.WithValues("rule", rule.Name, "kind", k)
|
logger = logger.WithValues("rule", rule.Name, "kind", kind)
|
||||||
_, err := pc.rm.GetScope(k)
|
_, err := pc.rm.GetScope(kind)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
gv, k := common.GetKindFromGVK(k)
|
gv, k := common.GetKindFromGVK(kind)
|
||||||
resourceSchema, _, err := pc.client.DiscoveryClient.FindResource(gv, k)
|
if !strings.Contains(k, "*") {
|
||||||
if err != nil {
|
resourceSchema, _, err := pc.client.DiscoveryClient.FindResource(gv, k)
|
||||||
logger.Error(err, "failed to find resource", "kind", k)
|
if err != nil {
|
||||||
continue
|
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
|
// 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 != "" {
|
if policy.Namespace != "" {
|
||||||
ns := 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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
pc.applyAndReportPerNamespace(policy, k, "", rule, logger.WithValues("kind", k), &metricRegisteredTracker)
|
pc.applyAndReportPerNamespace(policy, kind, "", rule, logger.WithValues("kind", kind), &metricRegisteredTracker)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1264,7 +1264,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")
|
return fmt.Errorf("kind and match resource kind should not be the same")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !mock && !utils.SkipSubResources(k) {
|
if !mock && !utils.SkipSubResources(k) && !strings.Contains(kind, "*") {
|
||||||
_, _, err := client.DiscoveryClient.FindResource(gv, k)
|
_, _, err := client.DiscoveryClient.FindResource(gv, k)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to convert GVK to GVR, %s, err: %s", kinds, err)
|
return fmt.Errorf("unable to convert GVK to GVR, %s, err: %s", kinds, err)
|
||||||
|
|
|
@ -805,7 +805,11 @@ func (m *webhookConfigManager) mergeWebhook(dst *webhook, policy *kyverno.Cluste
|
||||||
m.log.Error(err, "unable to convert GVK to GVR", "GVK", gvk)
|
m.log.Error(err, "unable to convert GVK to GVR", "GVK", gvk)
|
||||||
continue
|
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