1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-28 02:18:15 +00:00

fix: make alternate reports storage transparent (#9553)

* fix: make alternate reports storage transparent

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

* bg scan

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

* aggregation

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

* aggregation

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

* rm manager

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

* update

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

* fixes

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

* fixes

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

---------

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2024-01-30 15:53:37 +01:00 committed by GitHub
parent 374691d57a
commit 9102753323
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 370 additions and 721 deletions

View file

@ -39,15 +39,18 @@ type EphemeralReportSpec struct {
// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// +kubebuilder:resource:shortName=ephr,categories=kyverno
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="PASS",type=integer,JSONPath=".spec.summary.pass"
// +kubebuilder:printcolumn:name="FAIL",type=integer,JSONPath=".spec.summary.fail"
// +kubebuilder:printcolumn:name="WARN",type=integer,JSONPath=".spec.summary.warn"
// +kubebuilder:printcolumn:name="ERROR",type=integer,JSONPath=".spec.summary.error"
// +kubebuilder:printcolumn:name="SKIP",type=integer,JSONPath=".spec.summary.skip"
// +kubebuilder:printcolumn:name="GVR",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.gvr']"
// +kubebuilder:printcolumn:name="REF",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.name']"
// +kubebuilder:printcolumn:name="AGGREGATE",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/report\\.aggregate']",priority=1
// +kubebuilder:printcolumn:name="Source",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/source']"
// +kubebuilder:printcolumn:name="Group",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.group']"
// +kubebuilder:printcolumn:name="Kind",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.kind']"
// +kubebuilder:printcolumn:name="Owner",type=string,JSONPath=".metadata.annotations['audit\\.kyverno\\.io/resource\\.name']"
// +kubebuilder:printcolumn:name="Pass",type=integer,JSONPath=".spec.summary.pass"
// +kubebuilder:printcolumn:name="Fail",type=integer,JSONPath=".spec.summary.fail"
// +kubebuilder:printcolumn:name="Warn",type=integer,JSONPath=".spec.summary.warn"
// +kubebuilder:printcolumn:name="Error",type=integer,JSONPath=".spec.summary.error"
// +kubebuilder:printcolumn:name="Skip",type=integer,JSONPath=".spec.summary.skip"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="Uid",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.uid']",priority=1
// +kubebuilder:printcolumn:name="Hash",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.hash']",priority=1
// EphemeralReport is the Schema for the EphemeralReports API
type EphemeralReport struct {
@ -74,15 +77,18 @@ func (r *EphemeralReport) SetSummary(summary policyreportv1alpha2.PolicyReportSu
// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// +kubebuilder:resource:scope=Cluster,shortName=cephr,categories=kyverno
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="PASS",type=integer,JSONPath=".spec.summary.pass"
// +kubebuilder:printcolumn:name="FAIL",type=integer,JSONPath=".spec.summary.fail"
// +kubebuilder:printcolumn:name="WARN",type=integer,JSONPath=".spec.summary.warn"
// +kubebuilder:printcolumn:name="ERROR",type=integer,JSONPath=".spec.summary.error"
// +kubebuilder:printcolumn:name="SKIP",type=integer,JSONPath=".spec.summary.skip"
// +kubebuilder:printcolumn:name="GVR",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.gvr']"
// +kubebuilder:printcolumn:name="REF",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.name']"
// +kubebuilder:printcolumn:name="AGGREGATE",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/report\\.aggregate']",priority=1
// +kubebuilder:printcolumn:name="Source",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/source']"
// +kubebuilder:printcolumn:name="Group",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.group']"
// +kubebuilder:printcolumn:name="Kind",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.kind']"
// +kubebuilder:printcolumn:name="Owner",type=string,JSONPath=".metadata.annotations['audit\\.kyverno\\.io/resource\\.name']"
// +kubebuilder:printcolumn:name="Pass",type=integer,JSONPath=".spec.summary.pass"
// +kubebuilder:printcolumn:name="Fail",type=integer,JSONPath=".spec.summary.fail"
// +kubebuilder:printcolumn:name="Warn",type=integer,JSONPath=".spec.summary.warn"
// +kubebuilder:printcolumn:name="Error",type=integer,JSONPath=".spec.summary.error"
// +kubebuilder:printcolumn:name="Skip",type=integer,JSONPath=".spec.summary.skip"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="Uid",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.uid']"
// +kubebuilder:printcolumn:name="Hash",type=string,JSONPath=".metadata.labels['audit\\.kyverno\\.io/resource\\.hash']",priority=1
// ClusterEphemeralReport is the Schema for the ClusterEphemeralReports API
type ClusterEphemeralReport struct {

View file

@ -322,7 +322,6 @@ The chart values are organised per component.
|-----|------|---------|-------------|
| features.admissionReports.enabled | bool | `true` | Enables the feature |
| features.aggregateReports.enabled | bool | `true` | Enables the feature |
| features.alternateReportStorage.enabled | bool | `false` | Enables the feature |
| features.policyReports.enabled | bool | `true` | Enables the feature |
| features.validatingAdmissionPolicyReports.enabled | bool | `false` | Enables the feature |
| features.autoUpdateWebhooks.enabled | bool | `true` | Enables the feature |

View file

@ -25,32 +25,41 @@ spec:
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: AGE
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/source']
name: Source
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.group']
name: Group
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.kind']
name: Kind
type: string
- jsonPath: .metadata.annotations['audit\.kyverno\.io/resource\.name']
name: Owner
type: string
- jsonPath: .spec.summary.pass
name: PASS
name: Pass
type: integer
- jsonPath: .spec.summary.fail
name: FAIL
name: Fail
type: integer
- jsonPath: .spec.summary.warn
name: WARN
name: Warn
type: integer
- jsonPath: .spec.summary.error
name: ERROR
name: Error
type: integer
- jsonPath: .spec.summary.skip
name: SKIP
name: Skip
type: integer
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.gvr']
name: GVR
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.uid']
name: Uid
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.name']
name: REF
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/report\.aggregate']
name: AGGREGATE
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash']
name: Hash
priority: 1
type: string
name: v1
@ -361,32 +370,42 @@ spec:
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: AGE
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/source']
name: Source
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.group']
name: Group
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.kind']
name: Kind
type: string
- jsonPath: .metadata.annotations['audit\.kyverno\.io/resource\.name']
name: Owner
type: string
- jsonPath: .spec.summary.pass
name: PASS
name: Pass
type: integer
- jsonPath: .spec.summary.fail
name: FAIL
name: Fail
type: integer
- jsonPath: .spec.summary.warn
name: WARN
name: Warn
type: integer
- jsonPath: .spec.summary.error
name: ERROR
name: Error
type: integer
- jsonPath: .spec.summary.skip
name: SKIP
name: Skip
type: integer
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.gvr']
name: GVR
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.uid']
name: Uid
priority: 1
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.name']
name: REF
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/report\.aggregate']
name: AGGREGATE
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash']
name: Hash
priority: 1
type: string
name: v1

View file

@ -16,9 +16,6 @@
{{- with .aggregateReports -}}
{{- $flags = append $flags (print "--aggregateReports=" .enabled) -}}
{{- end -}}
{{- with .alternateReportStorage -}}
{{- $flags = append $flags (print "--alternateReportStorage=" .enabled) -}}
{{- end -}}
{{- with .policyReports -}}
{{- $flags = append $flags (print "--policyReports=" .enabled) -}}
{{- end -}}

View file

@ -168,7 +168,6 @@ spec:
"policyExceptions"
"protectManagedResources"
"registryClient"
"alternateReportStorage"
"tuf"
) | nindent 12 }}
{{- range $key, $value := .Values.admissionController.container.extraArgs }}

View file

@ -120,7 +120,6 @@ spec:
"logging"
"omitEvents"
"policyExceptions"
"alternateReportStorage"
) | nindent 12 }}
{{- range $key, $value := .Values.backgroundController.extraArgs }}
{{- if $value }}

View file

@ -127,7 +127,6 @@ spec:
"policyExceptions"
"reports"
"registryClient"
"alternateReportStorage"
"tuf"
) | nindent 12 }}
{{- range $key, $value := .Values.reportsController.extraArgs }}

View file

@ -580,9 +580,6 @@ features:
aggregateReports:
# -- Enables the feature
enabled: true
alternateReportStorage:
# -- Enables the feature
enabled: false
policyReports:
# -- Enables the feature
enabled: true

View file

@ -106,7 +106,6 @@ func main() {
internal.WithRegistryClient(),
internal.WithLeaderElection(),
internal.WithKyvernoClient(),
internal.WithAlternateReportStore(),
internal.WithDynamicClient(),
internal.WithKyvernoDynamicClient(),
internal.WithEventsClient(),

View file

@ -17,7 +17,6 @@ type Configuration interface {
UsesImageVerifyCache() bool
UsesLeaderElection() bool
UsesKyvernoClient() bool
UsesAlternateReportStore() bool
UsesDynamicClient() bool
UsesApiServerClient() bool
UsesMetadataClient() bool
@ -108,12 +107,6 @@ func WithKyvernoClient() ConfigurationOption {
}
}
func WithAlternateReportStore() ConfigurationOption {
return func(c *configuration) {
c.usesAlternateReportStore = true
}
}
func WithDynamicClient() ConfigurationOption {
return func(c *configuration) {
c.usesDynamicClient = true
@ -165,7 +158,6 @@ type configuration struct {
usesImageVerifyCache bool
usesLeaderElection bool
usesKyvernoClient bool
usesAlternateReportStore bool
usesDynamicClient bool
usesApiServerClient bool
usesMetadataClient bool
@ -222,10 +214,6 @@ func (c *configuration) UsesKyvernoClient() bool {
return c.usesKyvernoClient
}
func (c *configuration) UsesAlternateReportStore() bool {
return c.usesAlternateReportStore
}
func (c *configuration) UsesDynamicClient() bool {
return c.usesDynamicClient
}

View file

@ -56,8 +56,6 @@ var (
imageVerifyCacheEnabled bool
imageVerifyCacheTTLDuration time.Duration
imageVerifyCacheMaxSize int64
// alternate report storage
alternateReportStorage bool
)
func initLoggingFlags() {
@ -135,10 +133,6 @@ func initCleanupFlags() {
flag.StringVar(&cleanupServerPort, "cleanupServerPort", "9443", "kyverno cleanup server port, defaults to '9443'.")
}
func initAltReportStoreFlag() {
flag.BoolVar(&alternateReportStorage, "alternateReportStorage", false, "Store kyverno intermediate reports in a separate api group reports.kyverno.io. defaults to false.")
}
type options struct {
clientRateLimitQPS float64
clientRateLimitBurst int
@ -222,13 +216,7 @@ func initFlags(config Configuration, opts ...Option) {
if config.UsesLeaderElection() {
initLeaderElectionFlags()
}
// alternate report storage
if config.UsesAlternateReportStore() {
initAltReportStoreFlag()
}
initCleanupFlags()
for _, flagset := range config.FlagSets() {
flagset.VisitAll(func(f *flag.Flag) {
flag.CommandLine.Var(f.Value, f.Name, f.Usage)

View file

@ -16,7 +16,6 @@ import (
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/registryclient"
"github.com/kyverno/kyverno/pkg/report"
eventsv1 "k8s.io/client-go/kubernetes/typed/events/v1"
corev1listers "k8s.io/client-go/listers/core/v1"
)
@ -49,7 +48,6 @@ type SetupResult struct {
MetadataClient metadataclient.UpstreamInterface
KyvernoDynamicClient dclient.Interface
EventsClient eventsv1.EventsV1Interface
ReportManager report.Interface
}
func Setup(config Configuration, name string, skipResourceFilters bool) (context.Context, SetupResult, context.CancelFunc) {
@ -84,13 +82,8 @@ func Setup(config Configuration, name string, skipResourceFilters bool) (context
leaderElectionClient = createKubernetesClient(logger, clientRateLimitQPS, clientRateLimitBurst, kubeclient.WithMetrics(metricsManager, metrics.KubeClient), kubeclient.WithTracing())
}
var kyvernoClient kyvernoclient.UpstreamInterface
var reportManager report.Interface
if config.UsesKyvernoClient() {
kyvernoClient = createKyvernoClient(logger, kyvernoclient.WithMetrics(metricsManager, metrics.KyvernoClient), kyvernoclient.WithTracing())
if config.UsesAlternateReportStore() {
reportManager = report.NewReportManager(alternateReportStorage, kyvernoClient)
}
}
var dynamicClient dynamicclient.UpstreamInterface
if config.UsesDynamicClient() {
@ -130,7 +123,6 @@ func Setup(config Configuration, name string, skipResourceFilters bool) (context
MetadataClient: metadataClient,
KyvernoDynamicClient: dClient,
EventsClient: eventsClient,
ReportManager: reportManager,
},
shutdown(logger.WithName("shutdown"), sdownMaxProcs, sdownMetrics, sdownTracing, sdownSignals)
}

View file

@ -254,7 +254,6 @@ func main() {
internal.WithImageVerifyCache(),
internal.WithLeaderElection(),
internal.WithKyvernoClient(),
internal.WithAlternateReportStore(),
internal.WithDynamicClient(),
internal.WithKyvernoDynamicClient(),
internal.WithEventsClient(),
@ -483,7 +482,6 @@ func main() {
engine,
setup.KyvernoDynamicClient,
setup.KyvernoClient,
setup.ReportManager,
setup.Configuration,
setup.MetricsManager,
policyCache,

View file

@ -24,7 +24,6 @@ import (
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/leaderelection"
"github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/report"
"k8s.io/apimachinery/pkg/runtime/schema"
kubeinformers "k8s.io/client-go/informers"
admissionregistrationv1alpha1informers "k8s.io/client-go/informers/admissionregistration/v1alpha1"
@ -47,7 +46,6 @@ func createReportControllers(
backgroundScanWorkers int,
client dclient.Interface,
kyvernoClient versioned.Interface,
reportManager report.Interface,
metadataFactory metadatainformers.SharedInformerFactory,
kubeInformer kubeinformers.SharedInformerFactory,
kyvernoInformer kyvernoinformer.SharedInformerFactory,
@ -89,7 +87,6 @@ func createReportControllers(
aggregatereportcontroller.NewController(
kyvernoClient,
metadataFactory,
reportManager,
kyvernoV1.Policies(),
kyvernoV1.ClusterPolicies(),
vapInformer,
@ -106,7 +103,6 @@ func createReportControllers(
kyvernoClient,
client,
metadataFactory,
reportManager,
),
admissionreportcontroller.Workers,
))
@ -115,7 +111,6 @@ func createReportControllers(
backgroundScanController := backgroundscancontroller.NewController(
client,
kyvernoClient,
reportManager,
eng,
metadataFactory,
kyvernoV1.Policies(),
@ -161,7 +156,6 @@ func createrLeaderControllers(
kyvernoInformer kyvernoinformer.SharedInformerFactory,
metadataInformer metadatainformers.SharedInformerFactory,
kyvernoClient versioned.Interface,
reportManager report.Interface,
dynamicClient dclient.Interface,
configuration config.Configuration,
jp jmespath.Interface,
@ -179,7 +173,6 @@ func createrLeaderControllers(
backgroundScanWorkers,
dynamicClient,
kyvernoClient,
reportManager,
metadataInformer,
kubeInformer,
kyvernoInformer,
@ -233,7 +226,6 @@ func main() {
internal.WithImageVerifyCache(),
internal.WithLeaderElection(),
internal.WithKyvernoClient(),
internal.WithAlternateReportStore(),
internal.WithDynamicClient(),
internal.WithMetadataClient(),
internal.WithKyvernoDynamicClient(),
@ -324,7 +316,6 @@ func main() {
kyvernoInformer,
metadataInformer,
setup.KyvernoClient,
setup.ReportManager,
setup.KyvernoDynamicClient,
setup.Configuration,
setup.Jp,

View file

@ -19,32 +19,41 @@ spec:
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: AGE
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/source']
name: Source
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.group']
name: Group
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.kind']
name: Kind
type: string
- jsonPath: .metadata.annotations['audit\.kyverno\.io/resource\.name']
name: Owner
type: string
- jsonPath: .spec.summary.pass
name: PASS
name: Pass
type: integer
- jsonPath: .spec.summary.fail
name: FAIL
name: Fail
type: integer
- jsonPath: .spec.summary.warn
name: WARN
name: Warn
type: integer
- jsonPath: .spec.summary.error
name: ERROR
name: Error
type: integer
- jsonPath: .spec.summary.skip
name: SKIP
name: Skip
type: integer
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.gvr']
name: GVR
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.uid']
name: Uid
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.name']
name: REF
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/report\.aggregate']
name: AGGREGATE
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash']
name: Hash
priority: 1
type: string
name: v1

View file

@ -19,32 +19,42 @@ spec:
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: AGE
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/source']
name: Source
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.group']
name: Group
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.kind']
name: Kind
type: string
- jsonPath: .metadata.annotations['audit\.kyverno\.io/resource\.name']
name: Owner
type: string
- jsonPath: .spec.summary.pass
name: PASS
name: Pass
type: integer
- jsonPath: .spec.summary.fail
name: FAIL
name: Fail
type: integer
- jsonPath: .spec.summary.warn
name: WARN
name: Warn
type: integer
- jsonPath: .spec.summary.error
name: ERROR
name: Error
type: integer
- jsonPath: .spec.summary.skip
name: SKIP
name: Skip
type: integer
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.gvr']
name: GVR
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.uid']
name: Uid
priority: 1
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.name']
name: REF
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/report\.aggregate']
name: AGGREGATE
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash']
name: Hash
priority: 1
type: string
name: v1

View file

@ -49569,32 +49569,41 @@ spec:
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: AGE
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/source']
name: Source
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.group']
name: Group
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.kind']
name: Kind
type: string
- jsonPath: .metadata.annotations['audit\.kyverno\.io/resource\.name']
name: Owner
type: string
- jsonPath: .spec.summary.pass
name: PASS
name: Pass
type: integer
- jsonPath: .spec.summary.fail
name: FAIL
name: Fail
type: integer
- jsonPath: .spec.summary.warn
name: WARN
name: Warn
type: integer
- jsonPath: .spec.summary.error
name: ERROR
name: Error
type: integer
- jsonPath: .spec.summary.skip
name: SKIP
name: Skip
type: integer
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.gvr']
name: GVR
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.uid']
name: Uid
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.name']
name: REF
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/report\.aggregate']
name: AGGREGATE
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash']
name: Hash
priority: 1
type: string
name: v1
@ -49907,32 +49916,42 @@ spec:
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: AGE
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/source']
name: Source
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.group']
name: Group
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.kind']
name: Kind
type: string
- jsonPath: .metadata.annotations['audit\.kyverno\.io/resource\.name']
name: Owner
type: string
- jsonPath: .spec.summary.pass
name: PASS
name: Pass
type: integer
- jsonPath: .spec.summary.fail
name: FAIL
name: Fail
type: integer
- jsonPath: .spec.summary.warn
name: WARN
name: Warn
type: integer
- jsonPath: .spec.summary.error
name: ERROR
name: Error
type: integer
- jsonPath: .spec.summary.skip
name: SKIP
name: Skip
type: integer
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.gvr']
name: GVR
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.uid']
name: Uid
priority: 1
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.name']
name: REF
type: string
- jsonPath: .metadata.labels['audit\.kyverno\.io/report\.aggregate']
name: AGGREGATE
- jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash']
name: Hash
priority: 1
type: string
name: v1
@ -51494,7 +51513,6 @@ spec:
- --otelConfig=prometheus
- --metricsPort=8000
- --admissionReports=true
- --alternateReportStorage=false
- --autoUpdateWebhooks=true
- --enableConfigMapCaching=true
- --enableDeferredLoading=true
@ -51650,7 +51668,6 @@ spec:
- --disableMetrics=false
- --otelConfig=prometheus
- --metricsPort=8000
- --alternateReportStorage=false
- --enableConfigMapCaching=true
- --enableDeferredLoading=true
- --loggingFormat=text
@ -51892,7 +51909,6 @@ spec:
- --metricsPort=8000
- --admissionReports=true
- --aggregateReports=true
- --alternateReportStorage=false
- --policyReports=true
- --validatingAdmissionPolicyReports=false
- --backgroundScan=true

View file

@ -2,7 +2,6 @@ package admission
import (
"context"
"fmt"
"time"
"github.com/go-logr/logr"
@ -12,7 +11,6 @@ import (
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/controllers"
"github.com/kyverno/kyverno/pkg/controllers/report/utils"
"github.com/kyverno/kyverno/pkg/report"
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
"go.uber.org/multierr"
@ -38,9 +36,8 @@ const (
type controller struct {
// clients
client versioned.Interface
dclient dclient.Interface
reportManager report.Interface
client versioned.Interface
dclient dclient.Interface
// listers
admrLister cache.GenericLister
@ -54,18 +51,16 @@ func NewController(
client versioned.Interface,
dclient dclient.Interface,
metadataFactory metadatainformers.SharedInformerFactory,
reportManager report.Interface,
) controllers.Controller {
admrInformer := reportManager.AdmissionReportInformer(metadataFactory)
cadmrInformer := reportManager.ClusterAdmissionReportInformer(metadataFactory)
admrInformer := metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("admissionreports"))
cadmrInformer := metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("clusteradmissionreports"))
queue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), ControllerName)
c := controller{
client: client,
dclient: dclient,
reportManager: reportManager,
admrLister: admrInformer.Lister(),
cadmrLister: cadmrInformer.Lister(),
queue: queue,
client: client,
dclient: dclient,
admrLister: admrInformer.Lister(),
cadmrLister: cadmrInformer.Lister(),
queue: queue,
}
if _, err := controllerutils.AddEventHandlersT(
admrInformer.Informer(),
@ -115,9 +110,9 @@ func (c *controller) getReports(uid types.UID) ([]metav1.Object, error) {
func (c *controller) fetchReport(ctx context.Context, namespace, name string) (kyvernov1alpha2.ReportInterface, error) {
if namespace == "" {
return c.reportManager.GetClusterAdmissionReports(ctx, name, metav1.GetOptions{})
return c.client.KyvernoV1alpha2().ClusterAdmissionReports().Get(ctx, name, metav1.GetOptions{})
} else {
return c.reportManager.GetAdmissionReports(ctx, name, namespace, metav1.GetOptions{})
return c.client.KyvernoV1alpha2().AdmissionReports(namespace).Get(ctx, name, metav1.GetOptions{})
}
}
@ -147,26 +142,18 @@ func (c *controller) fetchReports(ctx context.Context, uid types.UID) ([]kyverno
} else {
for n := range ns {
if n == "" {
cadmrsObj, err := c.reportManager.ListClusterAdmissionReports(ctx, metav1.ListOptions{LabelSelector: selector.String()})
cadmrs, err := c.client.KyvernoV1alpha2().ClusterAdmissionReports().List(ctx, metav1.ListOptions{LabelSelector: selector.String()})
if err != nil {
return nil, err
}
cadmrs, ok := cadmrsObj.(*kyvernov1alpha2.ClusterAdmissionReportList)
if !ok {
return nil, fmt.Errorf("failed to convert runtime object to cluster admission report list")
}
for i := range cadmrs.Items {
results = append(results, &cadmrs.Items[i])
}
} else {
admrsObj, err := c.reportManager.ListAdmissionReports(ctx, n, metav1.ListOptions{LabelSelector: selector.String()})
admrs, err := c.client.KyvernoV1alpha2().AdmissionReports(n).List(ctx, metav1.ListOptions{LabelSelector: selector.String()})
if err != nil {
return nil, err
}
admrs, ok := admrsObj.(*kyvernov1alpha2.AdmissionReportList)
if !ok {
return nil, fmt.Errorf("failed to convert runtime object to admission report list")
}
for i := range admrs.Items {
results = append(results, &admrs.Items[i])
}
@ -178,9 +165,9 @@ func (c *controller) fetchReports(ctx context.Context, uid types.UID) ([]kyverno
func (c *controller) deleteReport(ctx context.Context, namespace, name string) error {
if namespace == "" {
return c.reportManager.DeleteClusterAdmissionReports(ctx, name, metav1.DeleteOptions{})
return c.client.KyvernoV1alpha2().ClusterAdmissionReports().Delete(ctx, name, metav1.DeleteOptions{})
} else {
return c.reportManager.DeleteAdmissionReports(ctx, name, namespace, metav1.DeleteOptions{})
return c.client.KyvernoV1alpha2().AdmissionReports(namespace).Delete(ctx, name, metav1.DeleteOptions{})
}
}
@ -237,7 +224,7 @@ func (c *controller) aggregateReports(ctx context.Context, uid types.UID) (kyver
// if we found the resource, build an aggregated report for it
if res != nil {
if aggregated == nil {
aggregated = c.reportManager.NewAdmissionReport(res.GetNamespace(), string(uid), gvr, *res)
aggregated = reportutils.NewAdmissionReport(res.GetNamespace(), string(uid), gvr, res.GroupVersionKind(), *res)
controllerutils.SetOwner(aggregated, res.GetAPIVersion(), res.GetKind(), res.GetName(), uid)
controllerutils.SetLabel(aggregated, reportutils.LabelAggregatedReport, string(uid))
}
@ -264,12 +251,12 @@ func (c *controller) aggregateReports(ctx context.Context, uid types.UID) (kyver
}
after := aggregated
if aggregated.GetResourceVersion() != "" {
after = c.reportManager.DeepCopy(aggregated)
after = reportutils.DeepCopy(aggregated)
}
reportutils.SetResults(after, results...)
if after.GetResourceVersion() == "" {
if len(results) > 0 {
if _, err := c.reportManager.CreateReport(ctx, after); err != nil {
if _, err := reportutils.CreateReport(ctx, after, c.client); err != nil {
errs = append(errs, err)
}
}
@ -280,7 +267,7 @@ func (c *controller) aggregateReports(ctx context.Context, uid types.UID) (kyver
}
} else {
if !utils.ReportsAreIdentical(aggregated, after) {
if _, err = c.reportManager.UpdateReport(ctx, after); err != nil {
if _, err = reportutils.UpdateReport(ctx, after, c.client); err != nil {
errs = append(errs, err)
}
}

View file

@ -16,7 +16,6 @@ import (
"github.com/kyverno/kyverno/pkg/controllers"
"github.com/kyverno/kyverno/pkg/controllers/report/resource"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/report"
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
datautils "github.com/kyverno/kyverno/pkg/utils/data"
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
@ -43,8 +42,7 @@ const (
type controller struct {
// clients
client versioned.Interface
reportManager report.Interface
client versioned.Interface
// listers
polLister kyvernov1listers.PolicyLister
@ -75,21 +73,19 @@ func keyFunc(obj metav1.Object) cache.ExplicitKey {
func NewController(
client versioned.Interface,
metadataFactory metadatainformers.SharedInformerFactory,
reportManager report.Interface,
polInformer kyvernov1informers.PolicyInformer,
cpolInformer kyvernov1informers.ClusterPolicyInformer,
metadataCache resource.MetadataCache,
chunkSize int,
) controllers.Controller {
admrInformer := reportManager.AdmissionReportInformer(metadataFactory)
cadmrInformer := reportManager.ClusterAdmissionReportInformer(metadataFactory)
bgscanrInformer := reportManager.BackgroundScanReportInformer(metadataFactory)
cbgscanrInformer := reportManager.ClusterBackgroundScanReportInformer(metadataFactory)
admrInformer := metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("admissionreports"))
cadmrInformer := metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("clusteradmissionreports"))
bgscanrInformer := metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("backgroundscanreports"))
cbgscanrInformer := metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("clusterbackgroundscanreports"))
polrInformer := metadataFactory.ForResource(policyreportv1alpha2.SchemeGroupVersion.WithResource("policyreports"))
cpolrInformer := metadataFactory.ForResource(policyreportv1alpha2.SchemeGroupVersion.WithResource("clusterpolicyreports"))
c := controller{
client: client,
reportManager: reportManager,
polLister: polInformer.Lister(),
cpolLister: cpolInformer.Lister(),
admrLister: admrInformer.Lister(),
@ -145,7 +141,7 @@ func (c *controller) mergeAdmissionReports(ctx context.Context, namespace string
if namespace == "" {
next := ""
for {
cadmsObj, err := c.reportManager.ListClusterAdmissionReports(ctx, metav1.ListOptions{
cadms, err := c.client.KyvernoV1alpha2().ClusterAdmissionReports().List(ctx, metav1.ListOptions{
// no need to consider non aggregated reports
LabelSelector: reportutils.LabelAggregatedReport,
Limit: mergeLimit,
@ -154,10 +150,6 @@ func (c *controller) mergeAdmissionReports(ctx context.Context, namespace string
if err != nil {
return err
}
cadms, ok := cadmsObj.(*kyvernov1alpha2.ClusterAdmissionReportList)
if !ok {
return fmt.Errorf("failed to convert runtime object to cluster admission report list")
}
next = cadms.Continue
for i := range cadms.Items {
mergeReports(policyMap, accumulator, &cadms.Items[i])
@ -169,7 +161,7 @@ func (c *controller) mergeAdmissionReports(ctx context.Context, namespace string
} else {
next := ""
for {
admsObj, err := c.reportManager.ListAdmissionReports(ctx, namespace, metav1.ListOptions{
adms, err := c.client.KyvernoV1alpha2().AdmissionReports(namespace).List(ctx, metav1.ListOptions{
// no need to consider non aggregated reports
LabelSelector: reportutils.LabelAggregatedReport,
Limit: mergeLimit,
@ -178,10 +170,6 @@ func (c *controller) mergeAdmissionReports(ctx context.Context, namespace string
if err != nil {
return err
}
adms, ok := admsObj.(*kyvernov1alpha2.AdmissionReportList)
if !ok {
return fmt.Errorf("failed to convert runtime object to admission report list")
}
next = adms.Continue
for i := range adms.Items {
mergeReports(policyMap, accumulator, &adms.Items[i])
@ -197,17 +185,13 @@ func (c *controller) mergeBackgroundScanReports(ctx context.Context, namespace s
if namespace == "" {
next := ""
for {
cbgscansObj, err := c.reportManager.ListClusterBackgroundScanReports(ctx, metav1.ListOptions{
cbgscans, err := c.client.KyvernoV1alpha2().ClusterBackgroundScanReports().List(ctx, metav1.ListOptions{
Limit: mergeLimit,
Continue: next,
})
if err != nil {
return err
}
cbgscans, ok := cbgscansObj.(*kyvernov1alpha2.ClusterBackgroundScanReportList)
if !ok {
return fmt.Errorf("failed to convert runtime object to admission report list")
}
next = cbgscans.Continue
for i := range cbgscans.Items {
mergeReports(policyMap, accumulator, &cbgscans.Items[i])
@ -219,17 +203,13 @@ func (c *controller) mergeBackgroundScanReports(ctx context.Context, namespace s
} else {
next := ""
for {
bgscansObj, err := c.reportManager.ListBackgroundScanReports(ctx, namespace, metav1.ListOptions{
bgscans, err := c.client.KyvernoV1alpha2().BackgroundScanReports(namespace).List(ctx, metav1.ListOptions{
Limit: mergeLimit,
Continue: next,
})
if err != nil {
return err
}
bgscans, ok := bgscansObj.(*kyvernov1alpha2.BackgroundScanReportList)
if !ok {
return fmt.Errorf("failed to convert runtime object to admission report list")
}
next = bgscans.Continue
for i := range bgscans.Items {
mergeReports(policyMap, accumulator, &bgscans.Items[i])
@ -250,9 +230,9 @@ func (c *controller) reconcileReport(ctx context.Context, policyMap map[string]p
reportutils.SetPolicyLabel(report, engineapi.NewKyvernoPolicy(policy.policy))
}
}
return c.reportManager.CreateReport(ctx, report)
return reportutils.CreateReport(ctx, report, c.client)
}
after := c.reportManager.DeepCopy(report)
after := reportutils.DeepCopy(report)
// hold custom labels
reportutils.CleanupKyvernoLabels(after)
reportutils.SetManagedByKyvernoLabel(after)
@ -266,7 +246,7 @@ func (c *controller) reconcileReport(ctx context.Context, policyMap map[string]p
if datautils.DeepEqual(report, after) {
return after, nil
}
return c.reportManager.UpdateReport(ctx, after)
return reportutils.UpdateReport(ctx, after, c.client)
}
func (c *controller) cleanReports(ctx context.Context, actual map[string]kyvernov1alpha2.ReportInterface, expected []kyvernov1alpha2.ReportInterface) error {
@ -276,7 +256,7 @@ func (c *controller) cleanReports(ctx context.Context, actual map[string]kyverno
}
for _, obj := range actual {
if !keep.Has(obj.GetName()) {
err := c.reportManager.DeleteReport(ctx, obj)
err := reportutils.DeleteReport(ctx, obj, c.client)
if err != nil {
return err
}

View file

@ -8,13 +8,13 @@ import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2"
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
reportsv1 "github.com/kyverno/kyverno/api/reports/v1"
"github.com/kyverno/kyverno/pkg/autogen"
"github.com/kyverno/kyverno/pkg/client/clientset/versioned"
kyvernov1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1"
kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1"
"github.com/kyverno/kyverno/pkg/controllers"
"github.com/kyverno/kyverno/pkg/controllers/report/resource"
"github.com/kyverno/kyverno/pkg/report"
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
corev1 "k8s.io/api/core/v1"
@ -40,8 +40,7 @@ const (
type controller struct {
// clients
client versioned.Interface
reportManager report.Interface
client versioned.Interface
// listers
polLister kyvernov1listers.PolicyLister
@ -65,22 +64,18 @@ type policyMapEntry struct {
func NewController(
client versioned.Interface,
metadataFactory metadatainformers.SharedInformerFactory,
reportManager report.Interface,
polInformer kyvernov1informers.PolicyInformer,
cpolInformer kyvernov1informers.ClusterPolicyInformer,
vapInformer admissionregistrationv1alpha1informers.ValidatingAdmissionPolicyInformer,
metadataCache resource.MetadataCache,
chunkSize int,
) controllers.Controller {
admrInformer := reportManager.AdmissionReportInformer(metadataFactory)
cadmrInformer := reportManager.ClusterAdmissionReportInformer(metadataFactory)
bgscanrInformer := reportManager.BackgroundScanReportInformer(metadataFactory)
cbgscanrInformer := reportManager.ClusterBackgroundScanReportInformer(metadataFactory)
ephrInformer := metadataFactory.ForResource(reportsv1.SchemeGroupVersion.WithResource("ephemeralreports"))
cephrInformer := metadataFactory.ForResource(reportsv1.SchemeGroupVersion.WithResource("clusterephemeralreports"))
polrInformer := metadataFactory.ForResource(policyreportv1alpha2.SchemeGroupVersion.WithResource("policyreports"))
cpolrInformer := metadataFactory.ForResource(policyreportv1alpha2.SchemeGroupVersion.WithResource("clusterpolicyreports"))
c := controller{
client: client,
reportManager: reportManager,
polLister: polInformer.Lister(),
cpolLister: cpolInformer.Lister(),
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), ControllerName),
@ -126,20 +121,17 @@ func NewController(
logger.Error(err, "failed to register event handlers")
}
}
if _, _, err := controllerutils.AddDelayedDefaultEventHandlers(logger, bgscanrInformer.Informer(), c.queue, enqueueDelay); err != nil {
logger.Error(err, "failed to register event handlers")
}
if _, _, err := controllerutils.AddDelayedDefaultEventHandlers(logger, cbgscanrInformer.Informer(), c.queue, enqueueDelay); err != nil {
logger.Error(err, "failed to register event handlers")
}
enqueueFromAdmr := func(obj metav1.Object) {
// no need to consider non aggregated reports
if controllerutils.HasLabel(obj, reportutils.LabelAggregatedReport) {
switch reportutils.GetSource(obj) {
case "background-scan":
c.queue.AddAfter(controllerutils.MetaObjectToName(obj), enqueueDelay)
case "admission":
obj := cache.ObjectName{Namespace: obj.GetNamespace(), Name: string(reportutils.GetResourceUid(obj))}
c.queue.AddAfter(obj.String(), enqueueDelay)
}
}
if _, err := controllerutils.AddEventHandlersT(
admrInformer.Informer(),
ephrInformer.Informer(),
func(obj metav1.Object) { enqueueFromAdmr(obj) },
func(_, obj metav1.Object) { enqueueFromAdmr(obj) },
func(obj metav1.Object) { enqueueFromAdmr(obj) },
@ -147,7 +139,7 @@ func NewController(
logger.Error(err, "failed to register event handlers")
}
if _, err := controllerutils.AddEventHandlersT(
cadmrInformer.Informer(),
cephrInformer.Informer(),
func(obj metav1.Object) { enqueueFromAdmr(obj) },
func(_, obj metav1.Object) { enqueueFromAdmr(obj) },
func(obj metav1.Object) { enqueueFromAdmr(obj) },
@ -220,7 +212,7 @@ func (c *controller) createVapMap() (sets.Set[string], error) {
func (c *controller) getBackgroundScanReport(ctx context.Context, namespace, name string) (kyvernov1alpha2.ReportInterface, error) {
if namespace == "" {
report, err := c.reportManager.GetClusterBackgroundScanReports(ctx, name, metav1.GetOptions{})
report, err := c.client.ReportsV1().ClusterEphemeralReports().Get(ctx, name, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
return nil, nil
@ -229,7 +221,7 @@ func (c *controller) getBackgroundScanReport(ctx context.Context, namespace, nam
}
return report, nil
} else {
report, err := c.reportManager.GetBackgroundScanReports(ctx, name, namespace, metav1.GetOptions{})
report, err := c.client.ReportsV1().EphemeralReports(namespace).Get(ctx, name, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
return nil, nil
@ -240,26 +232,42 @@ func (c *controller) getBackgroundScanReport(ctx context.Context, namespace, nam
}
}
func (c *controller) getAdmissionReport(ctx context.Context, namespace, name string) (kyvernov1alpha2.ReportInterface, error) {
if namespace == "" {
report, err := c.reportManager.GetClusterAdmissionReports(ctx, name, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
return nil, nil
}
return nil, err
}
return report, nil
} else {
report, err := c.reportManager.GetAdmissionReports(ctx, name, namespace, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
return nil, nil
}
return nil, err
}
return report, nil
func (c *controller) getAdmissionReports(ctx context.Context, namespace, name string) ([]kyvernov1alpha2.ReportInterface, error) {
selector, err := reportutils.SelectorResourceUidEquals(types.UID(name))
if err != nil {
return nil, err
}
var results []kyvernov1alpha2.ReportInterface
if namespace == "" {
reports, err := c.client.ReportsV1().ClusterEphemeralReports().List(ctx, metav1.ListOptions{
LabelSelector: selector.String(),
})
if err != nil {
if apierrors.IsNotFound(err) {
return nil, nil
}
return nil, err
}
for _, report := range reports.Items {
report := report
results = append(results, &report)
}
} else {
reports, err := c.client.ReportsV1().EphemeralReports(namespace).List(ctx, metav1.ListOptions{
LabelSelector: selector.String(),
})
if err != nil {
if apierrors.IsNotFound(err) {
return nil, nil
}
return nil, err
}
for _, report := range reports.Items {
report := report
results = append(results, &report)
}
}
return results, nil
}
func (c *controller) getPolicyReport(ctx context.Context, namespace, name string) (kyvernov1alpha2.ReportInterface, error) {
@ -284,8 +292,8 @@ func (c *controller) getPolicyReport(ctx context.Context, namespace, name string
}
}
func (c *controller) getReports(ctx context.Context, namespace, name string) (kyvernov1alpha2.ReportInterface, kyvernov1alpha2.ReportInterface, error) {
admissionReport, err := c.getAdmissionReport(ctx, namespace, name)
func (c *controller) getReports(ctx context.Context, namespace, name string) ([]kyvernov1alpha2.ReportInterface, kyvernov1alpha2.ReportInterface, error) {
admissionReports, err := c.getAdmissionReports(ctx, namespace, name)
if err != nil {
return nil, nil, err
}
@ -293,14 +301,14 @@ func (c *controller) getReports(ctx context.Context, namespace, name string) (ky
if err != nil {
return nil, nil, err
}
return admissionReport, backgroundReport, nil
return admissionReports, backgroundReport, nil
}
func (c *controller) reconcile(ctx context.Context, logger logr.Logger, _, namespace, name string) error {
uid := types.UID(name)
resource, gvk, exists := c.metadataCache.GetResourceHash(uid)
if exists {
admissionReport, backgroundReport, err := c.getReports(ctx, namespace, name)
admissionReports, backgroundReport, err := c.getReports(ctx, namespace, name)
if err != nil {
return err
}
@ -331,36 +339,40 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, _, names
return err
}
merged := map[string]policyreportv1alpha2.PolicyReportResult{}
mergeReports(policyMap, vapMap, merged, uid, policyReport, admissionReport, backgroundReport)
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 !create {
if err := deleteReport(ctx, policyReport, c.reportManager); err != nil {
if err := deleteReport(ctx, policyReport, c.client); err != nil {
return err
}
}
} else {
reportutils.SetResults(policyReport, results...)
if create {
if _, err := c.reportManager.CreateReport(ctx, policyReport); err != nil {
if _, err := reportutils.CreateReport(ctx, policyReport, c.client); err != nil {
return err
}
} else {
if _, err := updateReport(ctx, policyReport, c.reportManager); err != nil {
if _, err := updateReport(ctx, policyReport, c.client); err != nil {
return err
}
}
}
if admissionReport != nil {
if err := deleteReport(ctx, admissionReport, c.reportManager); err != nil {
for _, admissionReport := range admissionReports {
if err := deleteReport(ctx, admissionReport, c.client); err != nil {
return err
}
}
if backgroundReport != nil {
if err := deleteReport(ctx, backgroundReport, c.reportManager); err != nil {
if err := deleteReport(ctx, backgroundReport, c.client); err != nil {
return err
}
}
@ -370,7 +382,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, _, names
return err
}
if policyReport != nil {
if err := deleteReport(ctx, policyReport, c.reportManager); err != nil {
if err := deleteReport(ctx, policyReport, c.client); err != nil {
return err
}
}

View file

@ -6,8 +6,9 @@ import (
kyvernov1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2"
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
"github.com/kyverno/kyverno/pkg/report"
"github.com/kyverno/kyverno/pkg/client/clientset/versioned"
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
)
@ -41,16 +42,16 @@ func mergeReports(policyMap map[string]policyMapEntry, vapMap sets.Set[string],
}
}
func deleteReport(ctx context.Context, report kyvernov1alpha2.ReportInterface, reportManager report.Interface) error {
func deleteReport(ctx context.Context, report kyvernov1alpha2.ReportInterface, client versioned.Interface) error {
if !controllerutils.IsManagedByKyverno(report) {
return errors.New("can't delete report because it is not managed by kyverno")
}
return reportManager.DeleteReport(ctx, report)
return reportutils.DeleteReport(ctx, report, client)
}
func updateReport(ctx context.Context, report kyvernov1alpha2.ReportInterface, reportManager report.Interface) (kyvernov1alpha2.ReportInterface, error) {
func updateReport(ctx context.Context, report kyvernov1alpha2.ReportInterface, client versioned.Interface) (kyvernov1alpha2.ReportInterface, error) {
if !controllerutils.IsManagedByKyverno(report) {
return nil, errors.New("can't update report because it is not managed by kyverno")
}
return reportManager.UpdateReport(ctx, report)
return reportutils.UpdateReport(ctx, report, client)
}

View file

@ -9,6 +9,7 @@ import (
kyvernov1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2"
kyvernov2beta1 "github.com/kyverno/kyverno/api/kyverno/v2beta1"
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
reportsv1 "github.com/kyverno/kyverno/api/reports/v1"
"github.com/kyverno/kyverno/pkg/client/clientset/versioned"
kyvernov1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1"
kyvernov2beta1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v2beta1"
@ -22,7 +23,6 @@ import (
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/report"
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
datautils "github.com/kyverno/kyverno/pkg/utils/data"
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
@ -53,7 +53,6 @@ type controller struct {
// clients
client dclient.Interface
kyvernoClient versioned.Interface
reportManager report.Interface
engine engineapi.Engine
// listers
@ -83,7 +82,6 @@ type controller struct {
func NewController(
client dclient.Interface,
kyvernoClient versioned.Interface,
reportManager report.Interface,
engine engineapi.Engine,
metadataFactory metadatainformers.SharedInformerFactory,
polInformer kyvernov1informers.PolicyInformer,
@ -99,19 +97,18 @@ func NewController(
eventGen event.Interface,
policyReports bool,
) controllers.Controller {
bgscanr := reportManager.BackgroundScanReportInformer(metadataFactory)
cbgscanr := reportManager.ClusterBackgroundScanReportInformer(metadataFactory)
ephrInformer := metadataFactory.ForResource(reportsv1.SchemeGroupVersion.WithResource("ephemeralreports"))
cephrInformer := metadataFactory.ForResource(reportsv1.SchemeGroupVersion.WithResource("clusterephemeralreports"))
queue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), ControllerName)
c := controller{
client: client,
kyvernoClient: kyvernoClient,
reportManager: reportManager,
engine: engine,
polLister: polInformer.Lister(),
cpolLister: cpolInformer.Lister(),
polexLister: polexInformer.Lister(),
bgscanrLister: bgscanr.Lister(),
cbgscanrLister: cbgscanr.Lister(),
bgscanrLister: ephrInformer.Lister(),
cbgscanrLister: cephrInformer.Lister(),
nsLister: nsInformer.Lister(),
queue: queue,
metadataCache: metadataCache,
@ -225,9 +222,9 @@ func (c *controller) enqueueResources() {
func (c *controller) getReport(ctx context.Context, namespace, name string) (kyvernov1alpha2.ReportInterface, error) {
if namespace == "" {
return c.reportManager.GetClusterBackgroundScanReports(ctx, name, metav1.GetOptions{})
return c.kyvernoClient.ReportsV1().ClusterEphemeralReports().Get(ctx, name, metav1.GetOptions{})
} else {
return c.reportManager.GetBackgroundScanReports(ctx, name, namespace, metav1.GetOptions{})
return c.kyvernoClient.ReportsV1().EphemeralReports(namespace).Get(ctx, name, metav1.GetOptions{})
}
}
@ -330,7 +327,7 @@ func (c *controller) reconcileReport(
if !apierrors.IsNotFound(err) {
return err
}
observed = c.reportManager.NewBackgroundScanReport(namespace, name, gvk, resource.Name, uid)
observed = reportutils.NewBackgroundScanReport(namespace, name, gvk, resource.Name, uid)
}
// build desired report
expected := map[string]string{}
@ -343,7 +340,6 @@ func (c *controller) reconcileReport(
for _, binding := range bindings {
expected[reportutils.ValidatingAdmissionPolicyBindingLabel(binding)] = binding.GetResourceVersion()
}
actual := map[string]string{}
for key, value := range observed.GetLabels() {
if reportutils.IsPolicyLabel(key) {
@ -366,7 +362,6 @@ func (c *controller) reconcileReport(
}
policyNameToLabel[key] = reportutils.PolicyLabel(policy)
}
for _, exception := range exceptions {
key, err := cache.MetaNamespaceKeyFunc(exception)
if err != nil {
@ -374,7 +369,6 @@ func (c *controller) reconcileReport(
}
policyNameToLabel[key] = reportutils.PolicyExceptionLabel(exception)
}
for _, binding := range bindings {
key, err := cache.MetaNamespaceKeyFunc(binding)
if err != nil {
@ -382,7 +376,6 @@ func (c *controller) reconcileReport(
}
policyNameToLabel[key] = reportutils.ValidatingAdmissionPolicyBindingLabel(binding)
}
for _, result := range observed.GetResults() {
// if the policy did not change, keep the result
label := policyNameToLabel[result.Policy]
@ -425,7 +418,7 @@ func (c *controller) reconcileReport(
}
}
}
desired := c.reportManager.DeepCopy(observed)
desired := reportutils.DeepCopy(observed)
for key := range desired.GetLabels() {
if reportutils.IsPolicyLabel(key) {
delete(desired.GetLabels(), key)
@ -458,19 +451,19 @@ func (c *controller) storeReport(ctx context.Context, observed, desired kyvernov
if !hasReport && !wantsReport {
return nil
} else if !hasReport && wantsReport {
_, err = c.reportManager.CreateReport(ctx, desired)
_, err = reportutils.CreateReport(ctx, desired, c.kyvernoClient)
return err
} else if hasReport && !wantsReport {
if observed.GetNamespace() == "" {
return c.reportManager.DeleteClusterBackgroundScanReports(ctx, observed.GetName(), metav1.DeleteOptions{})
return c.kyvernoClient.ReportsV1().ClusterEphemeralReports().Delete(ctx, observed.GetName(), metav1.DeleteOptions{})
} else {
return c.reportManager.DeleteBackgroundScanReports(ctx, observed.GetName(), observed.GetNamespace(), metav1.DeleteOptions{})
return c.kyvernoClient.ReportsV1().EphemeralReports(observed.GetNamespace()).Delete(ctx, observed.GetName(), metav1.DeleteOptions{})
}
} else {
if utils.ReportsAreIdentical(observed, desired) {
return nil
}
_, err = c.reportManager.UpdateReport(ctx, desired)
_, err = reportutils.UpdateReport(ctx, desired, c.kyvernoClient)
return err
}
}
@ -490,9 +483,9 @@ func (c *controller) reconcile(ctx context.Context, log logr.Logger, key, namesp
return nil
} else {
if report.GetNamespace() == "" {
return c.reportManager.DeleteClusterBackgroundScanReports(ctx, report.GetName(), metav1.DeleteOptions{})
return c.kyvernoClient.ReportsV1().ClusterEphemeralReports().Delete(ctx, report.GetName(), metav1.DeleteOptions{})
} else {
return c.reportManager.DeleteBackgroundScanReports(ctx, report.GetName(), report.GetNamespace(), metav1.DeleteOptions{})
return c.kyvernoClient.ReportsV1().EphemeralReports(report.GetNamespace()).Delete(ctx, report.GetName(), metav1.DeleteOptions{})
}
}
}

View file

@ -102,14 +102,12 @@ func NewController(
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), ControllerName),
dynamicWatchers: map[schema.GroupVersionResource]*watcher{},
}
if vapInformer != nil {
c.vapLister = vapInformer.Lister()
if _, _, err := controllerutils.AddDefaultEventHandlers(logger, vapInformer.Informer(), c.queue); err != nil {
logger.Error(err, "failed to register event handlers")
}
}
if _, _, err := controllerutils.AddDefaultEventHandlers(logger, polInformer.Informer(), c.queue); err != nil {
logger.Error(err, "failed to register event handlers")
}

View file

@ -1,88 +0,0 @@
package report
import (
kyvernov1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2"
kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2"
reportsv1 "github.com/kyverno/kyverno/api/reports/v1"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
admissionv1 "k8s.io/api/admission/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
)
func newAdmissionReportV1Alpha1(namespace, name string, gvr schema.GroupVersionResource, resource unstructured.Unstructured) kyvernov1alpha2.ReportInterface {
var report kyvernov1alpha2.ReportInterface
if namespace == "" {
report = &kyvernov1alpha2.ClusterAdmissionReport{Spec: kyvernov2.AdmissionReportSpec{}}
} else {
report = &kyvernov1alpha2.AdmissionReport{Spec: kyvernov2.AdmissionReportSpec{}}
}
report.SetName(name)
report.SetNamespace(namespace)
reportutils.SetResourceUid(report, resource.GetUID())
reportutils.SetResourceGVR(report, gvr)
reportutils.SetResourceNamespaceAndName(report, resource.GetNamespace(), resource.GetName())
reportutils.SetManagedByKyvernoLabel(report)
return report
}
func buildAdmissionReportV1Alpha1(resource unstructured.Unstructured, request admissionv1.AdmissionRequest, responses ...engineapi.EngineResponse) kyvernov1alpha2.ReportInterface {
report := newAdmissionReportV1Alpha1(resource.GetNamespace(), string(request.UID), schema.GroupVersionResource(request.Resource), resource)
reportutils.SetResponses(report, responses...)
return report
}
func newAdmissionReportReportV1(namespace, name string, gvr schema.GroupVersionResource, resource unstructured.Unstructured) kyvernov1alpha2.ReportInterface {
var report kyvernov1alpha2.ReportInterface
if namespace == "" {
report = &reportsv1.ClusterEphemeralReport{Spec: reportsv1.EphemeralReportSpec{}}
} else {
report = &reportsv1.EphemeralReport{Spec: reportsv1.EphemeralReportSpec{}}
}
report.SetName(name)
report.SetNamespace(namespace)
reportutils.SetResourceUid(report, resource.GetUID())
reportutils.SetResourceGVR(report, gvr)
reportutils.SetResourceNamespaceAndName(report, resource.GetNamespace(), resource.GetName())
reportutils.SetManagedByKyvernoLabel(report)
return report
}
func buildAdmissionReportReportV1(resource unstructured.Unstructured, request admissionv1.AdmissionRequest, responses ...engineapi.EngineResponse) kyvernov1alpha2.ReportInterface {
report := newAdmissionReportReportV1(resource.GetNamespace(), string(request.UID), schema.GroupVersionResource(request.Resource), resource)
reportutils.SetResponses(report, responses...)
return report
}
func newBackgroundScanReportV1Alpha1(namespace, name string, gvk schema.GroupVersionKind, owner string, uid types.UID) kyvernov1alpha2.ReportInterface {
var report kyvernov1alpha2.ReportInterface
if namespace == "" {
report = &kyvernov1alpha2.ClusterBackgroundScanReport{}
} else {
report = &kyvernov1alpha2.BackgroundScanReport{}
}
report.SetName(name)
report.SetNamespace(namespace)
controllerutils.SetOwner(report, gvk.GroupVersion().String(), gvk.Kind, owner, uid)
reportutils.SetResourceUid(report, uid)
reportutils.SetManagedByKyvernoLabel(report)
return report
}
func newBackgroundScanReportReportsV1(namespace, name string, gvk schema.GroupVersionKind, owner string, uid types.UID) kyvernov1alpha2.ReportInterface {
var report kyvernov1alpha2.ReportInterface
if namespace == "" {
report = &reportsv1.ClusterEphemeralReport{}
} else {
report = &reportsv1.EphemeralReport{}
}
report.SetName(name)
report.SetNamespace(namespace)
controllerutils.SetOwner(report, gvk.GroupVersion().String(), gvk.Kind, owner, uid)
reportutils.SetResourceUid(report, uid)
reportutils.SetManagedByKyvernoLabel(report)
return report
}

View file

@ -1,247 +0,0 @@
package report
import (
"context"
kyvernov1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2"
reportsv1 "github.com/kyverno/kyverno/api/reports/v1"
"github.com/kyverno/kyverno/pkg/client/clientset/versioned"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
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"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/informers"
metadatainformers "k8s.io/client-go/metadata/metadatainformer"
)
type reportManager struct {
storeInDB bool
client versioned.Interface
}
type Interface interface {
CreateReport(ctx context.Context, report kyvernov1alpha2.ReportInterface) (kyvernov1alpha2.ReportInterface, error)
UpdateReport(ctx context.Context, report kyvernov1alpha2.ReportInterface) (kyvernov1alpha2.ReportInterface, error)
DeleteReport(ctx context.Context, report kyvernov1alpha2.ReportInterface) error
NewAdmissionReport(namespace, name string, gvr schema.GroupVersionResource, resource unstructured.Unstructured) kyvernov1alpha2.ReportInterface
BuildAdmissionReport(resource unstructured.Unstructured, request admissionv1.AdmissionRequest, responses ...engineapi.EngineResponse) kyvernov1alpha2.ReportInterface
NewBackgroundScanReport(namespace, name string, gvk schema.GroupVersionKind, owner string, uid types.UID) kyvernov1alpha2.ReportInterface
GetAdmissionReports(ctx context.Context, name string, namespace string, opts metav1.GetOptions) (kyvernov1alpha2.ReportInterface, error)
ListAdmissionReports(ctx context.Context, namespace string, opts metav1.ListOptions) (runtime.Object, error)
DeleteAdmissionReports(ctx context.Context, name, namespace string, opts metav1.DeleteOptions) error
GetBackgroundScanReports(ctx context.Context, name string, namespace string, opts metav1.GetOptions) (kyvernov1alpha2.ReportInterface, error)
ListBackgroundScanReports(ctx context.Context, namespace string, opts metav1.ListOptions) (runtime.Object, error)
DeleteBackgroundScanReports(ctx context.Context, name, namespace string, opts metav1.DeleteOptions) error
GetClusterAdmissionReports(ctx context.Context, name string, opts metav1.GetOptions) (kyvernov1alpha2.ReportInterface, error)
ListClusterAdmissionReports(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error)
DeleteClusterAdmissionReports(ctx context.Context, namespace string, opts metav1.DeleteOptions) error
GetClusterBackgroundScanReports(ctx context.Context, name string, opts metav1.GetOptions) (kyvernov1alpha2.ReportInterface, error)
ListClusterBackgroundScanReports(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error)
DeleteClusterBackgroundScanReports(ctx context.Context, namespace string, opts metav1.DeleteOptions) error
AdmissionReportInformer(metadataFactory metadatainformers.SharedInformerFactory) informers.GenericInformer
ClusterAdmissionReportInformer(metadataFactory metadatainformers.SharedInformerFactory) informers.GenericInformer
BackgroundScanReportInformer(metadataFactory metadatainformers.SharedInformerFactory) informers.GenericInformer
ClusterBackgroundScanReportInformer(metadataFactory metadatainformers.SharedInformerFactory) informers.GenericInformer
DeepCopy(report kyvernov1alpha2.ReportInterface) kyvernov1alpha2.ReportInterface
}
func NewReportManager(storeInDB bool, client versioned.Interface) Interface {
return &reportManager{
storeInDB: storeInDB,
client: client,
}
}
func (r *reportManager) CreateReport(ctx context.Context, report kyvernov1alpha2.ReportInterface) (kyvernov1alpha2.ReportInterface, error) {
if r.storeInDB {
return createReportV1Report(ctx, report, r.client)
} else {
return createV1Alpha1Report(ctx, report, r.client)
}
}
func (r *reportManager) UpdateReport(ctx context.Context, report kyvernov1alpha2.ReportInterface) (kyvernov1alpha2.ReportInterface, error) {
if r.storeInDB {
return updateReportsV1Report(ctx, report, r.client)
} else {
return updateV1Alpha1Report(ctx, report, r.client)
}
}
func (r *reportManager) DeleteReport(ctx context.Context, report kyvernov1alpha2.ReportInterface) error {
if r.storeInDB {
return deleteReportV1Reports(ctx, report, r.client)
} else {
return deleteV1Alpha1Reports(ctx, report, r.client)
}
}
func (r *reportManager) GetAdmissionReports(ctx context.Context, name string, namespace string, opts metav1.GetOptions) (kyvernov1alpha2.ReportInterface, error) {
if r.storeInDB {
return r.client.ReportsV1().EphemeralReports(namespace).Get(ctx, name, opts)
} else {
return r.client.KyvernoV1alpha2().AdmissionReports(namespace).Get(ctx, name, opts)
}
}
func (r *reportManager) ListAdmissionReports(ctx context.Context, namespace string, opts metav1.ListOptions) (runtime.Object, error) {
if r.storeInDB {
return r.client.ReportsV1().EphemeralReports(namespace).List(ctx, opts)
} else {
return r.client.KyvernoV1alpha2().AdmissionReports(namespace).List(ctx, opts)
}
}
func (r *reportManager) DeleteAdmissionReports(ctx context.Context, name, namespace string, opts metav1.DeleteOptions) error {
if r.storeInDB {
return r.client.ReportsV1().EphemeralReports(namespace).Delete(ctx, name, opts)
} else {
return r.client.KyvernoV1alpha2().AdmissionReports(namespace).Delete(ctx, name, opts)
}
}
func (r *reportManager) GetBackgroundScanReports(ctx context.Context, name string, namespace string, opts metav1.GetOptions) (kyvernov1alpha2.ReportInterface, error) {
if r.storeInDB {
return r.client.ReportsV1().EphemeralReports(namespace).Get(ctx, name, opts)
} else {
return r.client.KyvernoV1alpha2().BackgroundScanReports(namespace).Get(ctx, name, opts)
}
}
func (r *reportManager) ListBackgroundScanReports(ctx context.Context, namespace string, opts metav1.ListOptions) (runtime.Object, error) {
if r.storeInDB {
return r.client.ReportsV1().EphemeralReports(namespace).List(ctx, opts)
} else {
return r.client.KyvernoV1alpha2().BackgroundScanReports(namespace).List(ctx, opts)
}
}
func (r *reportManager) DeleteBackgroundScanReports(ctx context.Context, name, namespace string, opts metav1.DeleteOptions) error {
if r.storeInDB {
return r.client.ReportsV1().EphemeralReports(namespace).Delete(ctx, name, opts)
} else {
return r.client.KyvernoV1alpha2().BackgroundScanReports(namespace).Delete(ctx, name, opts)
}
}
func (r *reportManager) GetClusterAdmissionReports(ctx context.Context, name string, opts metav1.GetOptions) (kyvernov1alpha2.ReportInterface, error) {
if r.storeInDB {
return r.client.ReportsV1().ClusterEphemeralReports().Get(ctx, name, opts)
} else {
return r.client.KyvernoV1alpha2().ClusterAdmissionReports().Get(ctx, name, opts)
}
}
func (r *reportManager) ListClusterAdmissionReports(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) {
if r.storeInDB {
return r.client.ReportsV1().ClusterEphemeralReports().List(ctx, opts)
} else {
return r.client.KyvernoV1alpha2().ClusterAdmissionReports().List(ctx, opts)
}
}
func (r *reportManager) DeleteClusterAdmissionReports(ctx context.Context, name string, opts metav1.DeleteOptions) error {
if r.storeInDB {
return r.client.ReportsV1().ClusterEphemeralReports().Delete(ctx, name, opts)
} else {
return r.client.KyvernoV1alpha2().ClusterAdmissionReports().Delete(ctx, name, opts)
}
}
func (r *reportManager) GetClusterBackgroundScanReports(ctx context.Context, name string, opts metav1.GetOptions) (kyvernov1alpha2.ReportInterface, error) {
if r.storeInDB {
return r.client.ReportsV1().ClusterEphemeralReports().Get(ctx, name, opts)
} else {
return r.client.KyvernoV1alpha2().ClusterBackgroundScanReports().Get(ctx, name, opts)
}
}
func (r *reportManager) ListClusterBackgroundScanReports(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) {
if r.storeInDB {
return r.client.ReportsV1().ClusterEphemeralReports().List(ctx, opts)
} else {
return r.client.KyvernoV1alpha2().ClusterBackgroundScanReports().List(ctx, opts)
}
}
func (r *reportManager) DeleteClusterBackgroundScanReports(ctx context.Context, name string, opts metav1.DeleteOptions) error {
if r.storeInDB {
return r.client.ReportsV1().ClusterEphemeralReports().Delete(ctx, name, opts)
} else {
return r.client.KyvernoV1alpha2().ClusterBackgroundScanReports().Delete(ctx, name, opts)
}
}
func (r *reportManager) NewAdmissionReport(namespace, name string, gvr schema.GroupVersionResource, resource unstructured.Unstructured) kyvernov1alpha2.ReportInterface {
if r.storeInDB {
return newAdmissionReportReportV1(namespace, name, gvr, resource)
} else {
return newAdmissionReportV1Alpha1(namespace, name, gvr, resource)
}
}
func (r *reportManager) BuildAdmissionReport(resource unstructured.Unstructured, request admissionv1.AdmissionRequest, responses ...engineapi.EngineResponse) kyvernov1alpha2.ReportInterface {
if r.storeInDB {
return buildAdmissionReportReportV1(resource, request, responses...)
} else {
return buildAdmissionReportV1Alpha1(resource, request, responses...)
}
}
func (r *reportManager) NewBackgroundScanReport(namespace, name string, gvk schema.GroupVersionKind, owner string, uid types.UID) kyvernov1alpha2.ReportInterface {
if r.storeInDB {
return newBackgroundScanReportReportsV1(namespace, name, gvk, owner, uid)
} else {
return newBackgroundScanReportV1Alpha1(namespace, name, gvk, owner, uid)
}
}
func (r *reportManager) AdmissionReportInformer(metadataFactory metadatainformers.SharedInformerFactory) informers.GenericInformer {
if r.storeInDB {
return metadataFactory.ForResource(reportsv1.SchemeGroupVersion.WithResource("admissionreports"))
} else {
return metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("admissionreports"))
}
}
func (r *reportManager) ClusterAdmissionReportInformer(metadataFactory metadatainformers.SharedInformerFactory) informers.GenericInformer {
if r.storeInDB {
return metadataFactory.ForResource(reportsv1.SchemeGroupVersion.WithResource("clusteradmissionreports"))
} else {
return metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("clusteradmissionreports"))
}
}
func (r *reportManager) BackgroundScanReportInformer(metadataFactory metadatainformers.SharedInformerFactory) informers.GenericInformer {
if r.storeInDB {
return metadataFactory.ForResource(reportsv1.SchemeGroupVersion.WithResource("backgroundscanreports"))
} else {
return metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("backgroundscanreports"))
}
}
func (r *reportManager) ClusterBackgroundScanReportInformer(metadataFactory metadatainformers.SharedInformerFactory) informers.GenericInformer {
if r.storeInDB {
return metadataFactory.ForResource(reportsv1.SchemeGroupVersion.WithResource("clusterbackgroundscanreports"))
} else {
return metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("clusterbackgroundscanreports"))
}
}
func (r *reportManager) DeepCopy(report kyvernov1alpha2.ReportInterface) kyvernov1alpha2.ReportInterface {
if r.storeInDB {
return deepCopyReportV1(report)
} else {
return deepCopyV1Alpha2(report)
}
}

View file

@ -6,7 +6,7 @@ import (
reportsv1 "github.com/kyverno/kyverno/api/reports/v1"
)
func deepCopyV1Alpha2(report kyvernov1alpha2.ReportInterface) kyvernov1alpha2.ReportInterface {
func DeepCopy(report kyvernov1alpha2.ReportInterface) kyvernov1alpha2.ReportInterface {
switch v := report.(type) {
case *kyvernov1alpha2.AdmissionReport:
return v.DeepCopy()
@ -20,21 +20,10 @@ func deepCopyV1Alpha2(report kyvernov1alpha2.ReportInterface) kyvernov1alpha2.Re
return v.DeepCopy()
case *policyreportv1alpha2.ClusterPolicyReport:
return v.DeepCopy()
default:
return nil
}
}
func deepCopyReportV1(report kyvernov1alpha2.ReportInterface) kyvernov1alpha2.ReportInterface {
switch v := report.(type) {
case *reportsv1.EphemeralReport:
return v.DeepCopy()
case *reportsv1.ClusterEphemeralReport:
return v.DeepCopy()
case *policyreportv1alpha2.PolicyReport:
return v.DeepCopy()
case *policyreportv1alpha2.ClusterPolicyReport:
return v.DeepCopy()
default:
return nil
}

View file

@ -11,7 +11,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func createV1Alpha1Report(ctx context.Context, report kyvernov1alpha2.ReportInterface, client versioned.Interface) (kyvernov1alpha2.ReportInterface, error) {
func CreateReport(ctx context.Context, report kyvernov1alpha2.ReportInterface, client versioned.Interface) (kyvernov1alpha2.ReportInterface, error) {
switch v := report.(type) {
case *kyvernov1alpha2.AdmissionReport:
report, err := client.KyvernoV1alpha2().AdmissionReports(report.GetNamespace()).Create(ctx, v, metav1.CreateOptions{})
@ -31,25 +31,12 @@ func createV1Alpha1Report(ctx context.Context, report kyvernov1alpha2.ReportInte
case *policyreportv1alpha2.ClusterPolicyReport:
report, err := client.Wgpolicyk8sV1alpha2().ClusterPolicyReports().Create(ctx, v, metav1.CreateOptions{})
return report, err
default:
return nil, errors.New("unknow type")
}
}
func createReportV1Report(ctx context.Context, report kyvernov1alpha2.ReportInterface, client versioned.Interface) (kyvernov1alpha2.ReportInterface, error) {
switch v := report.(type) {
case *reportsv1.EphemeralReport:
report, err := client.ReportsV1().EphemeralReports(report.GetNamespace()).Create(ctx, v, metav1.CreateOptions{})
return report, err
case *reportsv1.ClusterEphemeralReport:
report, err := client.ReportsV1().ClusterEphemeralReports().Create(ctx, v, metav1.CreateOptions{})
return report, err
case *policyreportv1alpha2.PolicyReport:
report, err := client.Wgpolicyk8sV1alpha2().PolicyReports(report.GetNamespace()).Create(ctx, v, metav1.CreateOptions{})
return report, err
case *policyreportv1alpha2.ClusterPolicyReport:
report, err := client.Wgpolicyk8sV1alpha2().ClusterPolicyReports().Create(ctx, v, metav1.CreateOptions{})
return report, err
default:
return nil, errors.New("unknow type")
}

View file

@ -11,7 +11,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func deleteV1Alpha1Reports(ctx context.Context, report kyvernov1alpha2.ReportInterface, client versioned.Interface) error {
func DeleteReport(ctx context.Context, report kyvernov1alpha2.ReportInterface, client versioned.Interface) error {
switch v := report.(type) {
case *kyvernov1alpha2.AdmissionReport:
return client.KyvernoV1alpha2().AdmissionReports(report.GetNamespace()).Delete(ctx, v.GetName(), metav1.DeleteOptions{})
@ -25,21 +25,10 @@ func deleteV1Alpha1Reports(ctx context.Context, report kyvernov1alpha2.ReportInt
return client.Wgpolicyk8sV1alpha2().PolicyReports(report.GetNamespace()).Delete(ctx, v.GetName(), metav1.DeleteOptions{})
case *policyreportv1alpha2.ClusterPolicyReport:
return client.Wgpolicyk8sV1alpha2().ClusterPolicyReports().Delete(ctx, v.GetName(), metav1.DeleteOptions{})
default:
return errors.New("unknow type")
}
}
func deleteReportV1Reports(ctx context.Context, report kyvernov1alpha2.ReportInterface, client versioned.Interface) error {
switch v := report.(type) {
case *reportsv1.EphemeralReport:
return client.ReportsV1().EphemeralReports(report.GetNamespace()).Delete(ctx, v.GetName(), metav1.DeleteOptions{})
case *reportsv1.ClusterEphemeralReport:
return client.ReportsV1().ClusterEphemeralReports().Delete(ctx, v.GetName(), metav1.DeleteOptions{})
case *policyreportv1alpha2.PolicyReport:
return client.Wgpolicyk8sV1alpha2().PolicyReports(report.GetNamespace()).Delete(ctx, v.GetName(), metav1.DeleteOptions{})
case *policyreportv1alpha2.ClusterPolicyReport:
return client.Wgpolicyk8sV1alpha2().ClusterPolicyReports().Delete(ctx, v.GetName(), metav1.DeleteOptions{})
default:
return errors.New("unknow type")
}

View file

@ -27,6 +27,10 @@ const (
LabelResourceHash = "audit.kyverno.io/resource.hash"
LabelResourceUid = "audit.kyverno.io/resource.uid"
LabelResourceGVR = "audit.kyverno.io/resource.gvr"
LabelResourceGroup = "audit.kyverno.io/resource.group"
LabelResourceVersion = "audit.kyverno.io/resource.version"
LabelResourceKind = "audit.kyverno.io/resource.kind"
LabelSource = "audit.kyverno.io/source"
AnnotationResourceNamespace = "audit.kyverno.io/resource.namespace"
AnnotationResourceName = "audit.kyverno.io/resource.name"
// policy labels
@ -103,6 +107,10 @@ func SetManagedByKyvernoLabel(obj metav1.Object) {
controllerutils.SetLabel(obj, kyverno.LabelAppManagedBy, kyverno.ValueKyvernoApp)
}
func SetSource(obj metav1.Object, source string) {
controllerutils.SetLabel(obj, LabelSource, source)
}
func SetResourceUid(report kyvernov1alpha2.ReportInterface, uid types.UID) {
controllerutils.SetLabel(report, LabelResourceUid, string(uid))
}
@ -115,6 +123,12 @@ func SetResourceGVR(report kyvernov1alpha2.ReportInterface, gvr schema.GroupVers
}
}
func SetResourceGVK(report kyvernov1alpha2.ReportInterface, gvk schema.GroupVersionKind) {
controllerutils.SetLabel(report, LabelResourceGroup, gvk.Group)
controllerutils.SetLabel(report, LabelResourceVersion, gvk.Version)
controllerutils.SetLabel(report, LabelResourceKind, gvk.Kind)
}
func SetResourceNamespaceAndName(report kyvernov1alpha2.ReportInterface, namespace, name string) {
controllerutils.SetAnnotation(report, AnnotationResourceNamespace, namespace)
controllerutils.SetAnnotation(report, AnnotationResourceName, name)
@ -159,6 +173,10 @@ func SetValidatingAdmissionPolicyBindingLabel(report kyvernov1alpha2.ReportInter
controllerutils.SetLabel(report, ValidatingAdmissionPolicyBindingLabel(binding), binding.GetResourceVersion())
}
func GetSource(report metav1.Object) string {
return controllerutils.GetLabel(report, LabelSource)
}
func GetResourceUid(report metav1.Object) types.UID {
return types.UID(controllerutils.GetLabel(report, LabelResourceUid))
}

View file

@ -3,9 +3,58 @@ package report
import (
kyvernov1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2"
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
reportsv1 "github.com/kyverno/kyverno/api/reports/v1"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
admissionv1 "k8s.io/api/admission/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
)
func NewAdmissionReport(namespace, name string, gvr schema.GroupVersionResource, gvk schema.GroupVersionKind, resource unstructured.Unstructured) kyvernov1alpha2.ReportInterface {
var report kyvernov1alpha2.ReportInterface
if namespace == "" {
report = &reportsv1.ClusterEphemeralReport{Spec: reportsv1.EphemeralReportSpec{}}
} else {
report = &reportsv1.EphemeralReport{Spec: reportsv1.EphemeralReportSpec{}}
}
report.SetName(name)
report.SetNamespace(namespace)
SetResourceUid(report, resource.GetUID())
SetResourceGVR(report, gvr)
SetResourceGVK(report, gvk)
SetResourceNamespaceAndName(report, resource.GetNamespace(), resource.GetName())
SetManagedByKyvernoLabel(report)
SetSource(report, "admission")
return report
}
func BuildAdmissionReport(resource unstructured.Unstructured, request admissionv1.AdmissionRequest, responses ...engineapi.EngineResponse) kyvernov1alpha2.ReportInterface {
report := NewAdmissionReport(resource.GetNamespace(), string(request.UID), schema.GroupVersionResource(request.Resource), schema.GroupVersionKind(request.Kind), resource)
SetResponses(report, responses...)
return report
}
func NewBackgroundScanReport(namespace, name string, gvk schema.GroupVersionKind, owner string, uid types.UID) kyvernov1alpha2.ReportInterface {
var report kyvernov1alpha2.ReportInterface
if namespace == "" {
report = &reportsv1.ClusterEphemeralReport{}
} else {
report = &reportsv1.EphemeralReport{}
}
report.SetName(name)
report.SetNamespace(namespace)
controllerutils.SetOwner(report, gvk.GroupVersion().String(), gvk.Kind, owner, uid)
SetResourceUid(report, uid)
SetResourceGVK(report, gvk)
SetResourceNamespaceAndName(report, namespace, owner)
SetManagedByKyvernoLabel(report)
SetSource(report, "background-scan")
return report
}
func NewPolicyReport(namespace, name string, scope *corev1.ObjectReference, results ...policyreportv1alpha2.PolicyReportResult) kyvernov1alpha2.ReportInterface {
var report kyvernov1alpha2.ReportInterface
if namespace == "" {

View file

@ -11,7 +11,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func updateV1Alpha1Report(ctx context.Context, report kyvernov1alpha2.ReportInterface, client versioned.Interface) (kyvernov1alpha2.ReportInterface, error) {
func UpdateReport(ctx context.Context, report kyvernov1alpha2.ReportInterface, client versioned.Interface) (kyvernov1alpha2.ReportInterface, error) {
switch v := report.(type) {
case *kyvernov1alpha2.AdmissionReport:
report, err := client.KyvernoV1alpha2().AdmissionReports(report.GetNamespace()).Update(ctx, v, metav1.UpdateOptions{})
@ -31,25 +31,12 @@ func updateV1Alpha1Report(ctx context.Context, report kyvernov1alpha2.ReportInte
case *policyreportv1alpha2.ClusterPolicyReport:
report, err := client.Wgpolicyk8sV1alpha2().ClusterPolicyReports().Update(ctx, v, metav1.UpdateOptions{})
return report, err
default:
return nil, errors.New("unknow type")
}
}
func updateReportsV1Report(ctx context.Context, report kyvernov1alpha2.ReportInterface, client versioned.Interface) (kyvernov1alpha2.ReportInterface, error) {
switch v := report.(type) {
case *reportsv1.EphemeralReport:
report, err := client.ReportsV1().EphemeralReports(report.GetNamespace()).Update(ctx, v, metav1.UpdateOptions{})
return report, err
case *reportsv1.ClusterEphemeralReport:
report, err := client.ReportsV1().ClusterEphemeralReports().Update(ctx, v, metav1.UpdateOptions{})
return report, err
case *policyreportv1alpha2.PolicyReport:
report, err := client.Wgpolicyk8sV1alpha2().PolicyReports(report.GetNamespace()).Update(ctx, v, metav1.UpdateOptions{})
return report, err
case *policyreportv1alpha2.ClusterPolicyReport:
report, err := client.Wgpolicyk8sV1alpha2().ClusterPolicyReports().Update(ctx, v, metav1.UpdateOptions{})
return report, err
default:
return nil, errors.New("unknow type")
}

View file

@ -20,7 +20,6 @@ import (
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/policycache"
"github.com/kyverno/kyverno/pkg/report"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
engineutils "github.com/kyverno/kyverno/pkg/utils/engine"
jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
@ -39,7 +38,6 @@ type resourceHandlers struct {
// clients
client dclient.Interface
kyvernoClient versioned.Interface
reportManager report.Interface
engine engineapi.Engine
// config
@ -67,7 +65,6 @@ func NewHandlers(
engine engineapi.Engine,
client dclient.Interface,
kyvernoClient versioned.Interface,
reportManager report.Interface,
configuration config.Configuration,
metricsConfig metrics.MetricsConfigManager,
pCache policycache.Cache,
@ -85,7 +82,6 @@ func NewHandlers(
engine: engine,
client: client,
kyvernoClient: kyvernoClient,
reportManager: reportManager,
configuration: configuration,
metricsConfig: metricsConfig,
pCache: pCache,
@ -127,7 +123,7 @@ func (h *resourceHandlers) Validate(ctx context.Context, logger logr.Logger, req
namespaceLabels = engineutils.GetNamespaceSelectorsFromNamespaceLister(request.Kind.Kind, request.Namespace, h.nsLister, logger)
}
policyContext = policyContext.WithNamespaceLabels(namespaceLabels)
vh := validation.NewValidationHandler(logger, h.kyvernoClient, h.reportManager, h.engine, h.pCache, h.pcBuilder, h.eventGen, h.admissionReports, h.metricsConfig, h.configuration)
vh := validation.NewValidationHandler(logger, h.kyvernoClient, h.engine, h.pCache, h.pcBuilder, h.eventGen, h.admissionReports, h.metricsConfig, h.configuration)
ok, msg, warnings := vh.HandleValidation(ctx, request, policies, policyContext, startTime)
if !ok {
@ -172,7 +168,7 @@ func (h *resourceHandlers) Mutate(ctx context.Context, logger logr.Logger, reque
logger.Error(err, "failed to build policy context")
return admissionutils.Response(request.UID, err)
}
ivh := imageverification.NewImageVerificationHandler(logger, h.kyvernoClient, h.reportManager, h.engine, h.eventGen, h.admissionReports, h.configuration, h.nsLister)
ivh := imageverification.NewImageVerificationHandler(logger, h.kyvernoClient, h.engine, h.eventGen, h.admissionReports, h.configuration, h.nsLister)
imagePatches, imageVerifyWarnings, err := ivh.Handle(ctx, newRequest, verifyImagesPolicies, policyContext)
if err != nil {
logger.Error(err, "image verification failed")

View file

@ -13,7 +13,6 @@ import (
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/mutate/patch"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/report"
"github.com/kyverno/kyverno/pkg/tracing"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
engineutils "github.com/kyverno/kyverno/pkg/utils/engine"
@ -34,7 +33,6 @@ type ImageVerificationHandler interface {
type imageVerificationHandler struct {
kyvernoClient versioned.Interface
reportManager report.Interface
engine engineapi.Engine
log logr.Logger
eventGen event.Interface
@ -46,7 +44,6 @@ type imageVerificationHandler struct {
func NewImageVerificationHandler(
log logr.Logger,
kyvernoClient versioned.Interface,
reportManager report.Interface,
engine engineapi.Engine,
eventGen event.Interface,
admissionReports bool,
@ -56,7 +53,6 @@ func NewImageVerificationHandler(
return &imageVerificationHandler{
kyvernoClient: kyvernoClient,
engine: engine,
reportManager: reportManager,
log: log,
eventGen: eventGen,
admissionReports: admissionReports,
@ -177,9 +173,9 @@ func (v *imageVerificationHandler) handleAudit(
fmt.Sprintf("AUDIT %s %s", request.Operation, request.Kind),
func(ctx context.Context, span trace.Span) {
if createReport {
report := v.reportManager.BuildAdmissionReport(resource, request, engineResponses...)
report := reportutils.BuildAdmissionReport(resource, request, engineResponses...)
if len(report.GetResults()) > 0 {
_, err := v.reportManager.CreateReport(context.Background(), report)
_, err := reportutils.CreateReport(context.Background(), report, v.kyvernoClient)
if err != nil {
v.log.Error(err, "failed to create report")
}

View file

@ -14,7 +14,6 @@ import (
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/policycache"
"github.com/kyverno/kyverno/pkg/report"
"github.com/kyverno/kyverno/pkg/tracing"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
@ -36,7 +35,6 @@ type ValidationHandler interface {
func NewValidationHandler(
log logr.Logger,
kyvernoClient versioned.Interface,
reportManager report.Interface,
engine engineapi.Engine,
pCache policycache.Cache,
pcBuilder webhookutils.PolicyContextBuilder,
@ -48,7 +46,6 @@ func NewValidationHandler(
return &validationHandler{
log: log,
kyvernoClient: kyvernoClient,
reportManager: reportManager,
engine: engine,
pCache: pCache,
pcBuilder: pcBuilder,
@ -62,7 +59,6 @@ func NewValidationHandler(
type validationHandler struct {
log logr.Logger
kyvernoClient versioned.Interface
reportManager report.Interface
engine engineapi.Engine
pCache policycache.Cache
pcBuilder webhookutils.PolicyContextBuilder
@ -194,9 +190,9 @@ func (v *validationHandler) handleAudit(
v.eventGen.Add(events...)
if createReport {
responses = append(responses, engineResponses...)
report := v.reportManager.BuildAdmissionReport(resource, request.AdmissionRequest, responses...)
report := reportutils.BuildAdmissionReport(resource, request.AdmissionRequest, responses...)
if len(report.GetResults()) > 0 {
_, err = v.reportManager.CreateReport(ctx, report)
_, err = reportutils.CreateReport(ctx, report, v.kyvernoClient)
if err != nil {
v.log.Error(err, "failed to create report")
}

View file

@ -6,13 +6,13 @@ metadata:
namespace: test-cm-lookup
results:
- policy: validate-labels
resources:
- apiVersion: v1
kind: Pod
name: test-cm-lookup-pod
namespace: test-cm-lookup
result: pass
rule: validate-labels
scope:
apiVersion: v1
kind: Pod
name: test-cm-lookup-pod
namespace: test-cm-lookup
summary:
error: 0
fail: 0