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

126 lines
4.1 KiB
Go
Raw Normal View History

package policyviolation
import (
"fmt"
"reflect"
"github.com/golang/glog"
2019-11-13 13:41:08 -08:00
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
2019-11-13 13:56:07 -08:00
kyvernov1 "github.com/nirmata/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1"
2019-11-13 13:41:08 -08:00
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1"
2019-11-26 18:07:15 -08:00
client "github.com/nirmata/kyverno/pkg/dclient"
2020-02-25 20:55:07 +05:30
"github.com/nirmata/kyverno/pkg/policyStatus"
2019-11-26 18:07:15 -08:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
2019-11-26 18:07:15 -08:00
//NamespacedPV ...
type namespacedPV struct {
// dynamic client
dclient *client.Client
// get/list namespaced policy violation
2019-12-12 16:25:50 -08:00
nspvLister kyvernolister.PolicyViolationLister
2019-11-26 18:07:15 -08:00
// policy violation interface
kyvernoInterface kyvernov1.KyvernoV1Interface
// update policy status with violationCount
2020-02-25 20:55:07 +05:30
policyStatus *policyStatus.Sync
2019-11-15 12:03:58 -08:00
}
2019-11-26 18:07:15 -08:00
func newNamespacedPV(dclient *client.Client,
2019-12-12 16:25:50 -08:00
nspvLister kyvernolister.PolicyViolationLister,
2019-11-26 18:07:15 -08:00
kyvernoInterface kyvernov1.KyvernoV1Interface,
2020-02-25 20:55:07 +05:30
policyStatus *policyStatus.Sync,
2019-11-26 18:07:15 -08:00
) *namespacedPV {
nspv := namespacedPV{
dclient: dclient,
nspvLister: nspvLister,
kyvernoInterface: kyvernoInterface,
policyStatus: policyStatus,
2019-11-26 18:07:15 -08:00
}
return &nspv
}
2019-12-12 16:25:50 -08:00
func (nspv *namespacedPV) create(pv kyverno.PolicyViolationTemplate) error {
newPv := kyverno.PolicyViolation(pv)
2019-11-26 18:07:15 -08:00
// PV already exists
oldPv, err := nspv.getExisting(newPv)
if err != nil {
return err
}
2019-11-26 18:07:15 -08:00
if oldPv == nil {
// create a new policy violation
return nspv.createPV(&newPv)
2019-11-12 23:19:38 -08:00
}
2019-11-26 18:07:15 -08:00
// policy violation exists
// skip if there is not change, else update the violation
return nspv.updatePV(&newPv, oldPv)
}
2019-12-12 16:25:50 -08:00
func (nspv *namespacedPV) getExisting(newPv kyverno.PolicyViolation) (*kyverno.PolicyViolation, error) {
2019-12-11 11:15:13 -08:00
var err error
// use labels
policyLabelmap := map[string]string{"policy": newPv.Spec.Policy, "resource": newPv.Spec.ResourceSpec.ToKey()}
ls, err := converLabelToSelector(policyLabelmap)
if err != nil {
return nil, err
2019-11-12 14:58:38 -08:00
}
2019-12-12 16:25:50 -08:00
pvs, err := nspv.nspvLister.PolicyViolations(newPv.GetNamespace()).List(ls)
2019-11-26 18:07:15 -08:00
if err != nil {
glog.Errorf("unable to list namespaced policy violations : %v", err)
return nil, err
2019-11-12 14:58:38 -08:00
}
2019-11-26 18:07:15 -08:00
for _, pv := range pvs {
// find a policy on same resource and policy combination
if pv.Spec.Policy == newPv.Spec.Policy &&
pv.Spec.ResourceSpec.Kind == newPv.Spec.ResourceSpec.Kind &&
pv.Spec.ResourceSpec.Name == newPv.Spec.ResourceSpec.Name {
return pv, nil
}
}
2019-11-26 18:07:15 -08:00
return nil, nil
}
2019-12-12 16:25:50 -08:00
func (nspv *namespacedPV) createPV(newPv *kyverno.PolicyViolation) error {
2019-11-26 18:07:15 -08:00
var err error
2019-12-02 17:15:47 -08:00
glog.V(4).Infof("creating new policy violation for policy %s & resource %s/%s/%s", newPv.Spec.Policy, newPv.Spec.ResourceSpec.Kind, newPv.Spec.ResourceSpec.Namespace, newPv.Spec.ResourceSpec.Name)
obj, err := retryGetResource(nspv.dclient, newPv.Spec.ResourceSpec)
if err != nil {
2019-11-26 18:07:15 -08:00
return fmt.Errorf("failed to retry getting resource for policy violation %s/%s: %v", newPv.Name, newPv.Spec.Policy, err)
}
2019-11-26 18:07:15 -08:00
// set owner reference to resource
ownerRef := createOwnerReference(obj)
newPv.SetOwnerReferences([]metav1.OwnerReference{ownerRef})
2019-11-26 18:07:15 -08:00
// create resource
2019-12-12 16:25:50 -08:00
_, err = nspv.kyvernoInterface.PolicyViolations(newPv.GetNamespace()).Create(newPv)
2019-11-26 18:07:15 -08:00
if err != nil {
glog.V(4).Infof("failed to create Cluster Policy Violation: %v", err)
return err
}
go nspv.policyStatus.UpdatePolicyStatusWithViolationCount(newPv.Spec.Policy, newPv.Spec.ViolatedRules)
2019-11-26 18:07:15 -08:00
glog.Infof("policy violation created for resource %v", newPv.Spec.ResourceSpec)
return nil
}
2019-12-12 16:25:50 -08:00
func (nspv *namespacedPV) updatePV(newPv, oldPv *kyverno.PolicyViolation) error {
2019-11-26 18:07:15 -08:00
var err error
// check if there is any update
if reflect.DeepEqual(newPv.Spec, oldPv.Spec) {
glog.V(4).Infof("policy violation spec %v did not change so not updating it", newPv.Spec)
return nil
}
2019-11-26 18:07:15 -08:00
// set name
newPv.SetName(oldPv.Name)
2019-12-11 11:15:13 -08:00
newPv.SetResourceVersion(oldPv.ResourceVersion)
2019-11-26 18:07:15 -08:00
// update resource
2019-12-12 16:25:50 -08:00
_, err = nspv.kyvernoInterface.PolicyViolations(newPv.GetNamespace()).Update(newPv)
2019-11-26 18:07:15 -08:00
if err != nil {
2020-02-06 22:51:16 -08:00
return fmt.Errorf("failed to update namespaced policy violation: %v", err)
}
2020-02-06 22:51:16 -08:00
go nspv.policyStatus.UpdatePolicyStatusWithViolationCount(newPv.Spec.Policy, newPv.Spec.ViolatedRules)
glog.Infof("namespaced policy violation updated for resource %v", newPv.Spec.ResourceSpec)
2019-11-26 18:07:15 -08:00
return nil
}