1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

fix: properly use useCache field in image verification policies (#10709)

* fix: properly use useCache field in image verification policies

Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com>

* fix: add test

Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com>

* fix: revert client changes

Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com>

---------

Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com>
Co-authored-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
This commit is contained in:
Vishal Choudhary 2024-08-19 19:56:07 +05:30 committed by GitHub
parent 4d5d487e1d
commit 0c2a88638b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 42 additions and 7 deletions

View file

@ -212,6 +212,7 @@ var cosignTestPolicy = `{
"imageReferences": [ "imageReferences": [
"ghcr.io/kyverno/test-verify-image:*" "ghcr.io/kyverno/test-verify-image:*"
], ],
"useCache": true,
"attestors": [ "attestors": [
{ {
"entries": [ "entries": [
@ -266,6 +267,7 @@ var cosignTestPolicyUpdated = `{
"imageReferences": [ "imageReferences": [
"ghcr.io/kyverno/test-verify-image:*" "ghcr.io/kyverno/test-verify-image:*"
], ],
"useCache": true,
"attestors": [ "attestors": [
{ {
"entries": [ "entries": [
@ -837,7 +839,6 @@ var testNestedAttestorPolicy = `
` `
func Test_NestedAttestors(t *testing.T) { func Test_NestedAttestors(t *testing.T) {
policy := strings.Replace(testNestedAttestorPolicy, "KEY1", testVerifyImageKey, -1) policy := strings.Replace(testNestedAttestorPolicy, "KEY1", testVerifyImageKey, -1)
policy = strings.Replace(policy, "KEY2", testVerifyImageKey, -1) policy = strings.Replace(policy, "KEY2", testVerifyImageKey, -1)
policy = strings.Replace(policy, "COUNT", "0", -1) policy = strings.Replace(policy, "COUNT", "0", -1)
@ -1112,6 +1113,30 @@ func Test_ImageVerifyCacheCosign(t *testing.T) {
assert.Check(t, secondOperationTime < firstOperationTime/10, "cache entry is valid, so image verification should be from cache.", firstOperationTime, secondOperationTime) assert.Check(t, secondOperationTime < firstOperationTime/10, "cache entry is valid, so image verification should be from cache.", firstOperationTime, secondOperationTime)
} }
func Test_ImageVerifyCacheDisabled(t *testing.T) {
opts := []imageverifycache.Option{
imageverifycache.WithCacheEnableFlag(false),
imageverifycache.WithMaxSize(1000),
imageverifycache.WithTTLDuration(24 * time.Hour),
}
imageVerifyCache, err := imageverifycache.New(opts...)
assert.NilError(t, err)
image := "ghcr.io/kyverno/test-verify-image:signed"
policyContext := buildContext(t, cosignTestPolicy, cosignTestResource, "")
start := time.Now()
er, ivm := testImageVerifyCache(imageVerifyCache, context.TODO(), registryclient.NewOrDie(), nil, policyContext, cfg)
firstOperationTime := time.Since(start)
errorAssertionUtil(t, image, ivm, er)
start = time.Now()
er, ivm = testImageVerifyCache(imageVerifyCache, context.TODO(), registryclient.NewOrDie(), nil, policyContext, cfg)
secondOperationTime := time.Since(start)
errorAssertionUtil(t, image, ivm, er)
assert.Check(t, secondOperationTime > firstOperationTime/10 && secondOperationTime < firstOperationTime*10, "cache is disabled, so image verification should not be from cache.", firstOperationTime, secondOperationTime)
}
func Test_ImageVerifyCacheExpiredCosign(t *testing.T) { func Test_ImageVerifyCacheExpiredCosign(t *testing.T) {
opts := []imageverifycache.Option{ opts := []imageverifycache.Option{
imageverifycache.WithCacheEnableFlag(true), imageverifycache.WithCacheEnableFlag(true),
@ -1193,6 +1218,7 @@ var verifyImageNotaryPolicy = `{
"imageReferences": [ "imageReferences": [
"ghcr.io/kyverno/test-verify-image*" "ghcr.io/kyverno/test-verify-image*"
], ],
"useCache": true,
"attestors": [ "attestors": [
{ {
"count": 1, "count": 1,
@ -1242,6 +1268,7 @@ var verifyImageNotaryUpdatedPolicy = `{
"imageReferences": [ "imageReferences": [
"ghcr.io/kyverno/test-verify-image*" "ghcr.io/kyverno/test-verify-image*"
], ],
"useCache": true,
"attestors": [ "attestors": [
{ {
"count": 1, "count": 1,

View file

@ -261,7 +261,7 @@ func (iv *ImageVerifier) Verify(
start := time.Now() start := time.Now()
isInCache := false isInCache := false
if iv.ivCache != nil { if iv.ivCache != nil {
found, err := iv.ivCache.Get(ctx, iv.policyContext.Policy(), iv.rule.Name, image) found, err := iv.ivCache.Get(ctx, iv.policyContext.Policy(), iv.rule.Name, image, imageVerify.UseCache)
if err != nil { if err != nil {
iv.logger.Error(err, "error occurred during cache get") iv.logger.Error(err, "error occurred during cache get")
} else { } else {
@ -280,7 +280,7 @@ func (iv *ImageVerifier) Verify(
ruleResp, digest = iv.verifyImage(ctx, imageVerify, imageInfo, cfg) ruleResp, digest = iv.verifyImage(ctx, imageVerify, imageInfo, cfg)
if ruleResp != nil && ruleResp.Status() == engineapi.RuleStatusPass { if ruleResp != nil && ruleResp.Status() == engineapi.RuleStatusPass {
if iv.ivCache != nil { if iv.ivCache != nil {
setted, err := iv.ivCache.Set(ctx, iv.policyContext.Policy(), iv.rule.Name, image) setted, err := iv.ivCache.Set(ctx, iv.policyContext.Policy(), iv.rule.Name, image, imageVerify.UseCache)
if err != nil { if err != nil {
iv.logger.Error(err, "error occurred during cache set") iv.logger.Error(err, "error occurred during cache set")
} else { } else {

View file

@ -91,8 +91,12 @@ func generateKey(policy kyvernov1.PolicyInterface, ruleName string, imageRef str
return string(policy.GetUID()) + ";" + policy.GetResourceVersion() + ";" + ruleName + ";" + imageRef return string(policy.GetUID()) + ";" + policy.GetResourceVersion() + ";" + ruleName + ";" + imageRef
} }
func (c *cache) Set(ctx context.Context, policy kyvernov1.PolicyInterface, ruleName string, imageRef string) (bool, error) { func (c *cache) Set(ctx context.Context, policy kyvernov1.PolicyInterface, ruleName string, imageRef string, useCache bool) (bool, error) {
if !c.isCacheEnabled { if !c.isCacheEnabled {
// If cache is globally disabled just return
return false, nil
} else if !useCache {
// Else If enabled globally then return if locally disabled
return false, nil return false, nil
} }
key := generateKey(policy, ruleName, imageRef) key := generateKey(policy, ruleName, imageRef)
@ -105,8 +109,12 @@ func (c *cache) Set(ctx context.Context, policy kyvernov1.PolicyInterface, ruleN
return false, nil return false, nil
} }
func (c *cache) Get(ctx context.Context, policy kyvernov1.PolicyInterface, ruleName string, imageRef string) (bool, error) { func (c *cache) Get(ctx context.Context, policy kyvernov1.PolicyInterface, ruleName string, imageRef string, useCache bool) (bool, error) {
if !c.isCacheEnabled { if !c.isCacheEnabled {
// If cache is globally disabled just return
return false, nil
} else if !useCache {
// Else If enabled globally then return if locally disabled
return false, nil return false, nil
} }
key := generateKey(policy, ruleName, imageRef) key := generateKey(policy, ruleName, imageRef)

View file

@ -10,9 +10,9 @@ type Client interface {
// Set Adds an image to the cache. The image is considered to be verified for the given rule in the policy // 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 // The entry outomatically expires after sometime
// Returns true when the cache entry is added // Returns true when the cache entry is added
Set(ctx context.Context, policy kyvernov1.PolicyInterface, ruleName string, imageRef string) (bool, error) Set(ctx context.Context, policy kyvernov1.PolicyInterface, ruleName string, imageRef string, useCache bool) (bool, error)
// Get Searches for the image verified using the rule in the policy in the cache // Get Searches for the image verified using the rule in the policy in the cache
// Returns true when the cache entry is found // Returns true when the cache entry is found
Get(ctx context.Context, policy kyvernov1.PolicyInterface, ruleName string, imagerRef string) (bool, error) Get(ctx context.Context, policy kyvernov1.PolicyInterface, ruleName string, imagerRef string, useCache bool) (bool, error)
} }