1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

fix: improve banned types management in reports (#4953)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com>
This commit is contained in:
Charles-Edouard Brétéché 2022-10-14 17:20:30 +02:00 committed by GitHub
parent e749907302
commit 47780bf37f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 11 deletions

View file

@ -152,7 +152,13 @@ func (c serverPreferredResources) findResource(apiVersion string, kind string) (
logger.Error(err, "failed to parse GV", "groupVersion", serverResource.GroupVersion)
return nil, schema.GroupVersionResource{}, err
}
// We potentially need to fix Group and Version with what the list is for
if resource.Group == "" {
resource.Group = gv.Group
}
if resource.Version == "" {
resource.Version = gv.Version
}
return &resource, gv.WithResource(resource.Name), nil
}
}

View file

@ -126,24 +126,27 @@ func (c *controller) updateDynamicWatchers(ctx context.Context) error {
return err
}
kinds := utils.BuildKindSet(logger, utils.RemoveNonValidationPolicies(logger, append(clusterPolicies, policies...)...)...)
gvrs := map[string]schema.GroupVersionResource{}
gvrs := map[schema.GroupVersionKind]schema.GroupVersionResource{}
for _, kind := range kinds.List() {
apiVersion, kind := kubeutils.GetKindFromGVK(kind)
apiResource, gvr, err := c.client.Discovery().FindResource(apiVersion, kind)
if err != nil {
logger.Error(err, "failed to get gvr from kind", "kind", kind)
} else if apiVersion == "" && kind == "Event" {
logger.Info("Event cannot be an owner, skipping", "apiVersion", apiVersion, "kind", kind)
} else {
if pkgutils.ContainsString(apiResource.Verbs, "list") && pkgutils.ContainsString(apiResource.Verbs, "watch") {
gvrs[kind] = gvr
gvk := schema.GroupVersionKind{Group: apiResource.Group, Version: apiResource.Version, Kind: apiResource.Kind}
if !reportutils.IsGvkSupported(gvk) {
logger.Info("kind is not supported", "gvk", gvk)
} else {
logger.Info("list/watch not supported for kind", "kind", kind)
if pkgutils.ContainsString(apiResource.Verbs, "list") && pkgutils.ContainsString(apiResource.Verbs, "watch") {
gvrs[gvk] = gvr
} else {
logger.Info("list/watch not supported for kind", "kind", kind)
}
}
}
}
dynamicWatchers := map[schema.GroupVersionResource]*watcher{}
for kind, gvr := range gvrs {
for gvk, gvr := range gvrs {
// if we already have one, transfer it to the new map
if c.dynamicWatchers[gvr] != nil {
dynamicWatchers[gvr] = c.dynamicWatchers[gvr]
@ -156,7 +159,7 @@ func (c *controller) updateDynamicWatchers(ctx context.Context) error {
} else {
w := &watcher{
watcher: watchInterface,
gvk: gvr.GroupVersion().WithKind(kind),
gvk: gvk,
hashes: map[types.UID]Resource{},
}
go func() {

View file

@ -0,0 +1,20 @@
package report
import (
corev1 "k8s.io/api/core/v1"
eventsv1 "k8s.io/api/events/v1"
eventsv1beta1 "k8s.io/api/events/v1beta1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// bannedOwners are GVKs that are not allowed to be owners of other resources
var bannedOwners = map[schema.GroupVersionKind]struct{}{
corev1.SchemeGroupVersion.WithKind("Event"): {},
eventsv1.SchemeGroupVersion.WithKind("Event"): {},
eventsv1beta1.SchemeGroupVersion.WithKind("Event"): {},
}
func IsGvkSupported(gvk schema.GroupVersionKind) bool {
_, exists := bannedOwners[gvk]
return !exists
}

View file

@ -20,6 +20,7 @@ import (
admissionv1 "k8s.io/api/admission/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)
type ValidationHandler interface {
@ -163,17 +164,21 @@ func (v *validationHandler) handleAudit(
if !v.admissionReports {
return
}
// we don't need reports for deletions and when it's about sub resources
// we don't need reports for deletions and when it's about sub resources
if request.Operation == admissionv1.Delete || request.SubResource != "" {
return
}
// check if the resource supports reporting
if !reportutils.IsGvkSupported(schema.GroupVersionKind(request.Kind)) {
return
}
responses, err := v.buildAuditResponses(resource, request, namespaceLabels)
if err != nil {
v.log.Error(err, "failed to build audit responses")
}
responses = append(responses, engineResponses...)
report := reportutils.NewAdmissionReport(resource, request, request.Kind, responses...)
// if it's not a creation, the resource already exists, we can set the owner
// if it's not a creation, the resource already exists, we can set the owner
if request.Operation != admissionv1.Create {
gv := metav1.GroupVersion{Group: request.Kind.Group, Version: request.Kind.Version}
controllerutils.SetOwner(report, gv.String(), request.Kind.Kind, resource.GetName(), resource.GetUID())