1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-07 00:17:13 +00:00
kyverno/pkg/cel/engine/engine.go
Charles-Edouard Brétéché 5cc408dddb
feat: use policy provider (#11947)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
2025-01-20 09:43:05 +00:00

129 lines
3.3 KiB
Go

package engine
import (
"context"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov2alpha1 "github.com/kyverno/kyverno/api/kyverno/v2alpha1"
"github.com/kyverno/kyverno/pkg/cel/policy"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/handlers"
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
type EngineRequest struct {
Resource *unstructured.Unstructured
NamespaceLabels map[string]map[string]string
}
type EngineResponse struct {
Resource *unstructured.Unstructured
Policies []PolicyResponse
}
type PolicyResponse struct {
Policy kyvernov2alpha1.ValidatingPolicy
Rules []engineapi.RuleResponse
}
type ValidatingPolicy struct {
policy kyvernov2alpha1.ValidatingPolicy
}
func (p *ValidatingPolicy) AsKyvernoPolicy() kyvernov1.PolicyInterface {
return nil
}
func (p *ValidatingPolicy) AsValidatingAdmissionPolicy() *admissionregistrationv1beta1.ValidatingAdmissionPolicy {
return nil
}
func (p *ValidatingPolicy) GetType() engineapi.PolicyType {
return engineapi.ValidatingAdmissionPolicyType
}
func (p *ValidatingPolicy) GetAPIVersion() string {
return "admissionregistration.k8s.io/v1beta1"
}
func (p *ValidatingPolicy) GetName() string {
return p.policy.GetName()
}
func (p *ValidatingPolicy) GetNamespace() string {
return p.policy.GetNamespace()
}
func (p *ValidatingPolicy) GetKind() string {
return "ValidatingAdmissionPolicy"
}
func (p *ValidatingPolicy) GetResourceVersion() string {
return p.policy.GetResourceVersion()
}
func (p *ValidatingPolicy) GetAnnotations() map[string]string {
return p.policy.GetAnnotations()
}
func (p *ValidatingPolicy) IsNamespaced() bool {
return false
}
func (p *ValidatingPolicy) MetaObject() metav1.Object {
return &p.policy
}
func NewValidatingPolicy(pol kyvernov2alpha1.ValidatingPolicy) engineapi.GenericPolicy {
return &ValidatingPolicy{
policy: pol,
}
}
type Engine interface {
Handle(context.Context, EngineRequest, ...policy.CompiledPolicy) (EngineResponse, error)
}
type engine struct {
provider Provider
}
func NewEngine(provider Provider) *engine {
return &engine{
provider: provider,
}
}
func (e *engine) Handle(ctx context.Context, request EngineRequest) (EngineResponse, error) {
response := EngineResponse{
Resource: request.Resource,
}
policies, err := e.provider.CompiledPolicies(ctx)
if err != nil {
return response, err
}
for _, policy := range policies {
response.Policies = append(response.Policies, e.handlePolicy(ctx, policy, request))
}
return response, nil
}
func (e *engine) handlePolicy(ctx context.Context, policy policy.CompiledPolicy, request EngineRequest) PolicyResponse {
var rules []engineapi.RuleResponse
ok, err := policy.Evaluate(ctx, request.Resource, request.NamespaceLabels)
// TODO: evaluation should be per rule
if err != nil {
rules = handlers.WithResponses(engineapi.RuleError("todo", engineapi.Validation, "failed to load context", err, nil))
} else if ok {
rules = handlers.WithResponses(engineapi.RulePass("todo", engineapi.Validation, "success", nil))
} else {
rules = handlers.WithResponses(engineapi.RuleFail("todo", engineapi.Validation, "failure", nil))
}
return PolicyResponse{
// TODO
Policy: kyvernov2alpha1.ValidatingPolicy{},
Rules: rules,
}
}