diff --git a/pkg/controllers/report/aggregate/controller.go b/pkg/controllers/report/aggregate/controller.go index 060e0f82a5..7a55e61858 100644 --- a/pkg/controllers/report/aggregate/controller.go +++ b/pkg/controllers/report/aggregate/controller.go @@ -21,6 +21,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" admissionregistrationv1alpha1informers "k8s.io/client-go/informers/admissionregistration/v1alpha1" @@ -121,6 +122,17 @@ func NewController( logger.Error(err, "failed to register event handlers") } } + metadataCache.AddEventHandler(func(eventType resource.EventType, uid types.UID, _ schema.GroupVersionKind, res resource.Resource) { + // if it's a deletion, nothing to do + if eventType == resource.Deleted { + return + } + if res.Namespace == "" { + c.queue.AddAfter(string(uid), enqueueDelay) + } else { + c.queue.AddAfter(res.Namespace+"/"+string(uid), enqueueDelay) + } + }) enqueueFromAdmr := func(obj metav1.Object) { switch reportutils.GetSource(obj) { case "background-scan": @@ -381,7 +393,33 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, _, names if err != nil { return err } - if policyReport != nil { + if policyReport == nil { + return nil + } + admissionReports, backgroundReport, err := c.getReports(ctx, namespace, name) + if err != nil { + return err + } + // aggregate reports + policyMap, err := c.createPolicyMap() + if err != nil { + return err + } + vapMap, err := c.createVapMap() + if err != nil { + return err + } + merged := map[string]policyreportv1alpha2.PolicyReportResult{} + var reports []kyvernov1alpha2.ReportInterface + reports = append(reports, policyReport) + reports = append(reports, backgroundReport) + reports = append(reports, admissionReports...) + mergeReports(policyMap, vapMap, merged, uid, reports...) + var results []policyreportv1alpha2.PolicyReportResult + for _, result := range merged { + results = append(results, result) + } + if len(results) == 0 { if err := deleteReport(ctx, policyReport, c.client); err != nil { return err } diff --git a/pkg/controllers/report/aggregate/utils.go b/pkg/controllers/report/aggregate/utils.go index 7d25ea684b..0250ffe5ce 100644 --- a/pkg/controllers/report/aggregate/utils.go +++ b/pkg/controllers/report/aggregate/utils.go @@ -15,26 +15,27 @@ import ( func mergeReports(policyMap map[string]policyMapEntry, vapMap sets.Set[string], accumulator map[string]policyreportv1alpha2.PolicyReportResult, uid types.UID, reports ...kyvernov1alpha2.ReportInterface) { for _, report := range reports { - if report != nil { - for _, result := range report.GetResults() { - if result.Source == "ValidatingAdmissionPolicy" { - if vapMap != nil && vapMap.Has(result.Policy) { - key := result.Source + "/" + result.Policy + "/" + string(uid) - if rule, exists := accumulator[key]; !exists { - accumulator[key] = result - } else if rule.Timestamp.Seconds < result.Timestamp.Seconds { - accumulator[key] = result - } + if report == nil { + continue + } + for _, result := range report.GetResults() { + if result.Source == "ValidatingAdmissionPolicy" { + if vapMap != nil && vapMap.Has(result.Policy) { + key := result.Source + "/" + result.Policy + "/" + string(uid) + if rule, exists := accumulator[key]; !exists { + accumulator[key] = result + } else if rule.Timestamp.Seconds < result.Timestamp.Seconds { + accumulator[key] = result } - } else { - currentPolicy := policyMap[result.Policy] - if currentPolicy.rules != nil && currentPolicy.rules.Has(result.Rule) { - key := result.Source + "/" + result.Policy + "/" + result.Rule + "/" + string(uid) - if rule, exists := accumulator[key]; !exists { - accumulator[key] = result - } else if rule.Timestamp.Seconds < result.Timestamp.Seconds { - accumulator[key] = result - } + } + } else { + currentPolicy := policyMap[result.Policy] + if currentPolicy.rules != nil && currentPolicy.rules.Has(result.Rule) { + key := result.Source + "/" + result.Policy + "/" + result.Rule + "/" + string(uid) + if rule, exists := accumulator[key]; !exists { + accumulator[key] = result + } else if rule.Timestamp.Seconds < result.Timestamp.Seconds { + accumulator[key] = result } } }