1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-10 18:06:55 +00:00
kyverno/pkg/policyengine/policyengine.go

106 lines
3.8 KiB
Go
Raw Normal View History

2019-05-09 22:26:22 -07:00
package policyengine
import (
"fmt"
"log"
kubeClient "github.com/nirmata/kube-policy/kubeclient"
types "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
2019-05-10 12:36:55 -07:00
event "github.com/nirmata/kube-policy/pkg/event"
2019-05-09 22:26:22 -07:00
"github.com/nirmata/kube-policy/pkg/policyengine/mutation"
2019-05-10 12:36:55 -07:00
policyviolation "github.com/nirmata/kube-policy/pkg/policyviolation"
2019-05-09 22:26:22 -07:00
)
type PolicyEngine interface {
// ProcessMutation should be called from admission contoller
// when there is an creation / update of the resource
// ProcessMutation(policy types.Policy, rawResource []byte) (patchBytes []byte, events []Events, err error)
Mutate(policy types.Policy, rawResource []byte) []mutation.PatchBytes
2019-05-09 22:26:22 -07:00
// ProcessValidation should be called from admission contoller
// when there is an creation / update of the resource
// TODO: Change name to Validate
2019-05-09 22:26:22 -07:00
ProcessValidation(policy types.Policy, rawResource []byte)
// ProcessExisting should be called from policy controller
// when there is an create / update of the policy
// we should process the policy on matched resources, generate violations accordingly
// TODO: This method should not be in PolicyEngine. Validate will do this work instead
2019-05-10 12:36:55 -07:00
ProcessExisting(policy types.Policy, rawResource []byte) ([]policyviolation.Info, []event.Info, error)
// TODO: Add Generate method
2019-05-09 22:26:22 -07:00
}
type policyEngine struct {
kubeClient *kubeClient.KubeClient
2019-05-10 12:36:55 -07:00
logger *log.Logger
2019-05-09 22:26:22 -07:00
}
func NewPolicyEngine(kubeClient *kubeClient.KubeClient, logger *log.Logger) PolicyEngine {
return &policyEngine{
kubeClient: kubeClient,
logger: logger,
}
}
2019-05-10 12:36:55 -07:00
func (p *policyEngine) ProcessExisting(policy types.Policy, rawResource []byte) ([]policyviolation.Info, []event.Info, error) {
var violations []policyviolation.Info
var events []event.Info
2019-05-09 22:26:22 -07:00
for _, rule := range policy.Spec.Rules {
err := rule.Validate()
if err != nil {
p.logger.Printf("Invalid rule detected: #%s in policy %s, err: %v\n", rule.Name, policy.ObjectMeta.Name, err)
continue
}
if ok, err := mutation.IsRuleApplicableToResource(rawResource, rule.ResourceDescription); !ok {
2019-05-09 22:26:22 -07:00
p.logger.Printf("Rule %s of policy %s is not applicable to the request", rule.Name, policy.Name)
return nil, nil, err
}
violation, eventInfos, err := p.processRuleOnResource(policy.Name, rule, rawResource)
2019-05-09 22:26:22 -07:00
if err != nil {
p.logger.Printf("Failed to process rule %s, err: %v\n", rule.Name, err)
continue
}
// } else {
// policyPatches = append(policyPatches, processedPatches...)
// }
violations = append(violations, violation)
events = append(events, eventInfos...)
}
return violations, events, nil
}
func (p *policyEngine) processRuleOnResource(policyName string, rule types.Rule, rawResource []byte) (
2019-05-10 12:36:55 -07:00
policyviolation.Info, []event.Info, error) {
2019-05-09 22:26:22 -07:00
2019-05-10 12:36:55 -07:00
var violationInfo policyviolation.Info
var eventInfos []event.Info
2019-05-09 22:26:22 -07:00
resourceKind := mutation.ParseKindFromObject(rawResource)
resourceName := mutation.ParseNameFromObject(rawResource)
resourceNamespace := mutation.ParseNamespaceFromObject(rawResource)
rulePatchesProcessed, err := mutation.ProcessPatches(rule.Mutation.Patches, nil)
2019-05-09 22:26:22 -07:00
if err != nil {
return violationInfo, eventInfos, fmt.Errorf("Failed to process patches from rule %s: %v", rule.Name, err)
}
if rulePatchesProcessed != nil {
log.Printf("Rule %s: prepared %d patches", rule.Name, len(rulePatchesProcessed))
2019-05-10 12:36:55 -07:00
violationInfo = policyviolation.NewViolation(policyName, resourceKind, resourceNamespace+"/"+resourceName, rule.Name)
2019-05-09 22:26:22 -07:00
// add a violation to queue
// add an event to policy
2019-05-10 12:36:55 -07:00
//TODO: event msg
eventInfos = append(eventInfos, event.NewEvent("Policy", policyName, event.PolicyViolation, event.FResourcePolcy))
2019-05-09 22:26:22 -07:00
// add an event to resource
2019-05-10 12:36:55 -07:00
eventInfos = append(eventInfos, event.NewEvent(resourceKind, resourceNamespace+"/"+resourceName, event.PolicyViolation, event.FResourcePolcy))
2019-05-09 22:26:22 -07:00
}
return violationInfo, eventInfos, nil
}