1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-27 18:13:17 +00:00
kyverno/pkg/cel/libs/image/lib.go
Charles-Edouard Brétéché 2bb687550c
feat: add imagedata cel lib (#12442)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
2025-03-19 17:03:23 +08:00

160 lines
3.9 KiB
Go

package image
import (
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/google/go-containerregistry/pkg/name"
)
const libraryName = "kyverno.image"
func ImageLib() cel.EnvOption {
return cel.Lib(imageLib)
}
var imageLib = &imageLibType{}
type imageLibType struct{}
func (*imageLibType) LibraryName() string {
return libraryName
}
func (*imageLibType) Types() []*cel.Type {
return []*cel.Type{ImageType}
}
func (*imageLibType) declarations() map[string][]cel.FunctionOpt {
return map[string][]cel.FunctionOpt{
"image": {
cel.Overload("string_to_image", []*cel.Type{cel.StringType}, ImageType, cel.UnaryBinding((stringToImage))),
},
"isImage": {
cel.Overload("is_image_string", []*cel.Type{cel.StringType}, cel.BoolType, cel.UnaryBinding(isImage)),
},
"containsDigest": {
cel.MemberOverload("image_contains_digest", []*cel.Type{ImageType}, cel.BoolType, cel.UnaryBinding(imageContainsDigest)),
},
"registry": {
cel.MemberOverload("image_registry", []*cel.Type{ImageType}, cel.StringType, cel.UnaryBinding(imageRegistry)),
},
"repository": {
cel.MemberOverload("image_repository", []*cel.Type{ImageType}, cel.StringType, cel.UnaryBinding(imageRepository)),
},
"identifier": {
cel.MemberOverload("image_identifier", []*cel.Type{ImageType}, cel.StringType, cel.UnaryBinding(imageIdentifier)),
},
"tag": {
cel.MemberOverload("image_tag", []*cel.Type{ImageType}, cel.StringType, cel.UnaryBinding(imageTag)),
},
"digest": {
cel.MemberOverload("image_digest", []*cel.Type{ImageType}, cel.StringType, cel.UnaryBinding(imageDigest)),
},
}
}
func (i *imageLibType) CompileOptions() []cel.EnvOption {
imageLibraryDecls := i.declarations()
options := make([]cel.EnvOption, 0, len(imageLibraryDecls))
for name, overloads := range imageLibraryDecls {
options = append(options, cel.Function(name, overloads...))
}
return options
}
func (*imageLibType) ProgramOptions() []cel.ProgramOption {
return []cel.ProgramOption{}
}
func isImage(arg ref.Val) ref.Val {
str, ok := arg.Value().(string)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
_, err := name.ParseReference(str)
if err != nil {
return types.Bool(false)
}
return types.Bool(true)
}
func stringToImage(arg ref.Val) ref.Val {
str, ok := arg.Value().(string)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
v, err := name.ParseReference(str)
if err != nil {
return types.WrapErr(err)
}
return Image{ImageReference: ConvertToImageRef(v)}
}
func imageContainsDigest(arg ref.Val) ref.Val {
v, ok := arg.Value().(ImageReference)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
return types.Bool(len(v.Digest) != 0)
}
func imageRegistry(arg ref.Val) ref.Val {
v, ok := arg.Value().(ImageReference)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
return types.String(v.Registry)
}
func imageRepository(arg ref.Val) ref.Val {
v, ok := arg.Value().(ImageReference)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
return types.String(v.Repository)
}
func imageIdentifier(arg ref.Val) ref.Val {
v, ok := arg.Value().(ImageReference)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
return types.String(v.Identifier)
}
func imageTag(arg ref.Val) ref.Val {
v, ok := arg.Value().(ImageReference)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
return types.String(v.Tag)
}
func imageDigest(arg ref.Val) ref.Val {
v, ok := arg.Value().(ImageReference)
if !ok {
return types.MaybeNoSuchOverloadErr(arg)
}
return types.String(v.Digest)
}
func ConvertToImageRef(ref name.Reference) ImageReference {
var img ImageReference
img.Image = ref.String()
img.Registry = ref.Context().RegistryStr()
img.Repository = ref.Context().RepositoryStr()
img.Identifier = ref.Identifier()
if _, ok := ref.(name.Tag); ok {
img.Tag = ref.Identifier()
} else {
img.Digest = ref.Identifier()
}
return img
}