1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-15 12:17:56 +00:00

feat: add basic structure for image verify cache (#7890)

* feat: add interface for image verify cache

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* feat: add basic client for cache

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* feat: add ttl to client

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* feat: add flags and flag setup

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* feat: added a default image verify cache

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* feat: add propogation of cache to image verifier

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* feat: add useCache to image verification types

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* bug: add ivcache to image verifier

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* feat: add logger to cache

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* typo: DisabledImageVerfiyCache

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* typo: DisabledImageVerfiyCache

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* Update cmd/internal/flag.go

Signed-off-by: shuting <shutting06@gmail.com>

* feat: add use cache to v2beta1 crd

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* bug: change public attribute TTL to private

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* fix: replace nil in test with disabled cache

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* fix: convert ttl time to time.Duration

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* feat: update opts to use time.Duration

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* feat:add policy version and remove delete functions

by adding policy version, old entries will automatically become outdated and we will not have to remove them manually

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* feat: remove clear and update get and set to take interface as input

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

* style: fix lint issue

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>

---------

Signed-off-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>
Signed-off-by: shuting <shutting06@gmail.com>
Co-authored-by: shuting <shutting06@gmail.com>
Co-authored-by: shuting <shuting@nirmata.com>
Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Vishal Choudhary 2023-08-07 01:24:52 +05:30 committed by GitHub
parent bc95283b04
commit b385693509
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 411 additions and 30 deletions

View file

@ -109,6 +109,11 @@ type ImageVerification struct {
// ImageRegistryCredentials provides credentials that will be used for authentication with registry // ImageRegistryCredentials provides credentials that will be used for authentication with registry
// +kubebuilder:validation:Optional // +kubebuilder:validation:Optional
ImageRegistryCredentials *ImageRegistryCredentials `json:"imageRegistryCredentials,omitempty" yaml:"imageRegistryCredentials,omitempty"` ImageRegistryCredentials *ImageRegistryCredentials `json:"imageRegistryCredentials,omitempty" yaml:"imageRegistryCredentials,omitempty"`
// UseCache enables caching of image verify responses for this rule
// +kubebuilder:default=true
// +kubebuilder:validation:Optional
UseCache bool `json:"useCache" yaml:"useCache"`
} }
type AttestorSet struct { type AttestorSet struct {

View file

@ -54,6 +54,11 @@ type ImageVerification struct {
// ImageRegistryCredentials provides credentials that will be used for authentication with registry // ImageRegistryCredentials provides credentials that will be used for authentication with registry
// +kubebuilder:validation:Optional // +kubebuilder:validation:Optional
ImageRegistryCredentials *kyvernov1.ImageRegistryCredentials `json:"imageRegistryCredentials,omitempty" yaml:"imageRegistryCredentials,omitempty"` ImageRegistryCredentials *kyvernov1.ImageRegistryCredentials `json:"imageRegistryCredentials,omitempty" yaml:"imageRegistryCredentials,omitempty"`
// UseCache enables caching of image verify responses for this rule
// +kubebuilder:default=true
// +kubebuilder:validation:Optional
UseCache bool `json:"useCache" yaml:"useCache"`
} }
// Validate implements programmatic validation // Validate implements programmatic validation

View file

@ -7748,6 +7748,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have a description: VerifyDigest validates that images have a
@ -11851,6 +11856,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have description: VerifyDigest validates that images have
@ -15596,6 +15606,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have a description: VerifyDigest validates that images have a
@ -19699,6 +19714,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have description: VerifyDigest validates that images have
@ -23755,6 +23775,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have a description: VerifyDigest validates that images have a
@ -27859,6 +27884,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have description: VerifyDigest validates that images have
@ -31605,6 +31635,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have a description: VerifyDigest validates that images have a
@ -35708,6 +35743,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have description: VerifyDigest validates that images have

View file

@ -157,6 +157,7 @@ func main() {
setup.Jp, setup.Jp,
setup.KyvernoDynamicClient, setup.KyvernoDynamicClient,
setup.RegistryClient, setup.RegistryClient,
setup.ImageVerifyCacheClient,
setup.KubeClient, setup.KubeClient,
setup.KyvernoClient, setup.KyvernoClient,
setup.RegistrySecretLister, setup.RegistrySecretLister,

View file

@ -16,6 +16,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine/factories" "github.com/kyverno/kyverno/pkg/engine/factories"
"github.com/kyverno/kyverno/pkg/engine/jmespath" "github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/event" "github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/metrics"
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller" controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
"github.com/kyverno/kyverno/pkg/utils/match" "github.com/kyverno/kyverno/pkg/utils/match"
@ -130,6 +131,7 @@ func (h *handlers) executePolicy(
h.jp, h.jp,
h.client, h.client,
nil, nil,
imageverifycache.DisabledImageVerifyCache(),
spec.Context, spec.Context,
enginectx, enginectx,
); err != nil { ); err != nil {

View file

@ -27,6 +27,7 @@ import (
engineapi "github.com/kyverno/kyverno/pkg/engine/api" engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/jmespath" "github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/engine/variables/regex" "github.com/kyverno/kyverno/pkg/engine/variables/regex"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/logging" "github.com/kyverno/kyverno/pkg/logging"
datautils "github.com/kyverno/kyverno/pkg/utils/data" datautils "github.com/kyverno/kyverno/pkg/utils/data"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
@ -790,6 +791,7 @@ func initializeMockController(objects []runtime.Object) (*generate.GenerateContr
jmespath.New(cfg), jmespath.New(cfg),
adapters.Client(client), adapters.Client(client),
nil, nil,
imageverifycache.DisabledImageVerifyCache(),
store.ContextLoaderFactory(nil), store.ContextLoaderFactory(nil),
nil, nil,
"", "",

View file

@ -15,6 +15,7 @@ import (
engineapi "github.com/kyverno/kyverno/pkg/engine/api" engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/factories" "github.com/kyverno/kyverno/pkg/engine/factories"
"github.com/kyverno/kyverno/pkg/engine/jmespath" "github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/registryclient" "github.com/kyverno/kyverno/pkg/registryclient"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
@ -119,6 +120,7 @@ OuterLoop:
jmespath.New(cfg), jmespath.New(cfg),
adapters.Client(c.Client), adapters.Client(c.Client),
factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil), factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil),
imageverifycache.DisabledImageVerifyCache(),
store.ContextLoaderFactory(nil), store.ContextLoaderFactory(nil),
nil, nil,
"", "",

View file

@ -8,6 +8,7 @@ import (
enginecontext "github.com/kyverno/kyverno/pkg/engine/context" enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/factories" "github.com/kyverno/kyverno/pkg/engine/factories"
"github.com/kyverno/kyverno/pkg/engine/jmespath" "github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/imageverifycache"
) )
func ContextLoaderFactory(cmResolver engineapi.ConfigmapResolver) engineapi.ContextLoaderFactory { func ContextLoaderFactory(cmResolver engineapi.ConfigmapResolver) engineapi.ContextLoaderFactory {
@ -48,6 +49,7 @@ func (w wrapper) Load(
jp jmespath.Interface, jp jmespath.Interface,
client engineapi.RawClient, client engineapi.RawClient,
rclientFactory engineapi.RegistryClientFactory, rclientFactory engineapi.RegistryClientFactory,
ivCache imageverifycache.Client,
contextEntries []kyvernov1.ContextEntry, contextEntries []kyvernov1.ContextEntry,
jsonContext enginecontext.Interface, jsonContext enginecontext.Interface,
) error { ) error {
@ -57,5 +59,5 @@ func (w wrapper) Load(
if !GetRegistryAccess() { if !GetRegistryAccess() {
rclientFactory = nil rclientFactory = nil
} }
return w.inner.Load(ctx, jp, client, rclientFactory, contextEntries, jsonContext) return w.inner.Load(ctx, jp, client, rclientFactory, ivCache, contextEntries, jsonContext)
} }

View file

@ -14,6 +14,7 @@ type Configuration interface {
UsesDeferredLoading() bool UsesDeferredLoading() bool
UsesCosign() bool UsesCosign() bool
UsesRegistryClient() bool UsesRegistryClient() bool
UsesImageVerifyCache() bool
UsesLeaderElection() bool UsesLeaderElection() bool
UsesKyvernoClient() bool UsesKyvernoClient() bool
UsesDynamicClient() bool UsesDynamicClient() bool
@ -87,6 +88,12 @@ func WithRegistryClient() ConfigurationOption {
} }
} }
func WithImageVerifyCache() ConfigurationOption {
return func(c *configuration) {
c.usesImageVerifyCache = true
}
}
func WithLeaderElection() ConfigurationOption { func WithLeaderElection() ConfigurationOption {
return func(c *configuration) { return func(c *configuration) {
c.usesLeaderElection = true c.usesLeaderElection = true
@ -141,6 +148,7 @@ type configuration struct {
usesDeferredLoading bool usesDeferredLoading bool
usesCosign bool usesCosign bool
usesRegistryClient bool usesRegistryClient bool
usesImageVerifyCache bool
usesLeaderElection bool usesLeaderElection bool
usesKyvernoClient bool usesKyvernoClient bool
usesDynamicClient bool usesDynamicClient bool
@ -186,6 +194,10 @@ func (c *configuration) UsesRegistryClient() bool {
return c.usesRegistryClient return c.usesRegistryClient
} }
func (c *configuration) UsesImageVerifyCache() bool {
return c.usesImageVerifyCache
}
func (c *configuration) UsesLeaderElection() bool { func (c *configuration) UsesLeaderElection() bool {
return c.usesLeaderElection return c.usesLeaderElection
} }

View file

@ -16,6 +16,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine/context/resolvers" "github.com/kyverno/kyverno/pkg/engine/context/resolvers"
"github.com/kyverno/kyverno/pkg/engine/factories" "github.com/kyverno/kyverno/pkg/engine/factories"
"github.com/kyverno/kyverno/pkg/engine/jmespath" "github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/registryclient" "github.com/kyverno/kyverno/pkg/registryclient"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
corev1listers "k8s.io/client-go/listers/core/v1" corev1listers "k8s.io/client-go/listers/core/v1"
@ -29,6 +30,7 @@ func NewEngine(
jp jmespath.Interface, jp jmespath.Interface,
client dclient.Interface, client dclient.Interface,
rclient registryclient.Client, rclient registryclient.Client,
ivCache imageverifycache.Client,
kubeClient kubernetes.Interface, kubeClient kubernetes.Interface,
kyvernoClient versioned.Interface, kyvernoClient versioned.Interface,
secretLister corev1listers.SecretNamespaceLister, secretLister corev1listers.SecretNamespaceLister,
@ -43,6 +45,7 @@ func NewEngine(
jp, jp,
adapters.Client(client), adapters.Client(client),
factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), secretLister), factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), secretLister),
ivCache,
factories.DefaultContextLoaderFactory(configMapResolver), factories.DefaultContextLoaderFactory(configMapResolver),
exceptionsSelector, exceptionsSelector,
imageSignatureRepository, imageSignatureRepository,

View file

@ -44,6 +44,10 @@ var (
registryCredentialHelpers string registryCredentialHelpers string
// leader election // leader election
leaderElectionRetryPeriod time.Duration leaderElectionRetryPeriod time.Duration
// image verify cache
imageVerifyCacheEnabled bool
imageVerifyCacheTTLDuration int64
imageVerifyCacheMaxSize int64
) )
func initLoggingFlags() { func initLoggingFlags() {
@ -102,6 +106,12 @@ func initRegistryClientFlags() {
flag.StringVar(&registryCredentialHelpers, "registryCredentialHelpers", "", "Credential helpers to enable (default,google,amazon,azure,github). No helpers are added when this flag is empty.") flag.StringVar(&registryCredentialHelpers, "registryCredentialHelpers", "", "Credential helpers to enable (default,google,amazon,azure,github). No helpers are added when this flag is empty.")
} }
func initImageVerifyCacheFlags() {
flag.BoolVar(&imageVerifyCacheEnabled, "imageVerifyCacheEnabled", true, "Whether to use a TTL cache for storing verified images.")
flag.Int64Var(&imageVerifyCacheMaxSize, "imageVerifyCacheMaxSize", 0, "Max size limit for the TTL cache, 0 means no size limit.")
flag.Int64Var(&imageVerifyCacheTTLDuration, "imageVerifyCacheTTLDuration", 0, "Max TTL value for a cache, 0 means no TTL.")
}
func initLeaderElectionFlags() { func initLeaderElectionFlags() {
flag.DurationVar(&leaderElectionRetryPeriod, "leaderElectionRetryPeriod", leaderelection.DefaultRetryPeriod, "Configure leader election retry period.") flag.DurationVar(&leaderElectionRetryPeriod, "leaderElectionRetryPeriod", leaderelection.DefaultRetryPeriod, "Configure leader election retry period.")
} }
@ -177,6 +187,10 @@ func initFlags(config Configuration, opts ...Option) {
if config.UsesRegistryClient() { if config.UsesRegistryClient() {
initRegistryClientFlags() initRegistryClientFlags()
} }
// image verify cache
if config.UsesImageVerifyCache() {
initImageVerifyCacheFlags()
}
// leader election // leader election
if config.UsesLeaderElection() { if config.UsesLeaderElection() {
initLeaderElectionFlags() initLeaderElectionFlags()

View file

@ -0,0 +1,23 @@
package internal
import (
"context"
"time"
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/imageverifycache"
)
func setupImageVerifyCache(ctx context.Context, logger logr.Logger) imageverifycache.Client {
logger = logger.WithName("image-verify-cache").WithValues("enabled", imageVerifyCacheEnabled, "maxsize", imageVerifyCacheMaxSize, "ttl", imageVerifyCacheTTLDuration)
logger.Info("setup image verify cache...")
opts := []imageverifycache.Option{
imageverifycache.WithLogger(logger),
imageverifycache.WithCacheEnableFlag(imageVerifyCacheEnabled),
imageverifycache.WithMaxSize(imageVerifyCacheMaxSize),
imageverifycache.WithTTLDuration(time.Duration(imageVerifyCacheTTLDuration)),
}
imageVerifyCache, err := imageverifycache.New(opts...)
checkError(logger, err, "failed to create image verify cache client")
return imageVerifyCache
}

View file

@ -13,6 +13,7 @@ import (
metadataclient "github.com/kyverno/kyverno/pkg/clients/metadata" metadataclient "github.com/kyverno/kyverno/pkg/clients/metadata"
"github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine/jmespath" "github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/registryclient" "github.com/kyverno/kyverno/pkg/registryclient"
corev1listers "k8s.io/client-go/listers/core/v1" corev1listers "k8s.io/client-go/listers/core/v1"
@ -30,20 +31,21 @@ func shutdown(logger logr.Logger, sdowns ...context.CancelFunc) context.CancelFu
} }
type SetupResult struct { type SetupResult struct {
Logger logr.Logger Logger logr.Logger
Configuration config.Configuration Configuration config.Configuration
MetricsConfiguration config.MetricsConfiguration MetricsConfiguration config.MetricsConfiguration
MetricsManager metrics.MetricsConfigManager MetricsManager metrics.MetricsConfigManager
Jp jmespath.Interface Jp jmespath.Interface
KubeClient kubeclient.UpstreamInterface KubeClient kubeclient.UpstreamInterface
LeaderElectionClient kubeclient.UpstreamInterface LeaderElectionClient kubeclient.UpstreamInterface
RegistryClient registryclient.Client RegistryClient registryclient.Client
RegistrySecretLister corev1listers.SecretNamespaceLister ImageVerifyCacheClient imageverifycache.Client
KyvernoClient kyvernoclient.UpstreamInterface RegistrySecretLister corev1listers.SecretNamespaceLister
DynamicClient dynamicclient.UpstreamInterface KyvernoClient kyvernoclient.UpstreamInterface
ApiServerClient apiserverclient.UpstreamInterface DynamicClient dynamicclient.UpstreamInterface
MetadataClient metadataclient.UpstreamInterface ApiServerClient apiserverclient.UpstreamInterface
KyvernoDynamicClient dclient.Interface MetadataClient metadataclient.UpstreamInterface
KyvernoDynamicClient dclient.Interface
} }
func Setup(config Configuration, name string, skipResourceFilters bool) (context.Context, SetupResult, context.CancelFunc) { func Setup(config Configuration, name string, skipResourceFilters bool) (context.Context, SetupResult, context.CancelFunc) {
@ -66,6 +68,10 @@ func Setup(config Configuration, name string, skipResourceFilters bool) (context
if config.UsesRegistryClient() { if config.UsesRegistryClient() {
registryClient, registrySecretLister = setupRegistryClient(ctx, logger, client) registryClient, registrySecretLister = setupRegistryClient(ctx, logger, client)
} }
var imageVerifyCache imageverifycache.Client
if config.UsesImageVerifyCache() {
imageVerifyCache = setupImageVerifyCache(ctx, logger)
}
var leaderElectionClient kubeclient.UpstreamInterface var leaderElectionClient kubeclient.UpstreamInterface
if config.UsesLeaderElection() { if config.UsesLeaderElection() {
leaderElectionClient = createKubernetesClient(logger, kubeclient.WithMetrics(metricsManager, metrics.KubeClient), kubeclient.WithTracing()) leaderElectionClient = createKubernetesClient(logger, kubeclient.WithMetrics(metricsManager, metrics.KubeClient), kubeclient.WithTracing())
@ -92,20 +98,21 @@ func Setup(config Configuration, name string, skipResourceFilters bool) (context
} }
return ctx, return ctx,
SetupResult{ SetupResult{
Logger: logger, Logger: logger,
Configuration: configuration, Configuration: configuration,
MetricsConfiguration: metricsConfiguration, MetricsConfiguration: metricsConfiguration,
MetricsManager: metricsManager, MetricsManager: metricsManager,
Jp: jmespath.New(configuration), Jp: jmespath.New(configuration),
KubeClient: client, KubeClient: client,
LeaderElectionClient: leaderElectionClient, LeaderElectionClient: leaderElectionClient,
RegistryClient: registryClient, RegistryClient: registryClient,
RegistrySecretLister: registrySecretLister, ImageVerifyCacheClient: imageVerifyCache,
KyvernoClient: kyvernoClient, RegistrySecretLister: registrySecretLister,
DynamicClient: dynamicClient, KyvernoClient: kyvernoClient,
ApiServerClient: apiServerClient, DynamicClient: dynamicClient,
MetadataClient: metadataClient, ApiServerClient: apiServerClient,
KyvernoDynamicClient: dClient, MetadataClient: metadataClient,
KyvernoDynamicClient: dClient,
}, },
shutdown(logger.WithName("shutdown"), sdownMaxProcs, sdownMetrics, sdownTracing, sdownSignals) shutdown(logger.WithName("shutdown"), sdownMaxProcs, sdownMetrics, sdownTracing, sdownSignals)
} }

View file

@ -216,6 +216,7 @@ func main() {
internal.WithDeferredLoading(), internal.WithDeferredLoading(),
internal.WithCosign(), internal.WithCosign(),
internal.WithRegistryClient(), internal.WithRegistryClient(),
internal.WithImageVerifyCache(),
internal.WithLeaderElection(), internal.WithLeaderElection(),
internal.WithKyvernoClient(), internal.WithKyvernoClient(),
internal.WithDynamicClient(), internal.WithDynamicClient(),
@ -309,6 +310,7 @@ func main() {
setup.Jp, setup.Jp,
setup.KyvernoDynamicClient, setup.KyvernoDynamicClient,
setup.RegistryClient, setup.RegistryClient,
setup.ImageVerifyCacheClient,
setup.KubeClient, setup.KubeClient,
setup.KyvernoClient, setup.KyvernoClient,
setup.RegistrySecretLister, setup.RegistrySecretLister,

View file

@ -198,6 +198,7 @@ func main() {
internal.WithDeferredLoading(), internal.WithDeferredLoading(),
internal.WithCosign(), internal.WithCosign(),
internal.WithRegistryClient(), internal.WithRegistryClient(),
internal.WithImageVerifyCache(),
internal.WithLeaderElection(), internal.WithLeaderElection(),
internal.WithKyvernoClient(), internal.WithKyvernoClient(),
internal.WithDynamicClient(), internal.WithDynamicClient(),
@ -241,6 +242,7 @@ func main() {
setup.Jp, setup.Jp,
setup.KyvernoDynamicClient, setup.KyvernoDynamicClient,
setup.RegistryClient, setup.RegistryClient,
setup.ImageVerifyCacheClient,
setup.KubeClient, setup.KubeClient,
setup.KyvernoClient, setup.KyvernoClient,
setup.RegistrySecretLister, setup.RegistrySecretLister,

View file

@ -3931,6 +3931,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have a description: VerifyDigest validates that images have a
@ -8034,6 +8039,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have description: VerifyDigest validates that images have
@ -11779,6 +11789,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have a description: VerifyDigest validates that images have a
@ -15882,6 +15897,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have description: VerifyDigest validates that images have

View file

@ -3932,6 +3932,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have a description: VerifyDigest validates that images have a
@ -8036,6 +8041,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have description: VerifyDigest validates that images have
@ -11782,6 +11792,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have a description: VerifyDigest validates that images have a
@ -15885,6 +15900,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have description: VerifyDigest validates that images have

View file

@ -7951,6 +7951,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have a description: VerifyDigest validates that images have a
@ -12054,6 +12059,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have description: VerifyDigest validates that images have
@ -15799,6 +15809,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have a description: VerifyDigest validates that images have a
@ -19902,6 +19917,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have description: VerifyDigest validates that images have
@ -23958,6 +23978,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have a description: VerifyDigest validates that images have a
@ -28062,6 +28087,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have description: VerifyDigest validates that images have
@ -31808,6 +31838,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have a description: VerifyDigest validates that images have a
@ -35911,6 +35946,11 @@ spec:
- Cosign - Cosign
- Notary - Notary
type: string type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest: verifyDigest:
default: true default: true
description: VerifyDigest validates that images have description: VerifyDigest validates that images have

View file

@ -2310,6 +2310,17 @@ ImageRegistryCredentials
<p>ImageRegistryCredentials provides credentials that will be used for authentication with registry</p> <p>ImageRegistryCredentials provides credentials that will be used for authentication with registry</p>
</td> </td>
</tr> </tr>
<tr>
<td>
<code>useCache</code><br/>
<em>
bool
</em>
</td>
<td>
<p>UseCache enables caching of image verify responses for this rule</p>
</td>
</tr>
</tbody> </tbody>
</table> </table>
<hr /> <hr />
@ -6718,6 +6729,17 @@ ImageRegistryCredentials
<p>ImageRegistryCredentials provides credentials that will be used for authentication with registry</p> <p>ImageRegistryCredentials provides credentials that will be used for authentication with registry</p>
</td> </td>
</tr> </tr>
<tr>
<td>
<code>useCache</code><br/>
<em>
bool
</em>
</td>
<td>
<p>UseCache enables caching of image verify responses for this rule</p>
</td>
</tr>
</tbody> </tbody>
</table> </table>
<hr /> <hr />

View file

@ -41,6 +41,7 @@ type ImageVerificationApplyConfiguration struct {
VerifyDigest *bool `json:"verifyDigest,omitempty"` VerifyDigest *bool `json:"verifyDigest,omitempty"`
Required *bool `json:"required,omitempty"` Required *bool `json:"required,omitempty"`
ImageRegistryCredentials *ImageRegistryCredentialsApplyConfiguration `json:"imageRegistryCredentials,omitempty"` ImageRegistryCredentials *ImageRegistryCredentialsApplyConfiguration `json:"imageRegistryCredentials,omitempty"`
UseCache *bool `json:"useCache,omitempty"`
} }
// ImageVerificationApplyConfiguration constructs an declarative configuration of the ImageVerification type for use with // ImageVerificationApplyConfiguration constructs an declarative configuration of the ImageVerification type for use with
@ -200,3 +201,11 @@ func (b *ImageVerificationApplyConfiguration) WithImageRegistryCredentials(value
b.ImageRegistryCredentials = value b.ImageRegistryCredentials = value
return b return b
} }
// WithUseCache sets the UseCache field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UseCache field is set to the value of the last call.
func (b *ImageVerificationApplyConfiguration) WithUseCache(value bool) *ImageVerificationApplyConfiguration {
b.UseCache = &value
return b
}

View file

@ -35,6 +35,7 @@ type ImageVerificationApplyConfiguration struct {
VerifyDigest *bool `json:"verifyDigest,omitempty"` VerifyDigest *bool `json:"verifyDigest,omitempty"`
Required *bool `json:"required,omitempty"` Required *bool `json:"required,omitempty"`
ImageRegistryCredentials *kyvernov1.ImageRegistryCredentialsApplyConfiguration `json:"imageRegistryCredentials,omitempty"` ImageRegistryCredentials *kyvernov1.ImageRegistryCredentialsApplyConfiguration `json:"imageRegistryCredentials,omitempty"`
UseCache *bool `json:"useCache,omitempty"`
} }
// ImageVerificationApplyConfiguration constructs an declarative configuration of the ImageVerification type for use with // ImageVerificationApplyConfiguration constructs an declarative configuration of the ImageVerification type for use with
@ -126,3 +127,11 @@ func (b *ImageVerificationApplyConfiguration) WithImageRegistryCredentials(value
b.ImageRegistryCredentials = value b.ImageRegistryCredentials = value
return b return b
} }
// WithUseCache sets the UseCache field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UseCache field is set to the value of the last call.
func (b *ImageVerificationApplyConfiguration) WithUseCache(value bool) *ImageVerificationApplyConfiguration {
b.UseCache = &value
return b
}

View file

@ -6,6 +6,7 @@ import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context" enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/jmespath" "github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/imageverifycache"
) )
type RegistryClientFactory interface { type RegistryClientFactory interface {
@ -24,6 +25,7 @@ type ContextLoader interface {
jp jmespath.Interface, jp jmespath.Interface,
client RawClient, client RawClient,
rclientFactory RegistryClientFactory, rclientFactory RegistryClientFactory,
ivCache imageverifycache.Client,
contextEntries []kyvernov1.ContextEntry, contextEntries []kyvernov1.ContextEntry,
jsonContext enginecontext.Interface, jsonContext enginecontext.Interface,
) error ) error

View file

@ -15,6 +15,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine/internal" "github.com/kyverno/kyverno/pkg/engine/internal"
"github.com/kyverno/kyverno/pkg/engine/jmespath" "github.com/kyverno/kyverno/pkg/engine/jmespath"
engineutils "github.com/kyverno/kyverno/pkg/engine/utils" engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/logging" "github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/tracing" "github.com/kyverno/kyverno/pkg/tracing"
@ -31,6 +32,7 @@ type engine struct {
jp jmespath.Interface jp jmespath.Interface
client engineapi.Client client engineapi.Client
rclientFactory engineapi.RegistryClientFactory rclientFactory engineapi.RegistryClientFactory
ivCache imageverifycache.Client
contextLoader engineapi.ContextLoaderFactory contextLoader engineapi.ContextLoaderFactory
exceptionSelector engineapi.PolicyExceptionSelector exceptionSelector engineapi.PolicyExceptionSelector
imageSignatureRepository string imageSignatureRepository string
@ -47,6 +49,7 @@ func NewEngine(
jp jmespath.Interface, jp jmespath.Interface,
client engineapi.Client, client engineapi.Client,
rclientFactory engineapi.RegistryClientFactory, rclientFactory engineapi.RegistryClientFactory,
ivCache imageverifycache.Client,
contextLoader engineapi.ContextLoaderFactory, contextLoader engineapi.ContextLoaderFactory,
exceptionSelector engineapi.PolicyExceptionSelector, exceptionSelector engineapi.PolicyExceptionSelector,
imageSignatureRepository string, imageSignatureRepository string,
@ -72,6 +75,7 @@ func NewEngine(
jp: jp, jp: jp,
client: client, client: client,
rclientFactory: rclientFactory, rclientFactory: rclientFactory,
ivCache: ivCache,
contextLoader: contextLoader, contextLoader: contextLoader,
exceptionSelector: exceptionSelector, exceptionSelector: exceptionSelector,
imageSignatureRepository: imageSignatureRepository, imageSignatureRepository: imageSignatureRepository,
@ -176,6 +180,7 @@ func (e *engine) ContextLoader(
e.jp, e.jp,
e.client, e.client,
e.rclientFactory, e.rclientFactory,
e.ivCache,
contextEntries, contextEntries,
jsonContext, jsonContext,
) )

View file

@ -10,6 +10,7 @@ import (
enginecontext "github.com/kyverno/kyverno/pkg/engine/context" enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/context/loaders" "github.com/kyverno/kyverno/pkg/engine/context/loaders"
"github.com/kyverno/kyverno/pkg/engine/jmespath" "github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/logging" "github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/toggle" "github.com/kyverno/kyverno/pkg/toggle"
) )
@ -46,6 +47,7 @@ func (l *contextLoader) Load(
jp jmespath.Interface, jp jmespath.Interface,
client engineapi.RawClient, client engineapi.RawClient,
rclientFactory engineapi.RegistryClientFactory, rclientFactory engineapi.RegistryClientFactory,
ivCache imageverifycache.Client,
contextEntries []kyvernov1.ContextEntry, contextEntries []kyvernov1.ContextEntry,
jsonContext enginecontext.Interface, jsonContext enginecontext.Interface,
) error { ) error {

View file

@ -14,6 +14,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine/mutate/patch" "github.com/kyverno/kyverno/pkg/engine/mutate/patch"
engineutils "github.com/kyverno/kyverno/pkg/engine/utils" engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/kyverno/kyverno/pkg/engine/variables" "github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/imageverifycache"
apiutils "github.com/kyverno/kyverno/pkg/utils/api" apiutils "github.com/kyverno/kyverno/pkg/utils/api"
jsonutils "github.com/kyverno/kyverno/pkg/utils/json" jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
"gomodules.xyz/jsonpatch/v2" "gomodules.xyz/jsonpatch/v2"
@ -23,6 +24,7 @@ import (
type mutateImageHandler struct { type mutateImageHandler struct {
configuration config.Configuration configuration config.Configuration
rclientFactory engineapi.RegistryClientFactory rclientFactory engineapi.RegistryClientFactory
ivCache imageverifycache.Client
ivm *engineapi.ImageVerificationMetadata ivm *engineapi.ImageVerificationMetadata
images []apiutils.ImageInfo images []apiutils.ImageInfo
imageSignatureRepository string imageSignatureRepository string
@ -34,6 +36,7 @@ func NewMutateImageHandler(
rule kyvernov1.Rule, rule kyvernov1.Rule,
configuration config.Configuration, configuration config.Configuration,
rclientFactory engineapi.RegistryClientFactory, rclientFactory engineapi.RegistryClientFactory,
ivCache imageverifycache.Client,
ivm *engineapi.ImageVerificationMetadata, ivm *engineapi.ImageVerificationMetadata,
imageSignatureRepository string, imageSignatureRepository string,
) (handlers.Handler, error) { ) (handlers.Handler, error) {
@ -80,7 +83,7 @@ func (h mutateImageHandler) Process(
engineapi.RuleError(rule.Name, engineapi.ImageVerify, "failed to fetch secrets", err), engineapi.RuleError(rule.Name, engineapi.ImageVerify, "failed to fetch secrets", err),
) )
} }
iv := internal.NewImageVerifier(logger, rclient, policyContext, *ruleCopy, h.ivm, h.imageSignatureRepository) iv := internal.NewImageVerifier(logger, rclient, h.ivCache, policyContext, *ruleCopy, h.ivm, h.imageSignatureRepository)
patch, ruleResponse := iv.Verify(ctx, imageVerify, h.images, h.configuration) patch, ruleResponse := iv.Verify(ctx, imageVerify, h.images, h.configuration)
patches = append(patches, patch...) patches = append(patches, patch...)
engineResponses = append(engineResponses, ruleResponse...) engineResponses = append(engineResponses, ruleResponse...)

View file

@ -41,6 +41,7 @@ func (e *engine) verifyAndPatchImages(
rule, rule,
e.configuration, e.configuration,
e.rclientFactory, e.rclientFactory,
e.ivCache,
&ivm, &ivm,
e.imageSignatureRepository, e.imageSignatureRepository,
) )

View file

@ -22,6 +22,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine/mutate/patch" "github.com/kyverno/kyverno/pkg/engine/mutate/patch"
"github.com/kyverno/kyverno/pkg/engine/policycontext" "github.com/kyverno/kyverno/pkg/engine/policycontext"
engineutils "github.com/kyverno/kyverno/pkg/engine/utils" engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/registryclient" "github.com/kyverno/kyverno/pkg/registryclient"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
"gomodules.xyz/jsonpatch/v2" "gomodules.xyz/jsonpatch/v2"
@ -185,6 +186,7 @@ func testVerifyAndPatchImages(
jp, jp,
nil, nil,
factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil), factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil),
imageverifycache.DisabledImageVerifyCache(),
factories.DefaultContextLoaderFactory(cmResolver), factories.DefaultContextLoaderFactory(cmResolver),
nil, nil,
"", "",

View file

@ -17,6 +17,7 @@ import (
enginecontext "github.com/kyverno/kyverno/pkg/engine/context" enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/variables" "github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/images" "github.com/kyverno/kyverno/pkg/images"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/notary" "github.com/kyverno/kyverno/pkg/notary"
apiutils "github.com/kyverno/kyverno/pkg/utils/api" apiutils "github.com/kyverno/kyverno/pkg/utils/api"
"github.com/kyverno/kyverno/pkg/utils/jsonpointer" "github.com/kyverno/kyverno/pkg/utils/jsonpointer"
@ -29,6 +30,7 @@ import (
type ImageVerifier struct { type ImageVerifier struct {
logger logr.Logger logger logr.Logger
rclient engineapi.RegistryClient rclient engineapi.RegistryClient
ivCache imageverifycache.Client
policyContext engineapi.PolicyContext policyContext engineapi.PolicyContext
rule kyvernov1.Rule rule kyvernov1.Rule
ivm *engineapi.ImageVerificationMetadata ivm *engineapi.ImageVerificationMetadata
@ -38,6 +40,7 @@ type ImageVerifier struct {
func NewImageVerifier( func NewImageVerifier(
logger logr.Logger, logger logr.Logger,
rclient engineapi.RegistryClient, rclient engineapi.RegistryClient,
ivCache imageverifycache.Client,
policyContext engineapi.PolicyContext, policyContext engineapi.PolicyContext,
rule kyvernov1.Rule, rule kyvernov1.Rule,
ivm *engineapi.ImageVerificationMetadata, ivm *engineapi.ImageVerificationMetadata,
@ -46,6 +49,7 @@ func NewImageVerifier(
return &ImageVerifier{ return &ImageVerifier{
logger: logger, logger: logger,
rclient: rclient, rclient: rclient,
ivCache: ivCache,
policyContext: policyContext, policyContext: policyContext,
rule: rule, rule: rule,
ivm: ivm, ivm: ivm,

View file

@ -13,6 +13,7 @@ import (
engineapi "github.com/kyverno/kyverno/pkg/engine/api" engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context" enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/factories" "github.com/kyverno/kyverno/pkg/engine/factories"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/registryclient" "github.com/kyverno/kyverno/pkg/registryclient"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -38,6 +39,7 @@ func testMutate(
jp, jp,
adapters.Client(client), adapters.Client(client),
factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil), factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil),
imageverifycache.DisabledImageVerifyCache(),
contextLoader, contextLoader,
nil, nil,
"", "",

View file

@ -14,6 +14,7 @@ import (
engineapi "github.com/kyverno/kyverno/pkg/engine/api" engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context" enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/factories" "github.com/kyverno/kyverno/pkg/engine/factories"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/registryclient" "github.com/kyverno/kyverno/pkg/registryclient"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission" admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
@ -38,6 +39,7 @@ func testValidate(
jp, jp,
nil, nil,
factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil), factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil),
imageverifycache.DisabledImageVerifyCache(),
contextLoader, contextLoader,
nil, nil,
"", "",

View file

@ -0,0 +1,93 @@
package imageverifycache
import (
"context"
"sync"
"time"
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
)
type cache struct {
logger logr.Logger
isCacheEnabled bool
maxSize int64
ttl time.Duration
lock sync.Mutex
}
type Option = func(*cache) error
func New(options ...Option) (Client, error) {
cache := &cache{}
for _, opt := range options {
if err := opt(cache); err != nil {
return nil, err
}
}
return cache, nil
}
func DisabledImageVerifyCache() Client {
return &cache{
logger: logr.Discard(),
isCacheEnabled: false,
maxSize: 0,
ttl: 0,
}
}
func WithLogger(l logr.Logger) Option {
return func(c *cache) error {
c.logger = l
return nil
}
}
func WithCacheEnableFlag(b bool) Option {
return func(c *cache) error {
c.isCacheEnabled = b
return nil
}
}
func WithMaxSize(s int64) Option {
return func(c *cache) error {
c.maxSize = s
return nil
}
}
func WithTTLDuration(t time.Duration) Option {
return func(c *cache) error {
c.ttl = t
return nil
}
}
func (c *cache) Set(ctx context.Context, policy kyvernov1.PolicyInterface, ruleName string, imageRef string) (bool, error) {
c.lock.Lock()
defer c.lock.Unlock()
c.logger.Info("Setting cache", "policy", policy.GetName(), "ruleName", ruleName, "imageRef", imageRef)
if !c.isCacheEnabled {
return false, nil
}
c.logger.Info("Successfully set cache", "policy", policy.GetName(), "ruleName", ruleName, "imageRef", imageRef)
return false, nil
}
func (c *cache) Get(ctx context.Context, policy kyvernov1.PolicyInterface, ruleName string, imageRef string) (bool, error) {
c.lock.Lock()
defer c.lock.Unlock()
c.logger.Info("Searching in cache", "policy", policy.GetName(), "ruleName", ruleName, "imageRef", imageRef)
if !c.isCacheEnabled {
return false, nil
}
c.logger.Info("Cache entry not found", "policy", policy.GetName(), "ruleName", ruleName, "imageRef", imageRef)
c.logger.Info("Cache entry found", "policy", policy.GetName(), "ruleName", ruleName, "imageRef", imageRef)
return false, nil
}

View file

@ -0,0 +1,18 @@
package imageverifycache
import (
"context"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
)
type Client interface {
// Set Adds an image to the cache. The image is considered to be verified for the given rule in the policy
// The entry outomatically expires after sometime
// Returns true when the cache entry is added
Set(ctx context.Context, policy kyvernov1.PolicyInterface, ruleName string, imageRef string) (bool, error)
// Get Searches for the image verified using the rule in the policy in the cache
// Returns true when the cache entry is found
Get(ctx context.Context, policy kyvernov1.PolicyInterface, ruleName string, imagerRef string) (bool, error)
}

View file

@ -13,6 +13,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine/factories" "github.com/kyverno/kyverno/pkg/engine/factories"
"github.com/kyverno/kyverno/pkg/engine/jmespath" "github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/event" "github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/openapi" "github.com/kyverno/kyverno/pkg/openapi"
"github.com/kyverno/kyverno/pkg/policycache" "github.com/kyverno/kyverno/pkg/policycache"
@ -60,6 +61,7 @@ func NewFakeHandlers(ctx context.Context, policyCache policycache.Cache) webhook
jp, jp,
adapters.Client(dclient), adapters.Client(dclient),
factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil), factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil),
imageverifycache.DisabledImageVerifyCache(),
factories.DefaultContextLoaderFactory(configMapResolver), factories.DefaultContextLoaderFactory(configMapResolver),
peLister, peLister,
"", "",

View file

@ -13,6 +13,7 @@ import (
engineapi "github.com/kyverno/kyverno/pkg/engine/api" engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/factories" "github.com/kyverno/kyverno/pkg/engine/factories"
"github.com/kyverno/kyverno/pkg/engine/jmespath" "github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/imageverifycache"
log "github.com/kyverno/kyverno/pkg/logging" log "github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/registryclient" "github.com/kyverno/kyverno/pkg/registryclient"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
@ -1060,6 +1061,7 @@ func TestValidate_failure_action_overrides(t *testing.T) {
jp, jp,
nil, nil,
factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil), factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil),
imageverifycache.DisabledImageVerifyCache(),
factories.DefaultContextLoaderFactory(nil), factories.DefaultContextLoaderFactory(nil),
nil, nil,
"", "",
@ -1162,6 +1164,7 @@ func Test_RuleSelector(t *testing.T) {
jp, jp,
nil, nil,
factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil), factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil),
imageverifycache.DisabledImageVerifyCache(),
factories.DefaultContextLoaderFactory(nil), factories.DefaultContextLoaderFactory(nil),
nil, nil,
"", "",