1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-06 07:57:07 +00:00

distributed labels in group, version, and resource so it doesn't exceed (#11620)

* change label to hash if exceed 63 limit char

Signed-off-by: Mohd Kamaal <mohdkamaal2019@gmail.com>

* Distribute GVR labels into 'group', 'version', and 'resource' to avoid exceeding character limits

Signed-off-by: Mohd Kamaal <mohdkamaal2019@gmail.com>

---------

Signed-off-by: Mohd Kamaal <mohdkamaal2019@gmail.com>
Co-authored-by: Kamaal <kamaal@macs-MacBook-Air.local>
Co-authored-by: Vishal Choudhary <vishal.choudhary@nirmata.com>
This commit is contained in:
Mohd Kamaal 2024-12-16 10:36:34 +05:30 committed by GitHub
parent 3b6f4bdc2c
commit e771896541
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 188 additions and 6 deletions

View file

@ -115,7 +115,13 @@ func SetResourceUid(report reportsv1.ReportInterface, uid types.UID) {
}
func SetResourceGVR(report reportsv1.ReportInterface, gvr schema.GroupVersionResource) {
if gvr.Group != "" {
gvrString := gvr.Resource + "." + gvr.Version + "." + gvr.Group
if len(gvrString) > 63 {
controllerutils.SetLabel(report, LabelResourceGroup, gvr.Group)
controllerutils.SetLabel(report, LabelResourceVersion, gvr.Version)
controllerutils.SetLabel(report, AnnotationResourceName, gvr.Resource)
} else if gvr.Group != "" {
controllerutils.SetLabel(report, LabelResourceGVR, gvr.Resource+"."+gvr.Version+"."+gvr.Group)
} else {
controllerutils.SetLabel(report, LabelResourceGVR, gvr.Resource+"."+gvr.Version)
@ -181,16 +187,29 @@ func GetResourceUid(report metav1.Object) types.UID {
}
func GetResourceGVR(report metav1.Object) schema.GroupVersionResource {
arg := controllerutils.GetLabel(report, LabelResourceGVR)
dots := strings.Count(arg, ".")
group := controllerutils.GetLabel(report, LabelResourceGroup)
version := controllerutils.GetLabel(report, LabelResourceVersion)
resource := controllerutils.GetLabel(report, AnnotationResourceName)
GVRstring := group + version + resource
// If all three parts exist, return the GVR
if group != "" && version != "" && resource != "" {
if len(GVRstring) > 63 {
return schema.GroupVersionResource{Group: group, Version: version, Resource: resource}
}
}
// Fallback to the old combined label
combinedGVR := controllerutils.GetLabel(report, LabelResourceGVR)
dots := strings.Count(combinedGVR, ".")
if dots >= 2 {
s := strings.SplitN(arg, ".", 3)
s := strings.SplitN(combinedGVR, ".", 3)
return schema.GroupVersionResource{Group: s[2], Version: s[1], Resource: s[0]}
} else if dots == 1 {
s := strings.SplitN(arg, ".", 2)
s := strings.SplitN(combinedGVR, ".", 2)
return schema.GroupVersionResource{Version: s[1], Resource: s[0]}
}
return schema.GroupVersionResource{Resource: arg}
return schema.GroupVersionResource{Resource: combinedGVR}
}
func GetResourceNamespaceAndName(report metav1.Object) (string, string) {

View file

@ -0,0 +1,20 @@
## Description
This test ensures that the EphemeralReport is generated successfully at admission, even when long GVR (Group, Version, Resource) labels are used. Kyverno handles this by distributing the GVR components (group, version, resource) into separate labels, ensuring they fit within Kubernetes' 63-character limit.
Kubernetes enforces the 63-character label limit during resource creation, and Kyverno ensures that the GVR components are split appropriately into distinct labels to avoid exceeding this limit.
## Why It's Important
If the combined length of GVR identifiers exceeds the 63-character limit, Kubernetes won't create the EphemeralReport at admission. Kyverno addresses this by:
Splitting the GVR components into separate labels, ensuring no label exceeds the size limit.
This approach enables the successful creation of EphemeralReport at admission.
## Expected Behavior
- Kyverno splits the GVR components (group, version, resource) into separate labels.
- The creation of EphemeralReport at admission will proceed successfully with the labels preserved within size limits.
## Reference Issue(s)
- Kyverno Issue #11547

View file

@ -0,0 +1,30 @@
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
name: test-long-resource-labels
spec:
steps:
- name: create crd
try:
- apply:
file: crd-definition.yaml
- name: create permission
try:
- apply:
file: crd-permission.yaml
- name: apply policy
try:
- apply:
file: policy.yaml
- name: create resource
try:
- apply:
file: resource.yaml
- name: check report
try:
- assert:
file: ephemeral-report.yaml

View file

@ -0,0 +1,25 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: verylongresources.verylonggggggggggggggggggggggggggggggggggggggggroup.example.com
spec:
group: verylonggggggggggggggggggggggggggggggggggggggggroup.example.com
names:
kind: VeryLongResource
listKind: VeryLongResourceList
plural: verylongresources
singular: verylongresource
scope: Namespaced
versions:
- name: verylongversion
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
exampleField:
type: string

View file

@ -0,0 +1,22 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno-reports-controller
rules:
- apiGroups: ["verylonggggggggggggggggggggggggggggggggggggggggroup.example.com"]
resources: ["verylongresources"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kyverno-reports-controller-rolebinding
subjects:
- kind: ServiceAccount
name: kyverno-reports-controller
namespace: kyverno
roleRef:
kind: ClusterRole
name: kyverno-reports-controller
apiGroup: rbac.authorization.k8s.io

View file

@ -0,0 +1,39 @@
apiVersion: v1
items:
- apiVersion: reports.kyverno.io/v1
kind: EphemeralReport
metadata:
annotations:
audit.kyverno.io/resource.name: very-long-resource-name-testing-label-length
generation: 1
labels:
app.kubernetes.io/managed-by: kyverno
audit.kyverno.io/resource.group: verylonggggggggggggggggggggggggggggggggggggggggroup.example.com
audit.kyverno.io/resource.name: verylongresources
audit.kyverno.io/resource.kind: VeryLongResource
audit.kyverno.io/resource.version: verylongversion
audit.kyverno.io/source: admission
ownerReferences:
- apiVersion: verylonggggggggggggggggggggggggggggggggggggggggroup.example.com/verylongversion
kind: VeryLongResource
name: very-long-resource-name-testing-label-length
spec:
owner:
apiVersion: ""
kind: ""
name: ""
uid: ""
results:
- message: 'validation error: Resource must have valid labels. rule check-label-length
failed at path /metadata/labels/team/'
policy: validate-long-resource-labels
result: fail
rule: check-label-length
scored: true
source: kyverno
summary:
error: 0
fail: 1
pass: 0
skip: 0
warn: 0

View file

@ -0,0 +1,19 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: validate-long-resource-labels
spec:
rules:
- name: check-label-length
match:
resources:
kinds:
- VeryLongResource
validate:
message: "Resource must have valid labels."
pattern:
metadata:
labels:
env: "?*"
team: "?*"
failureAction: Audit

View file

@ -0,0 +1,8 @@
apiVersion: verylonggggggggggggggggggggggggggggggggggggggggroup.example.com/verylongversion
kind: VeryLongResource
metadata:
name: very-long-resource-name-testing-label-length
labels:
env: "test-environment"
spec:
exampleField: "exampleValue"