1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +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
// +kubebuilder:validation:Optional
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 {

View file

@ -54,6 +54,11 @@ type ImageVerification struct {
// ImageRegistryCredentials provides credentials that will be used for authentication with registry
// +kubebuilder:validation:Optional
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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,6 +8,7 @@ import (
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/factories"
"github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/imageverifycache"
)
func ContextLoaderFactory(cmResolver engineapi.ConfigmapResolver) engineapi.ContextLoaderFactory {
@ -48,6 +49,7 @@ func (w wrapper) Load(
jp jmespath.Interface,
client engineapi.RawClient,
rclientFactory engineapi.RegistryClientFactory,
ivCache imageverifycache.Client,
contextEntries []kyvernov1.ContextEntry,
jsonContext enginecontext.Interface,
) error {
@ -57,5 +59,5 @@ func (w wrapper) Load(
if !GetRegistryAccess() {
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
UsesCosign() bool
UsesRegistryClient() bool
UsesImageVerifyCache() bool
UsesLeaderElection() bool
UsesKyvernoClient() bool
UsesDynamicClient() bool
@ -87,6 +88,12 @@ func WithRegistryClient() ConfigurationOption {
}
}
func WithImageVerifyCache() ConfigurationOption {
return func(c *configuration) {
c.usesImageVerifyCache = true
}
}
func WithLeaderElection() ConfigurationOption {
return func(c *configuration) {
c.usesLeaderElection = true
@ -141,6 +148,7 @@ type configuration struct {
usesDeferredLoading bool
usesCosign bool
usesRegistryClient bool
usesImageVerifyCache bool
usesLeaderElection bool
usesKyvernoClient bool
usesDynamicClient bool
@ -186,6 +194,10 @@ func (c *configuration) UsesRegistryClient() bool {
return c.usesRegistryClient
}
func (c *configuration) UsesImageVerifyCache() bool {
return c.usesImageVerifyCache
}
func (c *configuration) UsesLeaderElection() bool {
return c.usesLeaderElection
}

View file

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

View file

@ -44,6 +44,10 @@ var (
registryCredentialHelpers string
// leader election
leaderElectionRetryPeriod time.Duration
// image verify cache
imageVerifyCacheEnabled bool
imageVerifyCacheTTLDuration int64
imageVerifyCacheMaxSize int64
)
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.")
}
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() {
flag.DurationVar(&leaderElectionRetryPeriod, "leaderElectionRetryPeriod", leaderelection.DefaultRetryPeriod, "Configure leader election retry period.")
}
@ -177,6 +187,10 @@ func initFlags(config Configuration, opts ...Option) {
if config.UsesRegistryClient() {
initRegistryClientFlags()
}
// image verify cache
if config.UsesImageVerifyCache() {
initImageVerifyCacheFlags()
}
// leader election
if config.UsesLeaderElection() {
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"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/registryclient"
corev1listers "k8s.io/client-go/listers/core/v1"
@ -38,6 +39,7 @@ type SetupResult struct {
KubeClient kubeclient.UpstreamInterface
LeaderElectionClient kubeclient.UpstreamInterface
RegistryClient registryclient.Client
ImageVerifyCacheClient imageverifycache.Client
RegistrySecretLister corev1listers.SecretNamespaceLister
KyvernoClient kyvernoclient.UpstreamInterface
DynamicClient dynamicclient.UpstreamInterface
@ -66,6 +68,10 @@ func Setup(config Configuration, name string, skipResourceFilters bool) (context
if config.UsesRegistryClient() {
registryClient, registrySecretLister = setupRegistryClient(ctx, logger, client)
}
var imageVerifyCache imageverifycache.Client
if config.UsesImageVerifyCache() {
imageVerifyCache = setupImageVerifyCache(ctx, logger)
}
var leaderElectionClient kubeclient.UpstreamInterface
if config.UsesLeaderElection() {
leaderElectionClient = createKubernetesClient(logger, kubeclient.WithMetrics(metricsManager, metrics.KubeClient), kubeclient.WithTracing())
@ -100,6 +106,7 @@ func Setup(config Configuration, name string, skipResourceFilters bool) (context
KubeClient: client,
LeaderElectionClient: leaderElectionClient,
RegistryClient: registryClient,
ImageVerifyCacheClient: imageVerifyCache,
RegistrySecretLister: registrySecretLister,
KyvernoClient: kyvernoClient,
DynamicClient: dynamicClient,

View file

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

View file

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

View file

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

View file

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

View file

@ -7951,6 +7951,11 @@ spec:
- Cosign
- Notary
type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -12054,6 +12059,11 @@ spec:
- Cosign
- Notary
type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest:
default: true
description: VerifyDigest validates that images have
@ -15799,6 +15809,11 @@ spec:
- Cosign
- Notary
type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -19902,6 +19917,11 @@ spec:
- Cosign
- Notary
type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest:
default: true
description: VerifyDigest validates that images have
@ -23958,6 +23978,11 @@ spec:
- Cosign
- Notary
type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -28062,6 +28087,11 @@ spec:
- Cosign
- Notary
type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest:
default: true
description: VerifyDigest validates that images have
@ -31808,6 +31838,11 @@ spec:
- Cosign
- Notary
type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest:
default: true
description: VerifyDigest validates that images have a
@ -35911,6 +35946,11 @@ spec:
- Cosign
- Notary
type: string
useCache:
default: true
description: UseCache enables caching of image verify
responses for this rule
type: boolean
verifyDigest:
default: true
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>
</td>
</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>
</table>
<hr />
@ -6718,6 +6729,17 @@ ImageRegistryCredentials
<p>ImageRegistryCredentials provides credentials that will be used for authentication with registry</p>
</td>
</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>
</table>
<hr />

View file

@ -41,6 +41,7 @@ type ImageVerificationApplyConfiguration struct {
VerifyDigest *bool `json:"verifyDigest,omitempty"`
Required *bool `json:"required,omitempty"`
ImageRegistryCredentials *ImageRegistryCredentialsApplyConfiguration `json:"imageRegistryCredentials,omitempty"`
UseCache *bool `json:"useCache,omitempty"`
}
// ImageVerificationApplyConfiguration constructs an declarative configuration of the ImageVerification type for use with
@ -200,3 +201,11 @@ func (b *ImageVerificationApplyConfiguration) WithImageRegistryCredentials(value
b.ImageRegistryCredentials = value
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"`
Required *bool `json:"required,omitempty"`
ImageRegistryCredentials *kyvernov1.ImageRegistryCredentialsApplyConfiguration `json:"imageRegistryCredentials,omitempty"`
UseCache *bool `json:"useCache,omitempty"`
}
// ImageVerificationApplyConfiguration constructs an declarative configuration of the ImageVerification type for use with
@ -126,3 +127,11 @@ func (b *ImageVerificationApplyConfiguration) WithImageRegistryCredentials(value
b.ImageRegistryCredentials = value
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"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/imageverifycache"
)
type RegistryClientFactory interface {
@ -24,6 +25,7 @@ type ContextLoader interface {
jp jmespath.Interface,
client RawClient,
rclientFactory RegistryClientFactory,
ivCache imageverifycache.Client,
contextEntries []kyvernov1.ContextEntry,
jsonContext enginecontext.Interface,
) error

View file

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

View file

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

View file

@ -14,6 +14,7 @@ import (
"github.com/kyverno/kyverno/pkg/engine/mutate/patch"
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/imageverifycache"
apiutils "github.com/kyverno/kyverno/pkg/utils/api"
jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
"gomodules.xyz/jsonpatch/v2"
@ -23,6 +24,7 @@ import (
type mutateImageHandler struct {
configuration config.Configuration
rclientFactory engineapi.RegistryClientFactory
ivCache imageverifycache.Client
ivm *engineapi.ImageVerificationMetadata
images []apiutils.ImageInfo
imageSignatureRepository string
@ -34,6 +36,7 @@ func NewMutateImageHandler(
rule kyvernov1.Rule,
configuration config.Configuration,
rclientFactory engineapi.RegistryClientFactory,
ivCache imageverifycache.Client,
ivm *engineapi.ImageVerificationMetadata,
imageSignatureRepository string,
) (handlers.Handler, error) {
@ -80,7 +83,7 @@ func (h mutateImageHandler) Process(
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)
patches = append(patches, patch...)
engineResponses = append(engineResponses, ruleResponse...)

View file

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

View file

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

View file

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

View file

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

View file

@ -14,6 +14,7 @@ import (
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/factories"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/registryclient"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
@ -38,6 +39,7 @@ func testValidate(
jp,
nil,
factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil),
imageverifycache.DisabledImageVerifyCache(),
contextLoader,
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/jmespath"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/imageverifycache"
"github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/openapi"
"github.com/kyverno/kyverno/pkg/policycache"
@ -60,6 +61,7 @@ func NewFakeHandlers(ctx context.Context, policyCache policycache.Cache) webhook
jp,
adapters.Client(dclient),
factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), nil),
imageverifycache.DisabledImageVerifyCache(),
factories.DefaultContextLoaderFactory(configMapResolver),
peLister,
"",

View file

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