mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-26 01:24:26 +00:00
131 lines
4.7 KiB
Go
131 lines
4.7 KiB
Go
package eval
|
|
|
|
import (
|
|
"github.com/google/cel-go/cel"
|
|
policiesv1alpha1 "github.com/kyverno/kyverno/api/policies.kyverno.io/v1alpha1"
|
|
engine "github.com/kyverno/kyverno/pkg/cel"
|
|
"github.com/kyverno/kyverno/pkg/cel/libs/globalcontext"
|
|
"github.com/kyverno/kyverno/pkg/cel/libs/http"
|
|
"github.com/kyverno/kyverno/pkg/cel/libs/imagedata"
|
|
"github.com/kyverno/kyverno/pkg/cel/libs/imageverify"
|
|
"github.com/kyverno/kyverno/pkg/cel/libs/resource"
|
|
"github.com/kyverno/kyverno/pkg/cel/libs/user"
|
|
"github.com/kyverno/kyverno/pkg/cel/policy"
|
|
"github.com/kyverno/kyverno/pkg/imageverification/imagedataloader"
|
|
"github.com/kyverno/kyverno/pkg/imageverification/match"
|
|
"github.com/kyverno/kyverno/pkg/imageverification/variables"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
|
apiservercel "k8s.io/apiserver/pkg/cel"
|
|
k8scorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
|
)
|
|
|
|
const (
|
|
AttestationKey = "attestations"
|
|
AttestorKey = "attestors"
|
|
GlobalContextKey = "globalcontext"
|
|
HttpKey = "http"
|
|
ImagesKey = "images"
|
|
NamespaceObjectKey = "namespaceObject"
|
|
ObjectKey = "object"
|
|
OldObjectKey = "oldObject"
|
|
RequestKey = "request"
|
|
ResourceKey = "resource"
|
|
)
|
|
|
|
type Compiler interface {
|
|
Compile(*policiesv1alpha1.ImageVerificationPolicy) (CompiledPolicy, field.ErrorList)
|
|
}
|
|
|
|
func NewCompiler(ictx imagedataloader.ImageContext, lister k8scorev1.SecretInterface, reqGVR *metav1.GroupVersionResource) Compiler {
|
|
return &compiler{
|
|
ictx: ictx,
|
|
lister: lister,
|
|
reqGVR: reqGVR,
|
|
}
|
|
}
|
|
|
|
type compiler struct {
|
|
ictx imagedataloader.ImageContext
|
|
lister k8scorev1.SecretInterface
|
|
reqGVR *metav1.GroupVersionResource
|
|
}
|
|
|
|
func (c *compiler) Compile(ivpolicy *policiesv1alpha1.ImageVerificationPolicy) (CompiledPolicy, field.ErrorList) {
|
|
var allErrs field.ErrorList
|
|
base, err := engine.NewEnv()
|
|
if err != nil {
|
|
return nil, append(allErrs, field.InternalError(nil, err))
|
|
}
|
|
var declTypes []*apiservercel.DeclType
|
|
declTypes = append(declTypes, imageverify.Types()...)
|
|
options := []cel.EnvOption{
|
|
cel.Variable(ResourceKey, resource.ContextType),
|
|
cel.Variable(GlobalContextKey, globalcontext.ContextType),
|
|
cel.Variable(HttpKey, http.HTTPType),
|
|
cel.Variable(ImagesKey, cel.MapType(cel.StringType, cel.ListType(cel.StringType))),
|
|
cel.Variable(AttestorKey, cel.MapType(cel.StringType, cel.StringType)),
|
|
cel.Variable(AttestationKey, cel.MapType(cel.StringType, cel.StringType)),
|
|
}
|
|
|
|
if ivpolicy.Spec.EvaluationMode() == policiesv1alpha1.EvaluationModeKubernetes {
|
|
options = append(options, cel.Variable(RequestKey, policy.RequestType.CelType()))
|
|
options = append(options, cel.Variable(NamespaceObjectKey, policy.NamespaceType.CelType()))
|
|
options = append(options, cel.Variable(ObjectKey, cel.DynType))
|
|
options = append(options, cel.Variable(OldObjectKey, cel.DynType))
|
|
} else {
|
|
options = append(options, cel.Variable(ObjectKey, cel.DynType))
|
|
}
|
|
|
|
for _, declType := range declTypes {
|
|
options = append(options, cel.Types(declType.CelType()))
|
|
}
|
|
options = append(options, globalcontext.Lib(), http.Lib(), imagedata.Lib(), imageverify.Lib(c.ictx, ivpolicy, c.lister), resource.Lib(), user.Lib())
|
|
env, err := base.Extend(options...)
|
|
if err != nil {
|
|
return nil, append(allErrs, field.InternalError(nil, err))
|
|
}
|
|
path := field.NewPath("spec")
|
|
matchConditions := make([]cel.Program, 0, len(ivpolicy.Spec.MatchConditions))
|
|
{
|
|
path := path.Child("matchConditions")
|
|
programs, errs := policy.CompileMatchConditions(path, ivpolicy.Spec.MatchConditions, env)
|
|
if errs != nil {
|
|
return nil, append(allErrs, errs...)
|
|
}
|
|
matchConditions = append(matchConditions, programs...)
|
|
}
|
|
imageRules, errs := match.CompileMatches(path.Child("imageRules"), ivpolicy.Spec.ImageRules)
|
|
if errs != nil {
|
|
return nil, append(allErrs, errs...)
|
|
}
|
|
|
|
imageExtractors, errs := variables.CompileImageExtractors(path.Child("images"), ivpolicy.Spec.Images, c.reqGVR, options)
|
|
if errs != nil {
|
|
return nil, append(allErrs, errs...)
|
|
}
|
|
|
|
verifications := make([]policy.CompiledValidation, 0, len(ivpolicy.Spec.Verifications))
|
|
{
|
|
path := path.Child("verifications")
|
|
for i, rule := range ivpolicy.Spec.Verifications {
|
|
path := path.Index(i)
|
|
program, errs := policy.CompileValidation(path, rule, env)
|
|
if errs != nil {
|
|
return nil, append(allErrs, errs...)
|
|
}
|
|
verifications = append(verifications, program)
|
|
}
|
|
}
|
|
|
|
return &compiledPolicy{
|
|
failurePolicy: ivpolicy.GetFailurePolicy(),
|
|
matchConditions: matchConditions,
|
|
imageRules: imageRules,
|
|
verifications: verifications,
|
|
imageExtractors: imageExtractors,
|
|
attestorList: variables.GetAttestors(ivpolicy.Spec.Attestors),
|
|
attestationList: variables.GetAttestations(ivpolicy.Spec.Attestations),
|
|
creds: ivpolicy.Spec.Credentials,
|
|
}, nil
|
|
}
|