2023-02-02 10:58:34 +00:00
|
|
|
package api
|
2022-05-05 21:06:18 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2023-02-01 06:38:04 +00:00
|
|
|
"fmt"
|
2022-05-05 21:06:18 +00:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/go-logr/logr"
|
2023-08-02 14:02:21 +00:00
|
|
|
"github.com/kyverno/kyverno/api/kyverno"
|
2023-06-08 10:23:20 +00:00
|
|
|
"gomodules.xyz/jsonpatch/v2"
|
2022-05-05 21:06:18 +00:00
|
|
|
)
|
|
|
|
|
2024-01-23 12:27:39 +00:00
|
|
|
type ImageVerificationMetadataStatus string
|
|
|
|
|
|
|
|
const (
|
|
|
|
ImageVerificationPass ImageVerificationMetadataStatus = "pass"
|
|
|
|
ImageVerificationFail ImageVerificationMetadataStatus = "fail"
|
|
|
|
ImageVerificationSkip ImageVerificationMetadataStatus = "skip"
|
|
|
|
)
|
|
|
|
|
2022-05-05 21:06:18 +00:00
|
|
|
type ImageVerificationMetadata struct {
|
2024-01-23 12:27:39 +00:00
|
|
|
Data map[string]ImageVerificationMetadataStatus `json:"data"`
|
2022-05-05 21:06:18 +00:00
|
|
|
}
|
|
|
|
|
2024-01-23 12:27:39 +00:00
|
|
|
func (ivm *ImageVerificationMetadata) Add(image string, verified ImageVerificationMetadataStatus) {
|
2022-05-05 21:06:18 +00:00
|
|
|
if ivm.Data == nil {
|
2024-01-23 12:27:39 +00:00
|
|
|
ivm.Data = make(map[string]ImageVerificationMetadataStatus)
|
2022-05-05 21:06:18 +00:00
|
|
|
}
|
|
|
|
ivm.Data[image] = verified
|
|
|
|
}
|
|
|
|
|
2023-02-02 10:58:34 +00:00
|
|
|
func (ivm *ImageVerificationMetadata) IsVerified(image string) bool {
|
2022-05-05 21:06:18 +00:00
|
|
|
if ivm.Data == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
verified, ok := ivm.Data[image]
|
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
2024-01-23 12:27:39 +00:00
|
|
|
return verified == ImageVerificationPass || verified == ImageVerificationSkip
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ivm *ImageVerificationMetadata) ImageVerificationStatus(image string) ImageVerificationMetadataStatus {
|
|
|
|
if ivm.Data == nil {
|
|
|
|
return ImageVerificationFail
|
|
|
|
}
|
|
|
|
verified, ok := ivm.Data[image]
|
|
|
|
if !ok {
|
|
|
|
return ImageVerificationFail
|
|
|
|
}
|
2022-05-05 21:06:18 +00:00
|
|
|
return verified
|
|
|
|
}
|
|
|
|
|
2023-02-02 10:58:34 +00:00
|
|
|
func ParseImageMetadata(jsonData string) (*ImageVerificationMetadata, error) {
|
2024-01-23 12:27:39 +00:00
|
|
|
var data map[string]ImageVerificationMetadataStatus
|
2022-05-05 21:06:18 +00:00
|
|
|
if err := json.Unmarshal([]byte(jsonData), &data); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &ImageVerificationMetadata{
|
|
|
|
Data: data,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2023-05-13 08:56:54 +00:00
|
|
|
func (ivm *ImageVerificationMetadata) Patches(hasAnnotations bool, log logr.Logger) ([]jsonpatch.JsonPatchOperation, error) {
|
2023-02-03 09:05:34 +00:00
|
|
|
if data, err := json.Marshal(ivm.Data); err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to marshal metadata value: %v: %w", data, err)
|
|
|
|
} else {
|
2023-05-13 08:56:54 +00:00
|
|
|
var patches []jsonpatch.JsonPatchOperation
|
2023-02-03 09:05:34 +00:00
|
|
|
if !hasAnnotations {
|
2023-05-13 08:56:54 +00:00
|
|
|
patch := jsonpatch.JsonPatchOperation{
|
|
|
|
Operation: "add",
|
|
|
|
Path: "/metadata/annotations",
|
|
|
|
Value: map[string]string{},
|
2023-02-03 09:05:34 +00:00
|
|
|
}
|
|
|
|
log.V(4).Info("adding annotation patch", "patch", patch)
|
2023-05-13 08:56:54 +00:00
|
|
|
patches = append(patches, patch)
|
2023-02-03 09:05:34 +00:00
|
|
|
}
|
2023-05-13 08:56:54 +00:00
|
|
|
patch := jsonpatch.JsonPatchOperation{
|
|
|
|
Operation: "add",
|
|
|
|
Path: makeAnnotationKeyForJSONPatch(),
|
|
|
|
Value: string(data),
|
2022-05-05 21:06:18 +00:00
|
|
|
}
|
2023-02-03 09:05:34 +00:00
|
|
|
log.V(4).Info("adding image verification patch", "patch", patch)
|
2023-05-13 08:56:54 +00:00
|
|
|
patches = append(patches, patch)
|
2023-02-03 09:05:34 +00:00
|
|
|
return patches, nil
|
2022-05-05 21:06:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-23 12:58:52 +00:00
|
|
|
func (ivm *ImageVerificationMetadata) Merge(other ImageVerificationMetadata) {
|
|
|
|
for k, v := range other.Data {
|
|
|
|
ivm.Add(k, v)
|
2022-05-05 21:06:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ivm *ImageVerificationMetadata) IsEmpty() bool {
|
|
|
|
return len(ivm.Data) == 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeAnnotationKeyForJSONPatch() string {
|
2023-08-02 14:02:21 +00:00
|
|
|
return "/metadata/annotations/" + strings.ReplaceAll(kyverno.AnnotationImageVerify, "/", "~1")
|
2022-05-05 21:06:18 +00:00
|
|
|
}
|