1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-31 03:45:17 +00:00

- remove policy violation created on owner and related logic; - use generic call to create violation info

This commit is contained in:
Shuting Zhao 2020-01-06 17:07:11 -08:00
parent 9194251a38
commit ecbbd04bc5
9 changed files with 95 additions and 377 deletions

View file

@ -4,7 +4,6 @@ import (
"fmt"
"github.com/golang/glog"
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
"github.com/nirmata/kyverno/pkg/engine/response"
"github.com/nirmata/kyverno/pkg/event"
"github.com/nirmata/kyverno/pkg/policyviolation"
@ -15,55 +14,10 @@ func (nsc *NamespaceController) report(engineResponses []response.EngineResponse
eventInfos := generateEvents(engineResponses)
nsc.eventGen.Add(eventInfos...)
// generate policy violations
pvInfos := generatePVs(engineResponses)
pvInfos := policyviolation.GeneratePVsFromEngineResponse(engineResponses)
nsc.pvGenerator.Add(pvInfos...)
}
func generatePVs(ers []response.EngineResponse) []policyviolation.Info {
var pvInfos []policyviolation.Info
for _, er := range ers {
// ignore creation of PV for resoruces that are yet to be assigned a name
if er.PolicyResponse.Resource.Name == "" {
glog.V(4).Infof("resource %v, has not been assigned a name, not creating a policy violation for it", er.PolicyResponse.Resource)
continue
}
if er.IsSuccesful() {
continue
}
glog.V(4).Infof("Building policy violation for engine response %v", er)
// build policy violation info
pvInfos = append(pvInfos, buildPVInfo(er))
}
return pvInfos
}
func buildPVInfo(er response.EngineResponse) policyviolation.Info {
info := policyviolation.Info{
Blocked: false,
PolicyName: er.PolicyResponse.Policy,
Resource: er.PatchedResource,
Rules: buildViolatedRules(er),
}
return info
}
func buildViolatedRules(er response.EngineResponse) []kyverno.ViolatedRule {
var violatedRules []kyverno.ViolatedRule
for _, rule := range er.PolicyResponse.Rules {
if rule.Success {
continue
}
vrule := kyverno.ViolatedRule{
Name: rule.Name,
Type: rule.Type,
Message: rule.Message,
}
violatedRules = append(violatedRules, vrule)
}
return violatedRules
}
func generateEvents(ers []response.EngineResponse) []event.Info {
var eventInfos []event.Info
for _, er := range ers {

View file

@ -7,84 +7,52 @@ import (
"github.com/golang/glog"
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1"
dclient "github.com/nirmata/kyverno/pkg/dclient"
"github.com/nirmata/kyverno/pkg/engine/response"
"github.com/nirmata/kyverno/pkg/policyviolation"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
)
func (pc *PolicyController) cleanUpPolicyViolation(pResponse response.PolicyResponse) {
// 1- check if there is violation on resource (label:Selector)
// 2- check if there is violation on owner
// - recursively get owner by queries the api server for owner information of the resource
// there can be multiple violations as a resource can have multiple owners
// - check if there is violation on resource (label:Selector)
if pResponse.Resource.Namespace == "" {
pvs, err := getClusterPVs(pc.cpvLister, pc.client, pResponse.Policy, pResponse.Resource.Kind, pResponse.Resource.Name)
pv, err := getClusterPV(pc.cpvLister, pResponse.Policy, pResponse.Resource.Kind, pResponse.Resource.Name)
if err != nil {
glog.Errorf("failed to cleanUp violations: %v", err)
return
}
for _, pv := range pvs {
if reflect.DeepEqual(pv, kyverno.ClusterPolicyViolation{}) {
continue
}
glog.V(4).Infof("cleanup cluster violation %s on %s", pv.Name, pv.Spec.ResourceSpec.ToKey())
if err := pc.pvControl.DeleteClusterPolicyViolation(pv.Name); err != nil {
glog.Errorf("failed to delete cluster policy violation %s on %s: %v", pv.Name, pv.Spec.ResourceSpec.ToKey(), err)
continue
}
if reflect.DeepEqual(pv, kyverno.ClusterPolicyViolation{}) {
return
}
glog.V(4).Infof("cleanup cluster violation %s on %s", pv.Name, pv.Spec.ResourceSpec.ToKey())
if err := pc.pvControl.DeleteClusterPolicyViolation(pv.Name); err != nil {
glog.Errorf("failed to delete cluster policy violation %s on %s: %v", pv.Name, pv.Spec.ResourceSpec.ToKey(), err)
}
return
}
nspvs, err := getNamespacedPVs(pc.nspvLister, pc.client, pResponse.Policy, pResponse.Resource.Kind, pResponse.Resource.Namespace, pResponse.Resource.Name)
// namespace policy violation
nspv, err := getNamespacedPV(pc.nspvLister, pResponse.Policy, pResponse.Resource.Kind, pResponse.Resource.Namespace, pResponse.Resource.Name)
if err != nil {
glog.Error(err)
return
}
for _, pv := range nspvs {
if reflect.DeepEqual(pv, kyverno.PolicyViolation{}) {
continue
}
glog.V(4).Infof("cleanup namespaced violation %s on %s.%s", pv.Name, pResponse.Resource.Namespace, pv.Spec.ResourceSpec.ToKey())
if err := pc.pvControl.DeleteNamespacedPolicyViolation(pv.Namespace, pv.Name); err != nil {
glog.Errorf("failed to delete namespaced policy violation %s on %s: %v", pv.Name, pv.Spec.ResourceSpec.ToKey(), err)
continue
}
if reflect.DeepEqual(nspv, kyverno.PolicyViolation{}) {
return
}
glog.V(4).Infof("cleanup namespaced violation %s on %s.%s", nspv.Name, pResponse.Resource.Namespace, nspv.Spec.ResourceSpec.ToKey())
if err := pc.pvControl.DeleteNamespacedPolicyViolation(nspv.Namespace, nspv.Name); err != nil {
glog.Errorf("failed to delete namespaced policy violation %s on %s: %v", nspv.Name, nspv.Spec.ResourceSpec.ToKey(), err)
}
}
func getClusterPVs(pvLister kyvernolister.ClusterPolicyViolationLister, client *dclient.Client, policyName, kind, name string) ([]kyverno.ClusterPolicyViolation, error) {
var pvs []kyverno.ClusterPolicyViolation
// Wont do the claiming of objects, just lookup based on selectors
func getClusterPV(pvLister kyvernolister.ClusterPolicyViolationLister, policyName, rkind, rname string) (kyverno.ClusterPolicyViolation, error) {
var err error
// Check Violation on resource
pv, err := getClusterPVOnResource(pvLister, policyName, kind, name)
if err != nil {
glog.V(4).Infof("error while fetching violation on existing resource: %v", err)
return nil, err
}
if !reflect.DeepEqual(pv, kyverno.ClusterPolicyViolation{}) {
// found a violation on resource
pvs = append(pvs, pv)
return pvs, nil
}
// Check Violations on owner
pvs, err = getClusterPVonOwnerRef(pvLister, client, policyName, kind, name)
if err != nil {
glog.V(4).Infof("error while fetching pv: %v", err)
return nil, err
}
return pvs, nil
}
// Wont do the claiming of objects, just lookup based on selectors and owner references
func getClusterPVOnResource(pvLister kyvernolister.ClusterPolicyViolationLister, policyName, kind, name string) (kyverno.ClusterPolicyViolation, error) {
pvs, err := pvLister.List(labels.Everything())
if err != nil {
glog.V(2).Infof("unable to list policy violations : %v", err)
@ -94,65 +62,16 @@ func getClusterPVOnResource(pvLister kyvernolister.ClusterPolicyViolationLister,
for _, pv := range pvs {
// find a policy on same resource and policy combination
if pv.Spec.Policy == policyName &&
pv.Spec.ResourceSpec.Kind == kind &&
pv.Spec.ResourceSpec.Name == name {
pv.Spec.ResourceSpec.Kind == rkind &&
pv.Spec.ResourceSpec.Name == rname {
return *pv, nil
}
}
return kyverno.ClusterPolicyViolation{}, nil
}
func getClusterPVonOwnerRef(pvLister kyvernolister.ClusterPolicyViolationLister, dclient *dclient.Client, policyName, kind, name string) ([]kyverno.ClusterPolicyViolation, error) {
var pvs []kyverno.ClusterPolicyViolation
// get resource
resource, err := dclient.GetResource(kind, "", name)
if err != nil {
glog.V(4).Infof("error while fetching the resource: %v", err)
return pvs, fmt.Errorf("error while fetching the resource: %v", err)
}
// getOwners returns nil if there is any error
owners := map[kyverno.ResourceSpec]interface{}{}
policyviolation.GetOwner(dclient, owners, *resource)
// as we can have multiple top level owners to a resource
// check if pv exists on each one
for owner := range owners {
pv, err := getClusterPVOnResource(pvLister, policyName, owner.Kind, owner.Name)
if err != nil {
glog.Errorf("error while fetching resource owners: %v", err)
continue
}
pvs = append(pvs, pv)
}
return pvs, nil
}
func getNamespacedPVs(nspvLister kyvernolister.PolicyViolationLister, client *dclient.Client, policyName, kind, namespace, name string) ([]kyverno.PolicyViolation, error) {
var pvs []kyverno.PolicyViolation
var err error
pv, err := getNamespacedPVOnResource(nspvLister, policyName, kind, namespace, name)
if err != nil {
glog.V(4).Infof("error while fetching violation on existing resource: %v", err)
return nil, err
}
if !reflect.DeepEqual(pv, kyverno.PolicyViolation{}) {
// found a violation on resource
pvs = append(pvs, pv)
return pvs, nil
}
// Check Violations on owner
pvs, err = getNamespacedPVonOwnerRef(nspvLister, client, policyName, kind, namespace, name)
if err != nil {
glog.V(4).Infof("error while fetching pv: %v", err)
return nil, err
}
return pvs, nil
}
func getNamespacedPVOnResource(nspvLister kyvernolister.PolicyViolationLister, policyName, kind, namespace, name string) (kyverno.PolicyViolation, error) {
nspvs, err := nspvLister.PolicyViolations(namespace).List(labels.Everything())
func getNamespacedPV(nspvLister kyvernolister.PolicyViolationLister, policyName, rkind, rnamespace, rname string) (kyverno.PolicyViolation, error) {
nspvs, err := nspvLister.PolicyViolations(rnamespace).List(labels.Everything())
if err != nil {
glog.V(2).Infof("failed to list namespaced pv: %v", err)
return kyverno.PolicyViolation{}, fmt.Errorf("failed to list namespaced pv: %v", err)
@ -161,39 +80,15 @@ func getNamespacedPVOnResource(nspvLister kyvernolister.PolicyViolationLister, p
for _, nspv := range nspvs {
// find a policy on same resource and policy combination
if nspv.Spec.Policy == policyName &&
nspv.Spec.ResourceSpec.Kind == kind &&
nspv.Spec.ResourceSpec.Name == name {
nspv.Spec.ResourceSpec.Kind == rkind &&
nspv.Spec.ResourceSpec.Name == rname {
return *nspv, nil
}
}
return kyverno.PolicyViolation{}, nil
}
func getNamespacedPVonOwnerRef(nspvLister kyvernolister.PolicyViolationLister, dclient *dclient.Client, policyName, kind, namespace, name string) ([]kyverno.PolicyViolation, error) {
var pvs []kyverno.PolicyViolation
// get resource
resource, err := dclient.GetResource(kind, namespace, name)
if err != nil {
glog.V(4).Infof("error while fetching the resource: %v", err)
return pvs, err
}
// getOwners returns nil if there is any error
owners := map[kyverno.ResourceSpec]interface{}{}
policyviolation.GetOwner(dclient, owners, *resource)
// as we can have multiple top level owners to a resource
// check if pv exists on each one
for owner := range owners {
pv, err := getNamespacedPVOnResource(nspvLister, policyName, owner.Kind, namespace, owner.Name)
if err != nil {
glog.Errorf("error while fetching resource owners: %v", err)
continue
}
pvs = append(pvs, pv)
}
return pvs, nil
}
func converLabelToSelector(labelMap map[string]string) (labels.Selector, error) {
ls := &metav1.LabelSelector{}
err := metav1.Convert_Map_string_To_string_To_v1_LabelSelector(&labelMap, ls, nil)

View file

@ -4,7 +4,6 @@ import (
"fmt"
"github.com/golang/glog"
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
"github.com/nirmata/kyverno/pkg/engine/response"
"github.com/nirmata/kyverno/pkg/event"
"github.com/nirmata/kyverno/pkg/policyviolation"
@ -12,13 +11,13 @@ import (
// for each policy-resource response
// - has violation -> report
// - no violation -> cleanup policy violations(resource or resource owner)
// - no violation -> cleanup policy violations
func (pc *PolicyController) cleanupAndReport(engineResponses []response.EngineResponse) {
// generate Events
eventInfos := generateEvents(engineResponses)
pc.eventGen.Add(eventInfos...)
// create policy violation
pvInfos := generatePVs(engineResponses)
pvInfos := policyviolation.GeneratePVsFromEngineResponse(engineResponses)
pc.pvGenerator.Add(pvInfos...)
// cleanup existing violations if any
// if there is any error in clean up, we dont re-queue the resource
@ -39,51 +38,6 @@ func (pc *PolicyController) cleanUp(ers []response.EngineResponse) {
}
}
func generatePVs(ers []response.EngineResponse) []policyviolation.Info {
var pvInfos []policyviolation.Info
for _, er := range ers {
// ignore creation of PV for resoruces that are yet to be assigned a name
if er.PolicyResponse.Resource.Name == "" {
glog.V(4).Infof("resource %v, has not been assigned a name, not creating a policy violation for it", er.PolicyResponse.Resource)
continue
}
if er.IsSuccesful() {
continue
}
glog.V(4).Infof("Building policy violation for engine response %v", er)
// build policy violation info
pvInfos = append(pvInfos, buildPVInfo(er))
}
return pvInfos
}
func buildPVInfo(er response.EngineResponse) policyviolation.Info {
info := policyviolation.Info{
Blocked: false,
PolicyName: er.PolicyResponse.Policy,
Resource: er.PatchedResource,
Rules: buildViolatedRules(er),
}
return info
}
func buildViolatedRules(er response.EngineResponse) []kyverno.ViolatedRule {
var violatedRules []kyverno.ViolatedRule
for _, rule := range er.PolicyResponse.Rules {
if rule.Success {
continue
}
vrule := kyverno.ViolatedRule{
Name: rule.Name,
Type: rule.Type,
Message: rule.Message,
}
violatedRules = append(violatedRules, vrule)
}
return violatedRules
}
func generateEvents(ers []response.EngineResponse) []event.Info {
var eventInfos []event.Info
for _, er := range ers {

View file

@ -3,14 +3,34 @@ package policyviolation
import (
"fmt"
"github.com/golang/glog"
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
client "github.com/nirmata/kyverno/pkg/dclient"
"github.com/nirmata/kyverno/pkg/engine/response"
)
func GeneratePVsFromEngineResponse(ers []response.EngineResponse) (pvInfos []Info) {
for _, er := range ers {
// ignore creation of PV for resoruces that are yet to be assigned a name
if er.PolicyResponse.Resource.Name == "" {
glog.V(4).Infof("resource %v, has not been assigned a name, not creating a policy violation for it", er.PolicyResponse.Resource)
continue
}
if er.IsSuccesful() {
continue
}
glog.V(4).Infof("Building policy violation for engine response %v", er)
// build policy violation info
pvInfos = append(pvInfos, buildPVInfo(er))
}
return pvInfos
}
// Builder builds Policy Violation struct
// this is base type of namespaced and cluster policy violation
type Builder interface {
generate(info Info) []kyverno.PolicyViolationTemplate
generate(info Info) kyverno.PolicyViolationTemplate
build(policy, kind, namespace, name string, rules []kyverno.ViolatedRule) *kyverno.PolicyViolationTemplate
}
@ -25,33 +45,10 @@ func newPvBuilder(dclient *client.Client) *pvBuilder {
}
return &pvb
}
func (pvb *pvBuilder) generate(info Info) []kyverno.PolicyViolationTemplate {
var owners []kyverno.ResourceSpec
// get the owners if the resource is blocked or
// TODO: https://github.com/nirmata/kyverno/issues/535
if info.Blocked {
// get resource owners
owners = GetOwners(pvb.dclient, info.Resource)
}
pvs := pvb.buildPolicyViolations(owners, info)
return pvs
}
func (pvb *pvBuilder) buildPolicyViolations(owners []kyverno.ResourceSpec, info Info) []kyverno.PolicyViolationTemplate {
var pvs []kyverno.PolicyViolationTemplate
if len(owners) != 0 {
// there are resource owners
// generate PV on them
for _, resource := range owners {
pv := pvb.build(info.PolicyName, resource.Kind, resource.Namespace, resource.Name, info.Rules)
pvs = append(pvs, *pv)
}
} else {
// generate PV on resource
pv := pvb.build(info.PolicyName, info.Resource.GetKind(), info.Resource.GetNamespace(), info.Resource.GetName(), info.Rules)
pvs = append(pvs, *pv)
}
return pvs
func (pvb *pvBuilder) generate(info Info) kyverno.PolicyViolationTemplate {
pv := pvb.build(info.PolicyName, info.Resource.GetKind(), info.Resource.GetNamespace(), info.Resource.GetName(), info.Rules)
return *pv
}
func (pvb *pvBuilder) build(policy, kind, namespace, name string, rules []kyverno.ViolatedRule) *kyverno.PolicyViolationTemplate {
@ -77,3 +74,28 @@ func (pvb *pvBuilder) build(policy, kind, namespace, name string, rules []kyvern
pv.SetGenerateName(fmt.Sprintf("%s-", policy))
return pv
}
func buildPVInfo(er response.EngineResponse) Info {
info := Info{
PolicyName: er.PolicyResponse.Policy,
Resource: er.PatchedResource,
Rules: buildViolatedRules(er),
}
return info
}
func buildViolatedRules(er response.EngineResponse) []kyverno.ViolatedRule {
var violatedRules []kyverno.ViolatedRule
for _, rule := range er.PolicyResponse.Rules {
if rule.Success {
continue
}
vrule := kyverno.ViolatedRule{
Name: rule.Name,
Type: rule.Type,
Message: rule.Message,
}
violatedRules = append(violatedRules, vrule)
}
return violatedRules
}

View file

@ -56,50 +56,6 @@ func retryGetResource(client *client.Client, rspec kyverno.ResourceSpec) (*unstr
return obj, nil
}
// GetOwners returns a list of owners
func GetOwners(dclient *client.Client, resource unstructured.Unstructured) []kyverno.ResourceSpec {
ownerMap := map[kyverno.ResourceSpec]interface{}{}
GetOwner(dclient, ownerMap, resource)
var owners []kyverno.ResourceSpec
for owner := range ownerMap {
owners = append(owners, owner)
}
return owners
}
// GetOwner of a resource by iterating over ownerReferences
func GetOwner(dclient *client.Client, ownerMap map[kyverno.ResourceSpec]interface{}, resource unstructured.Unstructured) {
var emptyInterface interface{}
resourceSpec := kyverno.ResourceSpec{
Kind: resource.GetKind(),
Namespace: resource.GetNamespace(),
Name: resource.GetName(),
}
if _, ok := ownerMap[resourceSpec]; ok {
// owner seen before
// breaking loop
return
}
rOwners := resource.GetOwnerReferences()
// if there are no resource owners then its top level resource
if len(rOwners) == 0 {
// add resource to map
ownerMap[resourceSpec] = emptyInterface
return
}
for _, rOwner := range rOwners {
// lookup resource via client
// owner has to be in same namespace
owner, err := dclient.GetResource(rOwner.Kind, resource.GetNamespace(), rOwner.Name)
if err != nil {
glog.Errorf("Failed to get resource owner for %s/%s/%s, err: %v", rOwner.Kind, resource.GetNamespace(), rOwner.Name, err)
// as we want to process other owners
continue
}
GetOwner(dclient, ownerMap, *owner)
}
}
func converLabelToSelector(labelMap map[string]string) (labels.Selector, error) {
ls := &metav1.LabelSelector{}
err := metav1.Convert_Map_string_To_string_To_v1_LabelSelector(&labelMap, ls, nil)

View file

@ -77,7 +77,6 @@ func (ds *dataStore) delete(keyHash string) {
//Info is a request to create PV
type Info struct {
Blocked bool
PolicyName string
Resource unstructured.Unstructured
Rules []kyverno.ViolatedRule
@ -85,7 +84,6 @@ type Info struct {
func (i Info) toKey() string {
keys := []string{
strconv.FormatBool(i.Blocked),
i.PolicyName,
i.Resource.GetKind(),
i.Resource.GetNamespace(),
@ -230,20 +228,17 @@ func (gen *Generator) syncHandler(info Info) error {
}
failure := false
// Generate Policy Violations
// as there can be multiple owners we can have multiple violations
pvs := builder.generate(info)
for _, pv := range pvs {
// Create Policy Violations
glog.V(3).Infof("Creating policy violation: %s", info.toKey())
err := handler.create(pv)
if err != nil {
failure = true
glog.V(3).Infof("Failed to create policy violation: %v", err)
} else {
glog.V(3).Infof("Policy violation created: %s", info.toKey())
}
pv := builder.generate(info)
// Create Policy Violations
glog.V(3).Infof("Creating policy violation: %s", info.toKey())
if err := handler.create(pv); err != nil {
failure = true
glog.V(3).Infof("Failed to create policy violation: %v", err)
} else {
glog.V(3).Infof("Policy violation created: %s", info.toKey())
}
if failure {
// even if there is a single failure we requeue the request
return errors.New("Failed to process some policy violations, re-queuing")

View file

@ -43,7 +43,7 @@ func getErrorMsg(engineReponses []response.EngineResponse) string {
if !er.IsSuccesful() {
// resource in engineReponses is identical as this was called per admission request
resourceInfo = fmt.Sprintf("%s/%s/%s", er.PolicyResponse.Resource.Kind, er.PolicyResponse.Resource.Namespace, er.PolicyResponse.Resource.Name)
str = append(str, fmt.Sprintf("failed policy %s", er.PolicyResponse.Policy))
str = append(str, fmt.Sprintf("failed policy %s:", er.PolicyResponse.Policy))
for _, rule := range er.PolicyResponse.Rules {
if !rule.Success {
str = append(str, rule.ToString())
@ -51,7 +51,7 @@ func getErrorMsg(engineReponses []response.EngineResponse) string {
}
}
}
return fmt.Sprintf("Resource %s: %s", resourceInfo, strings.Join(str, "\n"))
return fmt.Sprintf("Resource %s %s", resourceInfo, strings.Join(str, ";"))
}
//ArrayFlags to store filterkinds

View file

@ -1,12 +1,10 @@
package webhooks
import (
"fmt"
"strings"
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
"github.com/nirmata/kyverno/pkg/engine/response"
"github.com/nirmata/kyverno/pkg/policyviolation"
"github.com/golang/glog"
"github.com/nirmata/kyverno/pkg/event"
@ -105,57 +103,3 @@ func generateEvents(engineResponses []response.EngineResponse, onUpdate bool) []
}
return events
}
func generatePV(ers []response.EngineResponse, blocked bool) []policyviolation.Info {
var pvInfos []policyviolation.Info
// generate PV for each
for _, er := range ers {
// ignore creation of PV for resoruces that are yet to be assigned a name
if er.IsSuccesful() {
continue
}
glog.V(4).Infof("Building policy violation for engine response %v", er)
// build policy violation info
pvInfos = append(pvInfos, buildPVInfo(er, blocked))
}
return pvInfos
}
func buildPVInfo(er response.EngineResponse, blocked bool) policyviolation.Info {
info := policyviolation.Info{
Blocked: blocked,
PolicyName: er.PolicyResponse.Policy,
Resource: er.PatchedResource,
Rules: buildViolatedRules(er, blocked),
}
return info
}
func buildViolatedRules(er response.EngineResponse, blocked bool) []kyverno.ViolatedRule {
blockMsg := fmt.Sprintf("Request Blocked for resource %s/%s; ", er.PolicyResponse.Resource.Namespace, er.PolicyResponse.Resource.Kind)
var violatedRules []kyverno.ViolatedRule
// if resource was blocked we create dependent
dependant := kyverno.ManagedResourceSpec{
Kind: er.PolicyResponse.Resource.Kind,
CreationBlocked: true,
}
for _, rule := range er.PolicyResponse.Rules {
if rule.Success {
continue
}
vrule := kyverno.ViolatedRule{
Name: rule.Name,
Type: rule.Type,
}
if blocked {
vrule.Message = blockMsg + rule.Message
vrule.ManagedResource = dependant
} else {
vrule.Message = rule.Message
}
violatedRules = append(violatedRules, vrule)
}
return violatedRules
}

View file

@ -10,6 +10,7 @@ import (
"github.com/nirmata/kyverno/pkg/engine/context"
"github.com/nirmata/kyverno/pkg/engine/response"
policyctr "github.com/nirmata/kyverno/pkg/policy"
"github.com/nirmata/kyverno/pkg/policyviolation"
"github.com/nirmata/kyverno/pkg/utils"
v1beta1 "k8s.io/api/admission/v1beta1"
)
@ -99,20 +100,17 @@ func (ws *WebhookServer) HandleValidation(request *v1beta1.AdmissionRequest, pol
// If Validation fails then reject the request
// no violations will be created on "enforce"
// event will be reported on "owner"
// the event will be reported on owner by k8s
blocked := toBlockResource(engineResponses)
if blocked {
glog.V(4).Infof("resource %s/%s/%s is blocked\n", newR.GetKind(), newR.GetNamespace(), newR.GetName())
// ADD EVENTS
events := generateEvents(engineResponses, (request.Operation == v1beta1.Update))
ws.eventGen.Add(events...)
sendStat(true)
return false, getErrorMsg(engineResponses)
}
// ADD POLICY VIOLATIONS
// violations are created with resource on "audit"
pvInfos := generatePV(engineResponses, blocked)
pvInfos := policyviolation.GeneratePVsFromEngineResponse(engineResponses)
ws.pvGenerator.Add(pvInfos...)
// ADD EVENTS
events := generateEvents(engineResponses, (request.Operation == v1beta1.Update))