diff --git a/api/kyverno/constants.go b/api/kyverno/constants.go index 2403e973c3..7e0d9cfa7f 100644 --- a/api/kyverno/constants.go +++ b/api/kyverno/constants.go @@ -9,6 +9,7 @@ const ( LabelWebhookManagedBy = "webhook.kyverno.io/managed-by" // Well known annotations AnnotationAutogenControllers = "pod-policies.kyverno.io/autogen-controllers" + AnnotationImageVerify = "kyverno.io/verify-images" AnnotationPolicyCategory = "policies.kyverno.io/category" AnnotationPolicySeverity = "policies.kyverno.io/severity" AnnotationPolicyScored = "policies.kyverno.io/scored" diff --git a/pkg/controllers/report/utils/scanner.go b/pkg/controllers/report/utils/scanner.go index 6a7bb233b8..9c2c8cacb0 100644 --- a/pkg/controllers/report/utils/scanner.go +++ b/pkg/controllers/report/utils/scanner.go @@ -4,6 +4,7 @@ import ( "context" "github.com/go-logr/logr" + "github.com/kyverno/kyverno/api/kyverno" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/engine" @@ -88,7 +89,7 @@ func (s *scanner) validateImages(ctx context.Context, resource unstructured.Unst annotations := resource.GetAnnotations() if annotations != nil { resource = *resource.DeepCopy() - delete(annotations, "kyverno.io/verify-images") + delete(annotations, kyverno.AnnotationImageVerify) resource.SetAnnotations(annotations) } policyCtx, err := engine.NewPolicyContext(s.jp, resource, kyvernov1.Create, nil, s.config) diff --git a/pkg/engine/api/imageverifymetadata.go b/pkg/engine/api/imageverifymetadata.go index 9f257a4c67..e8b5691d6c 100644 --- a/pkg/engine/api/imageverifymetadata.go +++ b/pkg/engine/api/imageverifymetadata.go @@ -6,11 +6,10 @@ import ( "strings" "github.com/go-logr/logr" + "github.com/kyverno/kyverno/api/kyverno" "gomodules.xyz/jsonpatch/v2" ) -const ImageVerifyAnnotationKey = "kyverno.io/verify-images" - type ImageVerificationMetadata struct { Data map[string]bool `json:"data"` } @@ -79,5 +78,5 @@ func (ivm *ImageVerificationMetadata) IsEmpty() bool { } func makeAnnotationKeyForJSONPatch() string { - return "/metadata/annotations/" + strings.ReplaceAll(ImageVerifyAnnotationKey, "/", "~1") + return "/metadata/annotations/" + strings.ReplaceAll(kyverno.AnnotationImageVerify, "/", "~1") } diff --git a/pkg/engine/image_verify_test.go b/pkg/engine/image_verify_test.go index ace38f4705..0b6ea61437 100644 --- a/pkg/engine/image_verify_test.go +++ b/pkg/engine/image_verify_test.go @@ -8,7 +8,8 @@ import ( "testing" "github.com/go-logr/logr" - kyverno "github.com/kyverno/kyverno/api/kyverno/v1" + "github.com/kyverno/kyverno/api/kyverno" + kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/cosign" "github.com/kyverno/kyverno/pkg/engine/adapters" @@ -219,7 +220,7 @@ func Test_CosignMockAttest_fail(t *testing.T) { } func buildContext(t *testing.T, policy, resource string, oldResource string) *PolicyContext { - var cpol kyverno.ClusterPolicy + var cpol kyvernov1.ClusterPolicy err := json.Unmarshal([]byte(policy), &cpol) assert.NilError(t, err) @@ -229,7 +230,7 @@ func buildContext(t *testing.T, policy, resource string, oldResource string) *Po policyContext, err := policycontext.NewPolicyContext( jp, *resourceUnstructured, - kyverno.Create, + kyvernov1.Create, nil, cfg, ) @@ -560,7 +561,7 @@ func Test_RuleSelectorImageVerify(t *testing.T) { spec := policyContext.Policy().GetSpec() spec.Rules = append(spec.Rules, *rule) - applyAll := kyverno.ApplyAll + applyAll := kyvernov1.ApplyAll spec.ApplyRules = &applyAll resp, _ := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), nil, policyContext, cfg) @@ -568,33 +569,33 @@ func Test_RuleSelectorImageVerify(t *testing.T) { assert.Equal(t, resp.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass, resp.PolicyResponse.Rules[0].Message()) assert.Equal(t, resp.PolicyResponse.Rules[1].Status(), engineapi.RuleStatusFail, resp.PolicyResponse.Rules[1].Message()) - applyOne := kyverno.ApplyOne + applyOne := kyvernov1.ApplyOne spec.ApplyRules = &applyOne resp, _ = testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), nil, policyContext, cfg) assert.Equal(t, len(resp.PolicyResponse.Rules), 1) assert.Equal(t, resp.PolicyResponse.Rules[0].Status(), engineapi.RuleStatusPass, resp.PolicyResponse.Rules[0].Message()) } -func newStaticKeyRule(name, imageReference, key string) *kyverno.Rule { - return &kyverno.Rule{ +func newStaticKeyRule(name, imageReference, key string) *kyvernov1.Rule { + return &kyvernov1.Rule{ Name: name, - MatchResources: kyverno.MatchResources{ - All: kyverno.ResourceFilters{ + MatchResources: kyvernov1.MatchResources{ + All: kyvernov1.ResourceFilters{ { - ResourceDescription: kyverno.ResourceDescription{ + ResourceDescription: kyvernov1.ResourceDescription{ Kinds: []string{"Pod"}, }, }, }, }, - VerifyImages: []kyverno.ImageVerification{ + VerifyImages: []kyvernov1.ImageVerification{ { ImageReferences: []string{"*"}, - Attestors: []kyverno.AttestorSet{ + Attestors: []kyvernov1.AttestorSet{ { - Entries: []kyverno.Attestor{ + Entries: []kyvernov1.Attestor{ { - Keys: &kyverno.StaticKeyAttestor{ + Keys: &kyvernov1.StaticKeyAttestor{ PublicKeys: key, }, }, @@ -707,7 +708,7 @@ func Test_ExpandKeys(t *testing.T) { as = internal.ExpandStaticKeys(createStaticKeyAttestorSet("", false, true, false)) assert.Equal(t, 1, len(as.Entries)) - assert.DeepEqual(t, &kyverno.SecretReference{Name: "testsecret", Namespace: "default"}, + assert.DeepEqual(t, &kyvernov1.SecretReference{Name: "testsecret", Namespace: "default"}, as.Entries[0].Keys.Secret) as = internal.ExpandStaticKeys(createStaticKeyAttestorSet("", false, false, true)) @@ -717,23 +718,23 @@ func Test_ExpandKeys(t *testing.T) { as = internal.ExpandStaticKeys((createStaticKeyAttestorSet(testOtherKey, true, true, false))) assert.Equal(t, 2, len(as.Entries)) assert.DeepEqual(t, testOtherKey, as.Entries[0].Keys.PublicKeys) - assert.DeepEqual(t, &kyverno.SecretReference{Name: "testsecret", Namespace: "default"}, as.Entries[1].Keys.Secret) + assert.DeepEqual(t, &kyvernov1.SecretReference{Name: "testsecret", Namespace: "default"}, as.Entries[1].Keys.Secret) } -func createStaticKeyAttestorSet(s string, withPublicKey, withSecret, withKMS bool) kyverno.AttestorSet { - var entries []kyverno.Attestor +func createStaticKeyAttestorSet(s string, withPublicKey, withSecret, withKMS bool) kyvernov1.AttestorSet { + var entries []kyvernov1.Attestor if withPublicKey { - attestor := kyverno.Attestor{ - Keys: &kyverno.StaticKeyAttestor{ + attestor := kyvernov1.Attestor{ + Keys: &kyvernov1.StaticKeyAttestor{ PublicKeys: s, }, } entries = append(entries, attestor) } if withSecret { - attestor := kyverno.Attestor{ - Keys: &kyverno.StaticKeyAttestor{ - Secret: &kyverno.SecretReference{ + attestor := kyvernov1.Attestor{ + Keys: &kyvernov1.StaticKeyAttestor{ + Secret: &kyvernov1.SecretReference{ Name: "testsecret", Namespace: "default", }, @@ -743,18 +744,18 @@ func createStaticKeyAttestorSet(s string, withPublicKey, withSecret, withKMS boo } if withKMS { kmsKey := "gcpkms://projects/test_project_id/locations/asia-south1/keyRings/test_key_ring_name/cryptoKeys/test_key_name/versions/1" - attestor := kyverno.Attestor{ - Keys: &kyverno.StaticKeyAttestor{ + attestor := kyvernov1.Attestor{ + Keys: &kyvernov1.StaticKeyAttestor{ KMS: kmsKey, }, } entries = append(entries, attestor) } - return kyverno.AttestorSet{Entries: entries} + return kyvernov1.AttestorSet{Entries: entries} } func Test_ChangedAnnotation(t *testing.T) { - annotationKey := engineapi.ImageVerifyAnnotationKey + annotationKey := kyverno.AnnotationImageVerify annotationNew := fmt.Sprintf("\"annotations\": {\"%s\": \"%s\"}", annotationKey, "true") newResource := strings.ReplaceAll(testResource, "\"annotations\": {}", annotationNew) @@ -798,7 +799,7 @@ func Test_MarkImageVerified(t *testing.T) { patchedAnnotations := resource.GetAnnotations() assert.Equal(t, len(patchedAnnotations), 1) - json := patchedAnnotations[engineapi.ImageVerifyAnnotationKey] + json := patchedAnnotations[kyverno.AnnotationImageVerify] assert.Assert(t, json != "") verified, err := engineutils.IsImageVerified(resource, image, logr.Discard()) diff --git a/pkg/engine/internal/imageverifier.go b/pkg/engine/internal/imageverifier.go index 086d65810f..47199da541 100644 --- a/pkg/engine/internal/imageverifier.go +++ b/pkg/engine/internal/imageverifier.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/go-logr/logr" + "github.com/kyverno/kyverno/api/kyverno" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/cosign" @@ -58,8 +59,8 @@ func HasImageVerifiedAnnotationChanged(ctx engineapi.PolicyContext, log logr.Log if newResource.Object == nil || oldResource.Object == nil { return false } - newValue := newResource.GetAnnotations()[engineapi.ImageVerifyAnnotationKey] - oldValue := oldResource.GetAnnotations()[engineapi.ImageVerifyAnnotationKey] + newValue := newResource.GetAnnotations()[kyverno.AnnotationImageVerify] + oldValue := oldResource.GetAnnotations()[kyverno.AnnotationImageVerify] if newValue == oldValue { return false } @@ -79,7 +80,7 @@ func HasImageVerifiedAnnotationChanged(ctx engineapi.PolicyContext, log logr.Log if found { result := newValueObj[img] != oldValueObj[img] if result { - log.V(2).Info("annotation mismatch", "oldValue", oldValue, "newValue", newValue, "key", engineapi.ImageVerifyAnnotationKey) + log.V(2).Info("annotation mismatch", "oldValue", oldValue, "newValue", newValue, "key", kyverno.AnnotationImageVerify) return result } } @@ -104,9 +105,9 @@ func isImageVerified(resource unstructured.Unstructured, image string, log logr. if len(annotations) == 0 { return false, nil } - data, ok := annotations[engineapi.ImageVerifyAnnotationKey] + data, ok := annotations[kyverno.AnnotationImageVerify] if !ok { - log.V(2).Info("missing image metadata in annotation", "key", engineapi.ImageVerifyAnnotationKey) + log.V(2).Info("missing image metadata in annotation", "key", kyverno.AnnotationImageVerify) return false, fmt.Errorf("image is not verified") } ivm, err := engineapi.ParseImageMetadata(data) @@ -218,7 +219,7 @@ func (iv *ImageVerifier) Verify( image := imageInfo.String() if HasImageVerifiedAnnotationChanged(iv.policyContext, iv.logger) { - msg := engineapi.ImageVerifyAnnotationKey + " annotation cannot be changed" + msg := kyverno.AnnotationImageVerify + " annotation cannot be changed" iv.logger.Info("image verification error", "reason", msg) responses = append(responses, engineapi.RuleFail(iv.rule.Name, engineapi.ImageVerify, msg)) continue diff --git a/pkg/engine/utils/image.go b/pkg/engine/utils/image.go index 50964fed8b..7652b82525 100644 --- a/pkg/engine/utils/image.go +++ b/pkg/engine/utils/image.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/go-logr/logr" + "github.com/kyverno/kyverno/api/kyverno" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/config" engineapi "github.com/kyverno/kyverno/pkg/engine/api" @@ -71,8 +72,8 @@ func IsImageVerified(resource unstructured.Unstructured, image string, log logr. } if annotations := resource.GetAnnotations(); len(annotations) == 0 { return false, nil - } else if data, ok := annotations[engineapi.ImageVerifyAnnotationKey]; !ok { - log.V(2).Info("missing image metadata in annotation", "key", engineapi.ImageVerifyAnnotationKey) + } else if data, ok := annotations[kyverno.AnnotationImageVerify]; !ok { + log.V(2).Info("missing image metadata in annotation", "key", kyverno.AnnotationImageVerify) return false, fmt.Errorf("image is not verified") } else if ivm, err := engineapi.ParseImageMetadata(data); err != nil { log.Error(err, "failed to parse image verification metadata", "data", data)