1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-13 19:28:55 +00:00

- update report summary to optional; - generate clusterPolicyReport; - remove reportRequests after merged to report

This commit is contained in:
Shuting Zhao 2020-10-27 18:28:30 -07:00
parent 0c46b5700b
commit 63a8d89c8d
15 changed files with 308 additions and 162 deletions

View file

@ -592,12 +592,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1
@ -1002,12 +996,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1
@ -1665,12 +1653,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1
@ -2075,12 +2057,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1

View file

@ -321,12 +321,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1

View file

@ -318,12 +318,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1

View file

@ -320,12 +320,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1

View file

@ -318,12 +318,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1

View file

@ -597,12 +597,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1
@ -1007,12 +1001,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1
@ -1670,12 +1658,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1
@ -2080,12 +2062,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1

View file

@ -597,12 +597,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1
@ -1007,12 +1001,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1
@ -1670,12 +1658,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1
@ -2080,12 +2062,6 @@ spec:
description: Warn provides the count of unscored policies whose requirements
were not met
type: integer
required:
- Error
- Fail
- Pass
- Skip
- Warn
type: object
type: object
version: v1alpha1

1
go.mod
View file

@ -11,6 +11,7 @@ require (
github.com/aws/aws-sdk-go v1.28.9 // indirect
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b // indirect
github.com/cornelk/hashmap v1.0.1
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0
github.com/docker/go-connections v0.4.0 // indirect

4
go.sum
View file

@ -128,6 +128,8 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cornelk/hashmap v1.0.1 h1:RXGcy29hEdLLV8T6aK4s+BAd4tq4+3Hq50N2GoG0uIg=
github.com/cornelk/hashmap v1.0.1/go.mod h1:8wbysTUDnwJGrPZ1Iwsou3m+An6sldFrJItjRhfegCw=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
@ -135,6 +137,8 @@ github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/siphash v1.1.0 h1:1Rs9eTUlZLPBEvV+2sTaM8O0NWn0ppbgqS7p11aWawI=
github.com/dchest/siphash v1.1.0/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=

View file

@ -22,26 +22,34 @@ import (
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
const (
StatusPass = "Pass"
StatusFail = "Fail"
StatusPass = "Pass"
StatusFail = "Fail"
StatusWarn = "Warn"
StatusError = "Error"
StatusSkip = "Skip"
)
// PolicyReportSummary provides a status count summary
type PolicyReportSummary struct {
// Pass provides the count of policies whose requirements were met
// +optional
Pass int `json:"Pass"`
// Fail provides the count of policies whose requirements were not met
// +optional
Fail int `json:"Fail"`
// Warn provides the count of unscored policies whose requirements were not met
// +optional
Warn int `json:"Warn"`
// Error provides the count of policies that could not be evaluated
// +optional
Error int `json:"Error"`
// Skip indicates the count of policies that were not selected for evaluation
// +optional
Skip int `json:"Skip"`
}

View file

@ -1,11 +1,27 @@
// +build !ignore_autogenerated
// Code generated by controller-gen. DO NOT EDIT.
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package v1alpha1
import (
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
@ -37,6 +53,7 @@ func (in *ClusterPolicyReport) DeepCopyInto(out *ClusterPolicyReport) {
}
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterPolicyReport.
@ -69,6 +86,7 @@ func (in *ClusterPolicyReportList) DeepCopyInto(out *ClusterPolicyReportList) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterPolicyReportList.
@ -116,6 +134,7 @@ func (in *ClusterReportRequest) DeepCopyInto(out *ClusterReportRequest) {
}
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterReportRequest.
@ -148,6 +167,7 @@ func (in *ClusterReportRequestList) DeepCopyInto(out *ClusterReportRequestList)
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterReportRequestList.
@ -195,6 +215,7 @@ func (in *PolicyReport) DeepCopyInto(out *PolicyReport) {
}
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyReport.
@ -227,6 +248,7 @@ func (in *PolicyReportList) DeepCopyInto(out *PolicyReportList) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyReportList.
@ -273,6 +295,7 @@ func (in *PolicyReportResult) DeepCopyInto(out *PolicyReportResult) {
(*out)[key] = val
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyReportResult.
@ -288,6 +311,7 @@ func (in *PolicyReportResult) DeepCopy() *PolicyReportResult {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PolicyReportSummary) DeepCopyInto(out *PolicyReportSummary) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyReportSummary.
@ -327,6 +351,7 @@ func (in *ReportRequest) DeepCopyInto(out *ReportRequest) {
}
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReportRequest.
@ -359,6 +384,7 @@ func (in *ReportRequestList) DeepCopyInto(out *ReportRequestList) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReportRequestList.

View file

@ -9,6 +9,7 @@ import (
report "github.com/kyverno/kyverno/pkg/api/policyreport/v1alpha1"
"github.com/kyverno/kyverno/pkg/common"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/utils"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@ -61,6 +62,10 @@ func NewBuilder() *requestBuilder {
func (pvb *requestBuilder) build(info Info) (*unstructured.Unstructured, error) {
results := []*report.PolicyReportResult{}
for _, rule := range info.Rules {
if rule.Type != utils.Validation.String() {
continue
}
result := &report.PolicyReportResult{
Policy: info.PolicyName,
Resources: []*v1.ObjectReference{

View file

@ -0,0 +1,110 @@
package policyreport
import (
"fmt"
"reflect"
"github.com/cornelk/hashmap"
report "github.com/kyverno/kyverno/pkg/api/policyreport/v1alpha1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func updateResults(oldReport, newReport map[string]interface{}) (map[string]interface{}, error) {
oldResults := hashResults(oldReport)
newresults := newReport["results"].([]interface{})
for _, res := range newresults {
resMap := res.(map[string]interface{})
if key, ok := generateHashKey(resMap); ok {
oldResults.Set(key, res)
}
}
results := getResultsFromHash(oldResults)
if err := unstructured.SetNestedSlice(newReport, results, "results"); err != nil {
return nil, err
}
summary := updateSummary(results)
if err := unstructured.SetNestedMap(newReport, summary, "summary"); err != nil {
return nil, err
}
return newReport, nil
}
func hashResults(policyReport map[string]interface{}) *hashmap.HashMap {
resultsHash := &hashmap.HashMap{}
results, ok := policyReport["results"]
if !ok {
return resultsHash
}
for _, result := range results.([]interface{}) {
if key, ok := generateHashKey(result.(map[string]interface{})); ok {
resultsHash.Set(key, result)
}
}
return resultsHash
}
func getResultsFromHash(resHash *hashmap.HashMap) []interface{} {
results := make([]interface{}, 0)
for result := range resHash.Iter() {
if reflect.DeepEqual(result, hashmap.KeyValue{}) {
continue
}
results = append(results, result.Value.(map[string]interface{}))
}
return results
}
func generateHashKey(result map[string]interface{}) (string, bool) {
resources := result["resources"].([]interface{})
if len(resources) < 1 {
return "", false
}
resource := resources[0].(map[string]interface{})
return fmt.Sprintf(
"%s-%s-%s-%s-%s",
result["policy"],
result["rule"],
resource["name"],
resource["namespace"],
resource["name"]), true
}
func updateSummary(results []interface{}) map[string]interface{} {
summary := make(map[string]interface{}, 5)
for _, result := range results {
typedResult, ok := result.(map[string]interface{})
if !ok {
continue
}
switch typedResult["status"].(string) {
case report.StatusPass:
pass, _ := summary["Pass"].(int64)
summary["Pass"] = pass + 1
case report.StatusFail:
fail, _ := summary["Fail"].(int64)
summary["Fail"] = fail + 1
case "Warn":
warn, _ := summary["Warn"].(int64)
summary["warn"] = warn + 1
case "Error":
e, _ := summary["Error"].(int64)
summary["Error"] = e + 1
case "Skip":
skip, _ := summary["Skip"].(int64)
summary["Skip"] = skip + 1
}
}
return summary
}

View file

@ -75,14 +75,12 @@ func NewReportGenerator(
cache.ResourceEventHandlerFuncs{
AddFunc: gen.addReportRequest,
UpdateFunc: gen.updateReportRequest,
DeleteFunc: gen.deleteReportRequest,
})
clusterReportReqInformer.Informer().AddEventHandler(
cache.ResourceEventHandlerFuncs{
AddFunc: gen.addClusterReportRequest,
UpdateFunc: gen.updateClusterReportRequest,
DeleteFunc: gen.deleteClusterReportRequest,
})
gen.clusterReportLister = clusterReportInformer.Lister()
@ -123,19 +121,21 @@ func (g *ReportGenerator) updateReportRequest(old interface{}, cur interface{})
g.queue.Add(ns)
}
func (g *ReportGenerator) deleteReportRequest(obj interface{}) {
r := obj.(*report.ReportRequest)
ns := r.GetNamespace()
if ns == "" {
ns = "default"
}
g.queue.Add(ns)
func (g *ReportGenerator) addClusterReportRequest(obj interface{}) {
_ = obj.(*report.ClusterReportRequest)
g.queue.Add("")
}
func (g *ReportGenerator) addClusterReportRequest(obj interface{}) {}
func (g *ReportGenerator) updateClusterReportRequest(old interface{}, cur interface{}) {}
func (g *ReportGenerator) deleteClusterReportRequest(obj interface{}) {}
func (g *ReportGenerator) updateClusterReportRequest(old interface{}, cur interface{}) {
oldReq := old.(*report.ClusterReportRequest)
curReq := cur.(*report.ClusterReportRequest)
if reflect.DeepEqual(oldReq.Results, curReq.Results) {
return
}
g.queue.Add("")
}
// Run starts the workers
func (g *ReportGenerator) Run(workers int, stopCh <-chan struct{}) {
@ -201,66 +201,124 @@ func (g *ReportGenerator) handleErr(err error, key interface{}) {
logger.Error(err, "dropping key out of the queue", "key", key)
}
// syncHandler reconciles clusterPolicyReport if namespace == ""
// otherwise it updates policyrReport
func (g *ReportGenerator) syncHandler(namespace string) error {
log := g.log.WithName("sync")
// cluster policy report
if namespace == clusterpolicyreport {
return nil
}
// policy report
ns, err := g.nsLister.Get(namespace)
if err != nil {
return fmt.Errorf("unable to get namespace %s: %v", ns.GetName(), err)
}
new, err := g.aggregateReports(ns)
new, aggregatedRequests, err := g.aggregateReports(namespace)
if err != nil {
return fmt.Errorf("failed to aggregate reportRequest results %v", err)
}
old, err := g.reportLister.PolicyReports(namespace).Get(generatePolicyReportName((namespace)))
if err != nil {
if apierrors.IsNotFound(err) && new != nil {
if _, err := g.dclient.CreateResource(new.GetAPIVersion(), new.GetKind(), new.GetNamespace(), new, false); err != nil {
return fmt.Errorf("failed to create policyReport: %v", err)
var old interface{}
if namespace != "" {
old, err = g.reportLister.PolicyReports(namespace).Get(generatePolicyReportName((namespace)))
if err != nil {
if apierrors.IsNotFound(err) && new != nil {
if _, err := g.dclient.CreateResource(new.GetAPIVersion(), new.GetKind(), new.GetNamespace(), new, false); err != nil {
return fmt.Errorf("failed to create policyReport: %v", err)
}
log.V(2).Info("successfully created policyReport", "namespace", new.GetNamespace(), "name", new.GetName())
g.cleanupReportRequets(aggregatedRequests)
return nil
}
log.V(1).Info("successfully created policyReport", "namespace", new.GetNamespace(), "name", new.GetName())
return nil
return fmt.Errorf("unable to get policyReport: %v", err)
}
} else {
old, err = g.clusterReportLister.Get(generatePolicyReportName((namespace)))
if err != nil {
if apierrors.IsNotFound(err) && new != nil {
if _, err := g.dclient.CreateResource(new.GetAPIVersion(), new.GetKind(), new.GetNamespace(), new, false); err != nil {
return fmt.Errorf("failed to create ClusterPolicyReport: %v", err)
}
return fmt.Errorf("unable to get policyReport: %v", err)
log.V(2).Info("successfully created ClusterPolicyReport")
g.cleanupReportRequets(aggregatedRequests)
return nil
}
return fmt.Errorf("unable to get ClusterPolicyReport: %v", err)
}
}
return g.updateReport(old, new)
if err := g.updateReport(old, new); err != nil {
return err
}
g.cleanupReportRequets(aggregatedRequests)
return nil
}
func (g *ReportGenerator) aggregateReports(ns *v1.Namespace) (*unstructured.Unstructured, error) {
report := &unstructured.Unstructured{}
defer report.SetCreationTimestamp(metav1.Now())
if ns == nil {
func (g *ReportGenerator) aggregateReports(namespace string) (
report *unstructured.Unstructured, aggregatedRequests interface{}, err error) {
if namespace == "" {
requests, err := g.clusterReportLister.List(labels.Everything())
if err != nil {
return nil, nil, fmt.Errorf("unable to list ClusterReportRequests within: %v", err)
}
if report, aggregatedRequests, err = mergeRequests(nil, requests); err != nil {
return nil, nil, fmt.Errorf("unable to merge ClusterReportRequests results: %v", err)
}
} else {
ns, err := g.nsLister.Get(namespace)
if err != nil {
return nil, nil, fmt.Errorf("unable to get namespace %s: %v", ns.GetName(), err)
}
requests, err := g.reportRequestLister.ReportRequests(ns.GetName()).List(labels.Everything())
if err != nil {
return nil, fmt.Errorf("unable to list reportRequests within namespace %s: %v", ns, err)
return nil, nil, fmt.Errorf("unable to list reportRequests within namespace %s: %v", ns, err)
}
if report, err = mergeRequests(ns, requests); err != nil {
return nil, fmt.Errorf("unable to merge results: %v", err)
if report, aggregatedRequests, err = mergeRequests(ns, requests); err != nil {
return nil, nil, fmt.Errorf("unable to merge results: %v", err)
}
}
return report, nil
return report, aggregatedRequests, nil
}
func mergeRequests(ns *v1.Namespace, requests []*report.ReportRequest) (*unstructured.Unstructured, error) {
func mergeRequests(ns *v1.Namespace, requestsGeneral interface{}) (*unstructured.Unstructured, interface{}, error) {
results := []*report.PolicyReportResult{}
if len(requests) > 0 {
if requests, ok := requestsGeneral.([]*report.ClusterReportRequest); ok {
aggregatedRequests := []*report.ClusterReportRequest{}
for _, request := range requests {
if request.GetDeletionTimestamp() != nil {
continue
}
results = append(results, request.Results...)
aggregatedRequests = append(aggregatedRequests, request)
}
report := &report.ClusterPolicyReport{
Results: results,
Summary: calculateSummary(results),
}
obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(report)
if err != nil {
return nil, aggregatedRequests, err
}
req := &unstructured.Unstructured{Object: obj}
setReport(req, nil)
return req, aggregatedRequests, nil
}
if requests, ok := requestsGeneral.([]*report.ReportRequest); ok {
aggregatedRequests := []*report.ReportRequest{}
for _, request := range requests {
if request.GetDeletionTimestamp() != nil {
continue
}
results = append(results, request.Results...)
aggregatedRequests = append(aggregatedRequests, request)
}
report := &report.PolicyReport{
@ -270,15 +328,15 @@ func mergeRequests(ns *v1.Namespace, requests []*report.ReportRequest) (*unstruc
obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(report)
if err != nil {
return nil, err
return nil, aggregatedRequests, err
}
req := &unstructured.Unstructured{Object: obj}
setReport(req, ns)
return req, nil
return req, aggregatedRequests, nil
}
return nil, nil
return nil, nil, nil
}
func setReport(report *unstructured.Unstructured, ns *v1.Namespace) {
@ -310,9 +368,25 @@ func setReport(report *unstructured.Unstructured, ns *v1.Namespace) {
}
func (g *ReportGenerator) updateReport(old interface{}, new *unstructured.Unstructured) (err error) {
if new == nil {
g.log.V(4).Info("empty report to update")
return nil
}
oldUnstructed := make(map[string]interface{})
if oldTyped, ok := old.(*report.PolicyReport); ok {
if oldTyped.GetDeletionTimestamp() != nil || new == nil { // no report request in ns
if oldTyped, ok := old.(*report.ClusterPolicyReport); ok {
if oldTyped.GetDeletionTimestamp() != nil {
return g.dclient.DeleteResource(oldTyped.APIVersion, "ClusterPolicyReport", oldTyped.Namespace, oldTyped.Name, false)
}
if oldUnstructed, err = runtime.DefaultUnstructuredConverter.ToUnstructured(oldTyped); err != nil {
return fmt.Errorf("unable to convert clusterPolicyReport: %v", err)
}
new.SetUID(oldTyped.GetUID())
new.SetResourceVersion(oldTyped.GetResourceVersion())
} else if oldTyped, ok := old.(*report.PolicyReport); ok {
if oldTyped.GetDeletionTimestamp() != nil {
return g.dclient.DeleteResource(oldTyped.APIVersion, "PolicyReport", oldTyped.Namespace, oldTyped.Name, false)
}
@ -320,21 +394,16 @@ func (g *ReportGenerator) updateReport(old interface{}, new *unstructured.Unstru
return fmt.Errorf("unable to convert policyReport: %v", err)
}
new.SetUID(oldTyped.GetUID())
new.SetResourceVersion(oldTyped.GetResourceVersion())
} else {
oldTyped := old.(*report.ClusterReportRequest)
if oldTyped.GetDeletionTimestamp() != nil || new == nil {
return g.dclient.DeleteResource(oldTyped.APIVersion, "ClusterPolicyReport", oldTyped.Namespace, oldTyped.Name, false)
}
if oldUnstructed, err = runtime.DefaultUnstructuredConverter.ToUnstructured(oldTyped); err != nil {
return fmt.Errorf("unable to convert clusterPolicyReport: %v", err)
}
new.SetUID(oldTyped.GetUID())
new.SetResourceVersion(oldTyped.GetResourceVersion())
}
obj, err := updateResults(oldUnstructed, new.UnstructuredContent())
if err != nil {
return fmt.Errorf("failed to update results entry: %v", err)
}
new.Object = obj
if !hasResultsChanged(oldUnstructed, new.UnstructuredContent()) {
g.log.V(4).Info("unchanged policy report", "namespace", new.GetNamespace(), "name", new.GetName())
return nil
@ -344,6 +413,25 @@ func (g *ReportGenerator) updateReport(old interface{}, new *unstructured.Unstru
return fmt.Errorf("failed to update policy report: %v", err)
}
g.log.V(1).Info("successfully updated policy report", "kind", new.GetKind(), "namespace", new.GetNamespace(), "name", new.GetName())
g.log.V(3).Info("successfully updated policy report", "kind", new.GetKind(), "namespace", new.GetNamespace(), "name", new.GetName())
return
}
func (g *ReportGenerator) cleanupReportRequets(requestsGeneral interface{}) {
defer g.log.V(2).Info("successfully cleaned up report requests ")
if requests, ok := requestsGeneral.([]*report.ReportRequest); ok {
for _, request := range requests {
if err := g.dclient.DeleteResource(request.APIVersion, "ReportRequest", request.Namespace, request.Name, false); err != nil {
g.log.Error(err, "failed to delete report request")
}
}
}
if requests, ok := requestsGeneral.([]*report.ClusterReportRequest); ok {
for _, request := range requests {
if err := g.dclient.DeleteResource(request.APIVersion, "ClusterReportRequest", request.Namespace, request.Name, false); err != nil {
g.log.Error(err, "failed to delete clusterReportRequest")
}
}
}
}

View file

@ -88,7 +88,7 @@ func buildPVInfo(er response.EngineResponse) Info {
func buildViolatedRules(er response.EngineResponse) []kyverno.ViolatedRule {
var violatedRules []kyverno.ViolatedRule
for _, rule := range er.PolicyResponse.Rules {
if os.Getenv("POLICY-TYPE") != common.PolicyReport {
if os.Getenv("POLICY-TYPE") == common.PolicyViolation {
if rule.Success {
continue
}