1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-09 09:26:54 +00:00
kyverno/pkg/policyviolation/builder.go

116 lines
3.3 KiB
Go
Raw Normal View History

2019-05-10 10:38:38 -07:00
package policyviolation
2019-04-26 18:16:22 -07:00
import (
"fmt"
"log"
kubeClient "github.com/nirmata/kube-policy/kubeclient"
types "github.com/nirmata/kube-policy/pkg/apis/policy/v1alpha1"
2019-05-10 00:05:21 -07:00
policyclientset "github.com/nirmata/kube-policy/pkg/client/clientset/versioned"
policylister "github.com/nirmata/kube-policy/pkg/client/listers/policy/v1alpha1"
event "github.com/nirmata/kube-policy/pkg/event"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
2019-05-10 00:05:21 -07:00
"k8s.io/client-go/tools/cache"
)
2019-05-10 10:38:38 -07:00
//Generator to generate policy violation
type Generator interface {
2019-05-10 12:36:55 -07:00
Add(info Info) error
2019-04-26 18:16:22 -07:00
}
2019-05-10 10:38:38 -07:00
type builder struct {
2019-05-10 00:05:21 -07:00
kubeClient *kubeClient.KubeClient
policyLister policylister.PolicyLister
policyInterface policyclientset.Interface
2019-05-10 10:38:38 -07:00
eventBuilder event.Generator
2019-05-10 00:05:21 -07:00
logger *log.Logger
}
2019-05-10 10:38:38 -07:00
//Builder is to build policy violations
type Builder interface {
Generator
2019-05-10 12:36:55 -07:00
processViolation(info Info) error
2019-05-10 00:05:21 -07:00
isActive(kind string, resource string) (bool, error)
}
2019-05-10 10:38:38 -07:00
//NewPolicyViolationBuilder returns new violation builder
2019-05-10 00:05:21 -07:00
func NewPolicyViolationBuilder(
kubeClient *kubeClient.KubeClient,
2019-05-10 00:05:21 -07:00
policyLister policylister.PolicyLister,
policyInterface policyclientset.Interface,
2019-05-10 10:38:38 -07:00
eventController event.Generator,
logger *log.Logger) Builder {
2019-05-10 10:38:38 -07:00
builder := &builder{
2019-05-10 00:05:21 -07:00
kubeClient: kubeClient,
policyLister: policyLister,
policyInterface: policyInterface,
eventBuilder: eventController,
logger: logger,
2019-05-06 12:08:31 -07:00
}
2019-05-10 00:05:21 -07:00
return builder
}
2019-05-10 12:36:55 -07:00
func (b *builder) Add(info Info) error {
2019-05-10 10:38:38 -07:00
return b.processViolation(info)
}
2019-05-10 12:36:55 -07:00
func (b *builder) processViolation(info Info) error {
// Get the policy
2019-05-10 00:05:21 -07:00
namespace, name, err := cache.SplitMetaNamespaceKey(info.Policy)
if err != nil {
utilruntime.HandleError(fmt.Errorf("unable to extract namespace and name for %s", info.Policy))
return err
}
2019-05-10 10:38:38 -07:00
policy, err := b.policyLister.Policies(namespace).Get(name)
if err != nil {
2019-04-30 17:13:44 -07:00
utilruntime.HandleError(err)
return err
}
modifiedPolicy := policy.DeepCopy()
modifiedViolations := []types.Violation{}
2019-04-30 17:13:44 -07:00
2019-05-06 10:30:44 -07:00
// Create new violation
2019-05-10 12:36:55 -07:00
newViolation := info.Violation
for _, violation := range modifiedPolicy.Status.Violations {
2019-05-10 10:38:38 -07:00
ok, err := b.isActive(info.Kind, violation.Resource)
if err != nil {
utilruntime.HandleError(err)
continue
}
if !ok {
2019-05-10 10:38:38 -07:00
b.logger.Printf("removed violation")
2019-04-30 17:13:44 -07:00
}
}
2019-05-10 00:05:21 -07:00
// If violation already exists for this rule, we update the violation
//TODO: update violation, instead of re-creating one every time
2019-05-06 10:30:44 -07:00
modifiedViolations = append(modifiedViolations, newViolation)
modifiedPolicy.Status.Violations = modifiedViolations
// Violations are part of the status sub resource, so we can use the Update Status api instead of updating the policy object
2019-05-10 10:38:38 -07:00
_, err = b.policyInterface.NirmataV1alpha1().Policies(namespace).UpdateStatus(modifiedPolicy)
2019-05-10 00:05:21 -07:00
if err != nil {
return err
}
return nil
2019-04-30 17:13:44 -07:00
}
2019-05-10 10:38:38 -07:00
func (b *builder) isActive(kind string, resource string) (bool, error) {
// Generate Merge Patch
2019-05-10 10:38:38 -07:00
_, err := b.kubeClient.GetResource(kind, resource)
if err != nil {
utilruntime.HandleError(fmt.Errorf("unable to get resource %s ", resource))
2019-04-30 17:13:44 -07:00
return false, err
}
2019-04-30 17:13:44 -07:00
return true, nil
}
2019-05-10 12:36:55 -07:00
//NewViolation return new policy violation
func NewViolation(policyName string, kind string, resource string, rule string) Info {
return Info{Policy: policyName,
Violation: types.Violation{
Kind: kind, Resource: resource, Rule: rule},
}
}