From 595dd3700ab0633c4e9a709d84fe421095664195 Mon Sep 17 00:00:00 2001 From: Shuting Zhao Date: Mon, 8 Jul 2019 17:51:37 -0700 Subject: [PATCH] create violation for generation rule --- pkg/gencontroller/controller.go | 26 ++++++++++++++------------ pkg/gencontroller/generation.go | 30 ++++++++++++++++++++++++------ pkg/violation/builder.go | 11 ++++++----- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/pkg/gencontroller/controller.go b/pkg/gencontroller/controller.go index fd0e4703ac..f4853cd958 100644 --- a/pkg/gencontroller/controller.go +++ b/pkg/gencontroller/controller.go @@ -22,12 +22,13 @@ import ( //Controller watches the 'Namespace' resource creation/update and applied the generation rules on them type Controller struct { - client *client.Client - namespaceLister v1CoreLister.NamespaceLister - namespaceSynced cache.InformerSynced - policyLister policyLister.PolicyLister - eventController event.Generator - workqueue workqueue.RateLimitingInterface + client *client.Client + namespaceLister v1CoreLister.NamespaceLister + namespaceSynced cache.InformerSynced + policyLister policyLister.PolicyLister + eventController event.Generator + violationBuilder violation.Generator + workqueue workqueue.RateLimitingInterface } //NewGenController returns a new Controller to manage generation rules @@ -39,12 +40,13 @@ func NewGenController(client *client.Client, // create the controller controller := &Controller{ - client: client, - namespaceLister: namespaceInformer.Lister(), - namespaceSynced: namespaceInformer.Informer().HasSynced, - policyLister: policyInformer.GetLister(), - eventController: eventController, - workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), wqNamespace), + client: client, + namespaceLister: namespaceInformer.Lister(), + namespaceSynced: namespaceInformer.Informer().HasSynced, + policyLister: policyInformer.GetLister(), + eventController: eventController, + violationBuilder: violationBuilder, + workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), wqNamespace), } namespaceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: controller.createNamespaceHandler, diff --git a/pkg/gencontroller/generation.go b/pkg/gencontroller/generation.go index daf2169b13..b8cc3cea2e 100644 --- a/pkg/gencontroller/generation.go +++ b/pkg/gencontroller/generation.go @@ -1,11 +1,15 @@ package gencontroller import ( + "fmt" + "strings" + "github.com/golang/glog" v1alpha1 "github.com/nirmata/kyverno/pkg/apis/policy/v1alpha1" "github.com/nirmata/kyverno/pkg/engine" event "github.com/nirmata/kyverno/pkg/event" "github.com/nirmata/kyverno/pkg/info" + violation "github.com/nirmata/kyverno/pkg/violation" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/labels" ) @@ -49,6 +53,8 @@ func (c *Controller) listPolicies(ns *corev1.Namespace) ([]*v1alpha1.Policy, err func (c *Controller) processPolicy(ns *corev1.Namespace, p *v1alpha1.Policy) { var eventInfo *event.Info + var onViolation bool + var msg string policyInfo := info.NewPolicyInfo(p.Name, "Namespace", @@ -62,15 +68,27 @@ func (c *Controller) processPolicy(ns *corev1.Namespace, p *v1alpha1.Policy) { glog.Infof("Failed to apply policy %s on resource %s %s", p.Name, ns.Kind, ns.Name) for _, r := range ruleInfos { glog.Warning(r.Msgs) + + if msg = strings.Join(r.Msgs, " "); strings.Contains(msg, "rule configuration not present in resource") { + onViolation = true + msg = fmt.Sprintf(`Resource creation violates generate rule '%s' of policy '%s'`, r.Name, policyInfo.Name) + } } - eventInfo = event.NewEvent(policyKind, "", policyInfo.Name, event.RequestBlocked, - event.FPolicyApplyBlockCreate, policyInfo.RName, policyInfo.GetRuleNames(false)) + if onViolation { + glog.Infof("Adding violation for generation rule of policy %s\n", policyInfo.Name) - glog.V(3).Infof("Request blocked event info has prepared for %s/%s\n", policyKind, policyInfo.Name) + v := violation.NewViolation(event.PolicyViolation, policyInfo.Name, policyInfo.RKind, policyInfo.RName, + policyInfo.RNamespace, msg) + c.violationBuilder.Add(v) + } else { + eventInfo = event.NewEvent(policyKind, "", policyInfo.Name, event.RequestBlocked, + event.FPolicyApplyBlockCreate, policyInfo.RName, policyInfo.GetRuleNames(false)) - // TODO: Generate policy Violations based on policyInfo - c.eventController.Add(eventInfo) + glog.V(2).Infof("Request blocked event info has prepared for %s/%s\n", policyKind, policyInfo.Name) + + c.eventController.Add(eventInfo) + } return } @@ -79,7 +97,7 @@ func (c *Controller) processPolicy(ns *corev1.Namespace, p *v1alpha1.Policy) { eventInfo = event.NewEvent(policyInfo.RKind, policyInfo.RNamespace, policyInfo.RName, event.PolicyApplied, event.SRulesApply, policyInfo.GetRuleNames(true), policyInfo.Name) - glog.V(3).Infof("Success event info has prepared for %s/%s\n", policyInfo.RKind, policyInfo.RName) + glog.V(2).Infof("Success event info has prepared for %s/%s\n", policyInfo.RKind, policyInfo.RName) c.eventController.Add(eventInfo) } diff --git a/pkg/violation/builder.go b/pkg/violation/builder.go index d3dec2ac39..6871a7fd0d 100644 --- a/pkg/violation/builder.go +++ b/pkg/violation/builder.go @@ -156,7 +156,7 @@ func (b *builder) processViolation(info *Info) error { // return nil } -func (b *builder) isActive(kind string, rname string, rnamespace string) (bool, error) { +func (b *builder) isActive(kind, rname, rnamespace string) (bool, error) { // Generate Merge Patch _, err := b.client.GetResource(b.client.DiscoveryClient.GetGVRFromKind(kind).Resource, rnamespace, rname) if err != nil { @@ -167,19 +167,20 @@ func (b *builder) isActive(kind string, rname string, rnamespace string) (bool, } //NewViolation return new policy violation -func NewViolation(policyName string, kind string, rname string, rnamespace string, reason string, msg string) Info { - return Info{Policy: policyName, +func NewViolation(reason event.Reason, policyName, kind, rname, rnamespace, msg string) *Info { + return &Info{Policy: policyName, Violation: types.Violation{ Kind: kind, Name: rname, Namespace: rnamespace, - Reason: reason, + Reason: reason.String(), + Message: msg, }, } } //NewViolationFromEvent returns violation info from event -func NewViolationFromEvent(e *event.Info, pName string, rKind string, rName string, rnamespace string) *Info { +func NewViolationFromEvent(e *event.Info, pName, rKind, rName, rnamespace string) *Info { return &Info{ Policy: pName, Violation: types.Violation{