From b66c1b7f0cb51e381956d2217c528b0e1b79abaa Mon Sep 17 00:00:00 2001
From: shivkumar dudhani <shivkumar@nirmata.com>
Date: Wed, 4 Sep 2019 10:40:49 -0700
Subject: [PATCH 1/5] remove exlude kind checks

---
 pkg/namespace/utils.go | 48 ------------------------------------------
 pkg/webhooks/report.go | 44 --------------------------------------
 pkg/webhooks/utils.go  | 45 +--------------------------------------
 3 files changed, 1 insertion(+), 136 deletions(-)

diff --git a/pkg/namespace/utils.go b/pkg/namespace/utils.go
index ee0922fc44..6f648e8344 100644
--- a/pkg/namespace/utils.go
+++ b/pkg/namespace/utils.go
@@ -4,52 +4,4 @@ const (
 	wqNamespace  string = "namespace"
 	workerCount  int    = 1
 	wqRetryLimit int    = 5
-	policyKind   string = "Policy"
 )
-
-// func namespaceMeetsRuleDescription(ns *corev1.Namespace, resourceDescription v1alpha1.ResourceDescription) bool {
-// 	//REWORK Not needed but verify the 'Namespace' is defined in the list of supported kinds
-// 	if !findKind(resourceDescription.Kinds, "Namespace") {
-// 		return false
-// 	}
-// 	if resourceDescription.Name != nil {
-// 		if !wildcard.Match(*resourceDescription.Name, ns.Name) {
-// 			return false
-// 		}
-// 	}
-
-// 	if resourceDescription.Selector != nil {
-// 		selector, err := metav1.LabelSelectorAsSelector(resourceDescription.Selector)
-// 		if err != nil {
-// 			return false
-// 		}
-
-// 		labelSet := convertLabelsToLabelSet(ns.Labels)
-// 		// labels
-// 		if !selector.Matches(labelSet) {
-// 			return false
-// 		}
-// 	}
-// 	return true
-// }
-
-// func convertLabelsToLabelSet(labelMap map[string]string) labels.Set {
-// 	labelSet := make(labels.Set, len(labelMap))
-// 	// REWORK: check if the below works
-// 	// if x, ok := labelMap.(labels.Set); !ok {
-
-// 	// }
-// 	for k, v := range labelMap {
-// 		labelSet[k] = v
-// 	}
-// 	return labelSet
-// }
-
-// func findKind(kinds []string, kindGVK string) bool {
-// 	for _, kind := range kinds {
-// 		if kind == kindGVK {
-// 			return true
-// 		}
-// 	}
-// 	return false
-// }
diff --git a/pkg/webhooks/report.go b/pkg/webhooks/report.go
index a5fc8ef080..ab446254ca 100644
--- a/pkg/webhooks/report.go
+++ b/pkg/webhooks/report.go
@@ -94,47 +94,3 @@ func generateEvents(engineResponses []engine.EngineResponseNew, onUpdate bool) [
 	}
 	return events
 }
-
-// //TODO: change validation from bool -> enum(validation, mutation)
-// func newEventInfoFromPolicyInfo(policyInfoList []info.PolicyInfo, onUpdate bool, ruleType info.RuleType) []*event.Info {
-// 	var eventsInfo []*event.Info
-// 	ok, msg := isAdmSuccesful(policyInfoList)
-// 	// Some policies failed to apply succesfully
-// 	if !ok {
-// 		for _, pi := range policyInfoList {
-// 			if pi.IsSuccessful() {
-// 				continue
-// 			}
-// 			rules := pi.FailedRules()
-// 			ruleNames := strings.Join(rules, ";")
-// 			if !onUpdate {
-// 				// CREATE
-// 				eventsInfo = append(eventsInfo,
-// 					event.NewEvent(policyKind, "", pi.Name, event.RequestBlocked, event.FPolicyApplyBlockCreate, pi.RNamespace+"/"+pi.RName, ruleNames))
-
-// 				glog.V(3).Infof("Rule(s) %s of policy %s blocked resource creation, error: %s\n", ruleNames, pi.Name, msg)
-// 			} else {
-// 				// UPDATE
-// 				eventsInfo = append(eventsInfo,
-// 					event.NewEvent(pi.RKind, pi.RNamespace, pi.RName, event.RequestBlocked, event.FPolicyApplyBlockUpdate, ruleNames, pi.Name))
-// 				eventsInfo = append(eventsInfo,
-// 					event.NewEvent(policyKind, "", pi.Name, event.RequestBlocked, event.FPolicyBlockResourceUpdate, pi.RNamespace+"/"+pi.RName, ruleNames))
-// 				glog.V(3).Infof("Request blocked events info has prepared for %s/%s and %s/%s\n", policyKind, pi.Name, pi.RKind, pi.RName)
-// 			}
-// 		}
-// 	} else {
-// 		if !onUpdate {
-// 			// All policies were applied succesfully
-// 			// CREATE
-// 			for _, pi := range policyInfoList {
-// 				rules := pi.SuccessfulRules()
-// 				ruleNames := strings.Join(rules, ";")
-// 				eventsInfo = append(eventsInfo,
-// 					event.NewEvent(pi.RKind, pi.RNamespace, pi.RName, event.PolicyApplied, event.SRulesApply, ruleNames, pi.Name))
-
-// 				glog.V(3).Infof("Success event info has prepared for %s/%s\n", pi.RKind, pi.RName)
-// 			}
-// 		}
-// 	}
-// 	return eventsInfo
-// }
diff --git a/pkg/webhooks/utils.go b/pkg/webhooks/utils.go
index c7dcac6d8b..5c658553ce 100644
--- a/pkg/webhooks/utils.go
+++ b/pkg/webhooks/utils.go
@@ -9,23 +9,6 @@ import (
 	"github.com/nirmata/kyverno/pkg/engine"
 )
 
-const policyKind = "Policy"
-
-// func isAdmSuccesful(policyInfos []info.PolicyInfo) (bool, string) {
-// 	var admSuccess = true
-// 	var errMsgs []string
-// 	for _, pi := range policyInfos {
-// 		if !pi.IsSuccessful() {
-// 			admSuccess = false
-// 			errMsgs = append(errMsgs, fmt.Sprintf("\nPolicy %s failed with following rules", pi.Name))
-// 			// Get the error rules
-// 			errorRules := pi.ErrorRules()
-// 			errMsgs = append(errMsgs, errorRules)
-// 		}
-// 	}
-// 	return admSuccess, strings.Join(errMsgs, ";")
-// }
-
 func isResponseSuccesful(engineReponses []engine.EngineResponseNew) bool {
 	for _, er := range engineReponses {
 		if !er.IsSuccesful() {
@@ -82,26 +65,13 @@ func (i *ArrayFlags) Set(value string) error {
 
 // extract the kinds that the policy rules apply to
 func getApplicableKindsForPolicy(p *kyverno.ClusterPolicy) []string {
-	kindsMap := map[string]interface{}{}
 	kinds := []string{}
 	// iterate over the rules an identify all kinds
 	// Matching
 	for _, rule := range p.Spec.Rules {
 		for _, k := range rule.MatchResources.Kinds {
-			kindsMap[k] = nil
+			kinds = append(kinds, k)
 		}
-		// remove excluded ones
-		for _, k := range rule.ExcludeResources.Kinds {
-			if _, ok := kindsMap[k]; ok {
-				// delete kind
-				delete(kindsMap, k)
-			}
-		}
-	}
-
-	// get the kinds
-	for k := range kindsMap {
-		kinds = append(kinds, k)
 	}
 	return kinds
 }
@@ -112,19 +82,6 @@ const (
 	ReportViolation = "audit"
 )
 
-// // returns true -> if there is even one policy that blocks resource requst
-// // returns false -> if all the policies are meant to report only, we dont block resource request
-// func toBlock(pis []info.PolicyInfo) bool {
-// 	for _, pi := range pis {
-// 		if pi.ValidationFailureAction != ReportViolation {
-// 			glog.V(3).Infoln("ValidationFailureAction set to enforce, blocking resource ceation")
-// 			return true
-// 		}
-// 	}
-// 	glog.V(3).Infoln("ValidationFailureAction set to audit, allowing resource creation, reporting with violation")
-// 	return false
-// }
-
 func processResourceWithPatches(patch []byte, resource []byte) []byte {
 	if patch == nil {
 		return nil

From c2e822c887303f2a3adf32fb599512f85bec648e Mon Sep 17 00:00:00 2001
From: shivkumar dudhani <shivkumar@nirmata.com>
Date: Wed, 4 Sep 2019 13:43:12 -0700
Subject: [PATCH 2/5] refactor webhook configuration

---
 pkg/config/config.go              | 18 +++----
 pkg/policy/controller.go          | 69 +++-----------------------
 pkg/policy/webhookregistration.go | 71 +++++++++++++++++++++++++++
 pkg/webhookconfig/policy.go       | 12 ++---
 pkg/webhookconfig/registration.go | 80 ++++++++++++++++---------------
 pkg/webhookconfig/resource.go     | 33 ++++++++++---
 pkg/webhooks/policyvalidation.go  | 19 +++++++-
 pkg/webhooks/webhookManager.go    | 74 ----------------------------
 8 files changed, 176 insertions(+), 200 deletions(-)
 create mode 100644 pkg/policy/webhookregistration.go
 delete mode 100644 pkg/webhooks/webhookManager.go

diff --git a/pkg/config/config.go b/pkg/config/config.go
index 5052be504f..130e7c7f6d 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -7,13 +7,13 @@ const (
 	KubePolicyNamespace = "kyverno"
 	WebhookServiceName  = "kyverno-svc"
 
-	MutatingWebhookConfigurationName  = "kyverno-mutating-webhook-cfg"
-	MutatingWebhookConfigurationDebug = "kyverno-mutating-webhook-cfg-debug"
-	MutatingWebhookName               = "nirmata.kyverno.mutating-webhook"
+	MutatingWebhookConfigurationName      = "kyverno-resource-mutating-webhook-cfg"
+	MutatingWebhookConfigurationDebugName = "kyverno-resource-mutating-webhook-cfg-debug"
+	MutatingWebhookName                   = "nirmata.kyverno.resource.mutating-webhook"
 
-	ValidatingWebhookConfigurationName  = "kyverno-validating-webhook-cfg"
-	ValidatingWebhookConfigurationDebug = "kyverno-validating-webhook-cfg-debug"
-	ValidatingWebhookName               = "nirmata.kyverno.policy-validating-webhook"
+	// ValidatingWebhookConfigurationName  = "kyverno-validating-webhook-cfg"
+	// ValidatingWebhookConfigurationDebug = "kyverno-validating-webhook-cfg-debug"
+	// ValidatingWebhookName               = "nirmata.kyverno.policy-validating-webhook"
 
 	PolicyValidatingWebhookConfigurationName      = "kyverno-policy-validating-webhook-cfg"
 	PolicyValidatingWebhookConfigurationDebugName = "kyverno-policy-validating-webhook-cfg-debug"
@@ -36,9 +36,9 @@ var (
 	ValidatingWebhookServicePath       = "/validate"
 	PolicyValidatingWebhookServicePath = "/policyvalidate"
 	PolicyMutatingWebhookServicePath   = "/policymutate"
-	KubePolicyAppLabels                = map[string]string{
-		"app": "kyverno",
-	}
+	// KubePolicyAppLabels                = map[string]string{
+	// 	"app": "kyverno",
+	// }
 
 	SupportedKinds = []string{
 		"ConfigMap",
diff --git a/pkg/policy/controller.go b/pkg/policy/controller.go
index 9cc4b377fe..35f5eb45b8 100644
--- a/pkg/policy/controller.go
+++ b/pkg/policy/controller.go
@@ -13,7 +13,6 @@ import (
 	"github.com/nirmata/kyverno/pkg/client/clientset/versioned/scheme"
 	kyvernoinformer "github.com/nirmata/kyverno/pkg/client/informers/externalversions/kyverno/v1alpha1"
 	kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1alpha1"
-	"github.com/nirmata/kyverno/pkg/config"
 	client "github.com/nirmata/kyverno/pkg/dclient"
 	"github.com/nirmata/kyverno/pkg/event"
 	"github.com/nirmata/kyverno/pkg/utils"
@@ -409,17 +408,21 @@ func (pc *PolicyController) syncPolicy(key string) error {
 		// remove the recorded stats for the policy
 		pc.statusAggregator.RemovePolicyStats(key)
 		// remove webhook configurations if there are not policies
-		if err := pc.handleWebhookRegistration(true, nil); err != nil {
+		if err := pc.removeResourceWebhookConfiguration(); err != nil {
+			// do not fail, if unable to delete resource webhook config
+			glog.V(4).Info("failed to remove resource webhook configuration: %v", err)
 			glog.Errorln(err)
 		}
 		return nil
 	}
 
 	if err != nil {
+		glog.V(4).Info(err)
 		return err
 	}
 
-	if err := pc.handleWebhookRegistration(false, policy); err != nil {
+	if err := pc.createResourceMutatingWebhookConfigurationIfRequired(*policy); err != nil {
+		glog.V(4).Infof("failed to create resource mutating webhook configurations, policies wont be applied on resources: %v", err)
 		glog.Errorln(err)
 	}
 
@@ -440,47 +443,6 @@ func (pc *PolicyController) syncPolicy(key string) error {
 	return pc.syncStatusOnly(p, pvList)
 }
 
-// TODO: here checks mutatingwebhook only
-// as 'kubectl scale' is not funtional with validatingwebhook
-// refer to https://github.com/nirmata/kyverno/issues/250
-func (pc *PolicyController) handleWebhookRegistration(delete bool, policy *kyverno.ClusterPolicy) error {
-	policies, _ := pc.pLister.List(labels.NewSelector())
-	selector := &metav1.LabelSelector{MatchLabels: config.KubePolicyAppLabels}
-	webhookSelector, err := metav1.LabelSelectorAsSelector(selector)
-	if err != nil {
-		return fmt.Errorf("invalid label selector: %v", err)
-	}
-
-	webhookList, err := pc.mutationwebhookLister.List(webhookSelector)
-	if err != nil {
-		return fmt.Errorf("failed to list mutatingwebhookconfigurations, err %v", err)
-	}
-
-	if delete {
-		if webhookList == nil {
-			return nil
-		}
-
-		// webhook exist, deregister webhookconfigurations on condition
-		// check empty policy first, then rule type in terms of O(time)
-		if policies == nil {
-			glog.V(3).Infoln("No policy found in the cluster, deregistering webhook")
-			pc.webhookRegistrationClient.RemoveResourceMutatingWebhookConfiguration()
-		} else if !HasMutateOrValidatePolicies(policies) {
-			glog.V(3).Infoln("No muatate/validate policy found in the cluster, deregistering webhook")
-			pc.webhookRegistrationClient.RemoveResourceMutatingWebhookConfiguration()
-		}
-		return nil
-	}
-
-	if webhookList == nil && HasMutateOrValidate(*policy) {
-		glog.V(3).Infoln("Found policy without mutatingwebhook, registering webhook")
-		pc.webhookRegistrationClient.CreateResourceMutatingWebhookConfiguration()
-	}
-
-	return nil
-}
-
 //syncStatusOnly updates the policy status subresource
 // status:
 // 		- violations : (count of the resources that violate this policy )
@@ -930,22 +892,3 @@ func joinPatches(patches ...[]byte) []byte {
 	result = append(result, []byte("\n]")...)
 	return result
 }
-
-func HasMutateOrValidatePolicies(policies []*kyverno.ClusterPolicy) bool {
-	for _, policy := range policies {
-		if HasMutateOrValidate(*policy) {
-			return true
-		}
-	}
-	return false
-}
-
-func HasMutateOrValidate(policy kyverno.ClusterPolicy) bool {
-	for _, rule := range policy.Spec.Rules {
-		if !reflect.DeepEqual(rule.Mutation, kyverno.Mutation{}) || !reflect.DeepEqual(rule.Validation, kyverno.Validation{}) {
-			glog.Infoln(rule.Name)
-			return true
-		}
-	}
-	return false
-}
diff --git a/pkg/policy/webhookregistration.go b/pkg/policy/webhookregistration.go
new file mode 100644
index 0000000000..4883cfb8de
--- /dev/null
+++ b/pkg/policy/webhookregistration.go
@@ -0,0 +1,71 @@
+package policy
+
+import (
+	"reflect"
+
+	"github.com/golang/glog"
+	kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
+	"k8s.io/apimachinery/pkg/labels"
+)
+
+func (pc *PolicyController) removeResourceWebhookConfiguration() error {
+	removeWebhookConfig := func() error {
+		var err error
+		err = pc.webhookRegistrationClient.RemoveResourceMutatingWebhookConfiguration()
+		if err != nil {
+			return err
+		}
+		glog.V(4).Info("removed resource webhook configuration")
+		return nil
+	}
+
+	var err error
+	// get all existing policies
+	policies, err := pc.pLister.List(labels.NewSelector())
+	if err != nil {
+		glog.V(4).Infof("failed to list policies: %v", err)
+		return err
+	}
+
+	if len(policies) == 0 {
+		glog.V(4).Info("no policies loaded, removing resource webhook configuration if one exists")
+		return removeWebhookConfig()
+	}
+
+	// if there are policies, check if they contain mutating or validating rule
+	if !hasMutateOrValidatePolicies(policies) {
+		glog.V(4).Info("no policies with mutating or validating webhook configurations, remove resource webhook configuration if one exists")
+		return removeWebhookConfig()
+	}
+
+	return nil
+}
+
+func (pc *PolicyController) createResourceMutatingWebhookConfigurationIfRequired(policy kyverno.ClusterPolicy) error {
+	// if the policy contains mutating & validation rules and it config does not exist we create one
+	if hasMutateOrValidate(policy) {
+		if err := pc.webhookRegistrationClient.CreateResourceMutatingWebhookConfiguration(); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func hasMutateOrValidatePolicies(policies []*kyverno.ClusterPolicy) bool {
+	for _, policy := range policies {
+		if hasMutateOrValidate(*policy) {
+			return true
+		}
+	}
+	return false
+}
+
+func hasMutateOrValidate(policy kyverno.ClusterPolicy) bool {
+	for _, rule := range policy.Spec.Rules {
+		if !reflect.DeepEqual(rule.Mutation, kyverno.Mutation{}) || !reflect.DeepEqual(rule.Validation, kyverno.Validation{}) {
+			glog.Infoln(rule.Name)
+			return true
+		}
+	}
+	return false
+}
diff --git a/pkg/webhookconfig/policy.go b/pkg/webhookconfig/policy.go
index e434b52c30..60a7b5bfae 100644
--- a/pkg/webhookconfig/policy.go
+++ b/pkg/webhookconfig/policy.go
@@ -13,8 +13,7 @@ func (wrc *WebhookRegistrationClient) contructPolicyValidatingWebhookConfig(caDa
 
 	return &admregapi.ValidatingWebhookConfiguration{
 		ObjectMeta: v1.ObjectMeta{
-			Name:   config.PolicyValidatingWebhookConfigurationName,
-			Labels: config.KubePolicyAppLabels,
+			Name: config.PolicyValidatingWebhookConfigurationName,
 			OwnerReferences: []v1.OwnerReference{
 				wrc.constructOwner(),
 			},
@@ -41,8 +40,7 @@ func (wrc *WebhookRegistrationClient) contructDebugPolicyValidatingWebhookConfig
 
 	return &admregapi.ValidatingWebhookConfiguration{
 		ObjectMeta: v1.ObjectMeta{
-			Name:   config.PolicyValidatingWebhookConfigurationDebugName,
-			Labels: config.KubePolicyAppLabels,
+			Name: config.PolicyValidatingWebhookConfigurationDebugName,
 		},
 		Webhooks: []admregapi.Webhook{
 			generateDebugWebhook(
@@ -63,8 +61,7 @@ func (wrc *WebhookRegistrationClient) contructDebugPolicyValidatingWebhookConfig
 func (wrc *WebhookRegistrationClient) contructPolicyMutatingWebhookConfig(caData []byte) *admregapi.MutatingWebhookConfiguration {
 	return &admregapi.MutatingWebhookConfiguration{
 		ObjectMeta: v1.ObjectMeta{
-			Name:   config.PolicyMutatingWebhookConfigurationName,
-			Labels: config.KubePolicyAppLabels,
+			Name: config.PolicyMutatingWebhookConfigurationName,
 			OwnerReferences: []v1.OwnerReference{
 				wrc.constructOwner(),
 			},
@@ -90,8 +87,7 @@ func (wrc *WebhookRegistrationClient) contructDebugPolicyMutatingWebhookConfig(c
 
 	return &admregapi.MutatingWebhookConfiguration{
 		ObjectMeta: v1.ObjectMeta{
-			Name:   config.PolicyMutatingWebhookConfigurationDebugName,
-			Labels: config.KubePolicyAppLabels,
+			Name: config.PolicyMutatingWebhookConfigurationDebugName,
 		},
 		Webhooks: []admregapi.Webhook{
 			generateDebugWebhook(
diff --git a/pkg/webhookconfig/registration.go b/pkg/webhookconfig/registration.go
index a8f036484e..2511a13167 100644
--- a/pkg/webhookconfig/registration.go
+++ b/pkg/webhookconfig/registration.go
@@ -7,7 +7,6 @@ import (
 	"github.com/golang/glog"
 	"github.com/nirmata/kyverno/pkg/config"
 	client "github.com/nirmata/kyverno/pkg/dclient"
-	"github.com/tevino/abool"
 	admregapi "k8s.io/api/admissionregistration/v1beta1"
 	errorsapi "k8s.io/apimachinery/pkg/api/errors"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -21,10 +20,8 @@ type WebhookRegistrationClient struct {
 	client             *client.Client
 	clientConfig       *rest.Config
 	// serverIP should be used if running Kyverno out of clutser
-	serverIP             string
-	timeoutSeconds       int32
-	MutationRegistered   *abool.AtomicBool
-	ValidationRegistered *abool.AtomicBool
+	serverIP       string
+	timeoutSeconds int32
 }
 
 // NewWebhookRegistrationClient creates new WebhookRegistrationClient instance
@@ -34,16 +31,14 @@ func NewWebhookRegistrationClient(clientConfig *rest.Config, client *client.Clie
 		return nil, err
 	}
 
-	glog.V(3).Infof("Registering webhook client using serverIP %s\n", serverIP)
+	glog.V(4).Infof("Registering webhook client using serverIP %s\n", serverIP)
 
 	return &WebhookRegistrationClient{
-		registrationClient:   registrationClient,
-		client:               client,
-		clientConfig:         clientConfig,
-		serverIP:             serverIP,
-		timeoutSeconds:       webhookTimeout,
-		MutationRegistered:   abool.New(),
-		ValidationRegistered: abool.New(),
+		registrationClient: registrationClient,
+		client:             client,
+		clientConfig:       clientConfig,
+		serverIP:           serverIP,
+		timeoutSeconds:     webhookTimeout,
 	}, nil
 }
 
@@ -104,14 +99,30 @@ func (wrc *WebhookRegistrationClient) CreateResourceMutatingWebhookConfiguration
 		config = wrc.constructMutatingWebhookConfig(caData)
 	}
 
-	if _, err := wrc.registrationClient.MutatingWebhookConfigurations().Create(config); err != nil {
+	_, err := wrc.registrationClient.MutatingWebhookConfigurations().Create(config)
+	if errorsapi.IsAlreadyExists(err) {
+		glog.V(4).Infof("resource mutating webhook configuration %s, already exists. not creating one", config.Name)
+		return nil
+	}
+	if err != nil {
+		glog.V(4).Infof("failed to create resource mutating webhook configuration %s: %v", config.Name, err)
 		return err
 	}
-
-	wrc.MutationRegistered.Set()
 	return nil
 }
 
+//GetResourceMutatingWebhookConfiguration returns the MutatingWebhookConfiguration
+func (wrc *WebhookRegistrationClient) GetResourceMutatingWebhookConfiguration() (*admregapi.MutatingWebhookConfiguration, error) {
+	var name string
+	if wrc.serverIP != "" {
+		name = config.MutatingWebhookConfigurationDebugName
+	} else {
+		name = config.MutatingWebhookConfigurationName
+	}
+
+	return wrc.registrationClient.MutatingWebhookConfigurations().Get(name, v1.GetOptions{})
+}
+
 //registerPolicyValidatingWebhookConfiguration create a Validating webhook configuration for Policy CRD
 func (wrc *WebhookRegistrationClient) createPolicyValidatingWebhookConfiguration() error {
 	var caData []byte
@@ -193,6 +204,7 @@ func (wrc *WebhookRegistrationClient) removeWebhookConfigurations() {
 // webhookConfigurations are re-created later
 func (wrc *WebhookRegistrationClient) removePolicyWebhookConfigurations() {
 	// Validating webhook configuration
+	var err error
 	var validatingConfig string
 	if wrc.serverIP != "" {
 		validatingConfig = config.PolicyValidatingWebhookConfigurationDebugName
@@ -200,9 +212,13 @@ func (wrc *WebhookRegistrationClient) removePolicyWebhookConfigurations() {
 		validatingConfig = config.PolicyValidatingWebhookConfigurationName
 	}
 	glog.V(4).Infof("removing webhook configuration %s", validatingConfig)
-	err := wrc.registrationClient.ValidatingWebhookConfigurations().Delete(validatingConfig, &v1.DeleteOptions{})
-	if err != nil && !errorsapi.IsNotFound(err) {
-		glog.Error(err)
+	err = wrc.registrationClient.ValidatingWebhookConfigurations().Delete(validatingConfig, &v1.DeleteOptions{})
+	if errorsapi.IsNotFound(err) {
+		glog.V(4).Infof("policy webhook configuration %s, does not exits. not deleting", validatingConfig)
+	} else if err != nil {
+		glog.Errorf("failed to delete policy webhook configuration %s: %v", validatingConfig, err)
+	} else {
+		glog.V(4).Infof("succesfully deleted policy webhook configuration %s", validatingConfig)
 	}
 
 	// Mutating webhook configuration
@@ -214,24 +230,12 @@ func (wrc *WebhookRegistrationClient) removePolicyWebhookConfigurations() {
 	}
 
 	glog.V(4).Infof("removing webhook configuration %s", mutatingConfig)
-	if err := wrc.registrationClient.MutatingWebhookConfigurations().Delete(mutatingConfig, &v1.DeleteOptions{}); err != nil && !errorsapi.IsNotFound(err) {
-		glog.Error(err)
-	}
-}
-
-//RemoveResourceMutatingWebhookConfiguration removes mutating webhook configuration for all resources
-func (wrc *WebhookRegistrationClient) RemoveResourceMutatingWebhookConfiguration() {
-	var configName string
-	if wrc.serverIP != "" {
-		configName = config.MutatingWebhookConfigurationDebug
-	} else {
-		configName = config.MutatingWebhookConfigurationName
-	}
-	// delete webhook configuration
-	err := wrc.registrationClient.MutatingWebhookConfigurations().Delete(configName, &v1.DeleteOptions{})
-	if err != nil && !errorsapi.IsNotFound(err) {
-		glog.Error(err)
-	} else {
-		wrc.MutationRegistered.UnSet()
+	err = wrc.registrationClient.MutatingWebhookConfigurations().Delete(mutatingConfig, &v1.DeleteOptions{})
+	if errorsapi.IsNotFound(err) {
+		glog.V(4).Infof("policy webhook configuration %s, does not exits. not deleting", mutatingConfig)
+	} else if err != nil {
+		glog.Errorf("failed to delete policy webhook configuration %s: %v", mutatingConfig, err)
+	} else {
+		glog.V(4).Infof("succesfully deleted policy webhook configuration %s", mutatingConfig)
 	}
 }
diff --git a/pkg/webhookconfig/resource.go b/pkg/webhookconfig/resource.go
index 63d44d28d6..f86777cb82 100644
--- a/pkg/webhookconfig/resource.go
+++ b/pkg/webhookconfig/resource.go
@@ -6,6 +6,7 @@ import (
 	"github.com/golang/glog"
 	"github.com/nirmata/kyverno/pkg/config"
 	admregapi "k8s.io/api/admissionregistration/v1beta1"
+	"k8s.io/apimachinery/pkg/api/errors"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -15,8 +16,7 @@ func (wrc *WebhookRegistrationClient) contructDebugMutatingWebhookConfig(caData
 
 	return &admregapi.MutatingWebhookConfiguration{
 		ObjectMeta: v1.ObjectMeta{
-			Name:   config.MutatingWebhookConfigurationDebug,
-			Labels: config.KubePolicyAppLabels,
+			Name: config.MutatingWebhookConfigurationDebugName,
 		},
 		Webhooks: []admregapi.Webhook{
 			generateDebugWebhook(
@@ -28,7 +28,7 @@ func (wrc *WebhookRegistrationClient) contructDebugMutatingWebhookConfig(caData
 				"*/*",
 				"*",
 				"*",
-				[]admregapi.OperationType{admregapi.Create},
+				[]admregapi.OperationType{admregapi.Create, admregapi.Update},
 			),
 		},
 	}
@@ -37,8 +37,7 @@ func (wrc *WebhookRegistrationClient) contructDebugMutatingWebhookConfig(caData
 func (wrc *WebhookRegistrationClient) constructMutatingWebhookConfig(caData []byte) *admregapi.MutatingWebhookConfiguration {
 	return &admregapi.MutatingWebhookConfiguration{
 		ObjectMeta: v1.ObjectMeta{
-			Name:   config.MutatingWebhookConfigurationName,
-			Labels: config.KubePolicyAppLabels,
+			Name: config.MutatingWebhookConfigurationName,
 			OwnerReferences: []v1.OwnerReference{
 				wrc.constructOwner(),
 			},
@@ -53,8 +52,30 @@ func (wrc *WebhookRegistrationClient) constructMutatingWebhookConfig(caData []by
 				"*/*",
 				"*",
 				"*",
-				[]admregapi.OperationType{admregapi.Create},
+				[]admregapi.OperationType{admregapi.Create, admregapi.Update},
 			),
 		},
 	}
 }
+
+//RemoveResourceMutatingWebhookConfiguration removes mutating webhook configuration for all resources
+func (wrc *WebhookRegistrationClient) RemoveResourceMutatingWebhookConfiguration() error {
+	var configName string
+	if wrc.serverIP != "" {
+		configName = config.MutatingWebhookConfigurationDebugName
+	} else {
+		configName = config.MutatingWebhookConfigurationName
+	}
+	// delete webhook configuration
+	err := wrc.registrationClient.MutatingWebhookConfigurations().Delete(configName, &v1.DeleteOptions{})
+	if errors.IsNotFound(err) {
+		glog.V(4).Infof("resource webhook configuration %s does not exits, so not deleting", configName)
+		return nil
+	}
+	if err != nil {
+		glog.V(4).Infof("failed to delete resource webhook configuration %s: %v", configName, err)
+		return err
+	}
+	glog.V(4).Infof("deleted resource webhook configuration %s", configName)
+	return nil
+}
diff --git a/pkg/webhooks/policyvalidation.go b/pkg/webhooks/policyvalidation.go
index b63c659da4..0e54b64340 100644
--- a/pkg/webhooks/policyvalidation.go
+++ b/pkg/webhooks/policyvalidation.go
@@ -31,10 +31,25 @@ func (ws *WebhookServer) handlePolicyValidation(request *v1beta1.AdmissionReques
 	// check for uniqueness of rule names while CREATE/DELET
 	admissionResp = ws.validateUniqueRuleName(policy)
 
-	if admissionResp.Allowed {
-		ws.manageWebhookConfigurations(*policy, request.Operation)
+	// helper function to evaluate if policy has validtion or mutation rules defined
+	hasMutateOrValidate := func() bool {
+		for _, rule := range policy.Spec.Rules {
+			if !reflect.DeepEqual(rule.Mutation, kyverno.Mutation{}) || !reflect.DeepEqual(rule.Validation, kyverno.Validation{}) {
+				glog.Infoln(rule.Name)
+				return true
+			}
+		}
+		return false
 	}
 
+	if admissionResp.Allowed {
+		if hasMutateOrValidate() {
+			// create mutating resource mutatingwebhookconfiguration if not present
+			if err := ws.webhookRegistrationClient.CreateResourceMutatingWebhookConfiguration(); err != nil {
+				glog.Error("failed to created resource mutating webhook configuration, policies wont be applied on the resource")
+			}
+		}
+	}
 	return admissionResp
 }
 
diff --git a/pkg/webhooks/webhookManager.go b/pkg/webhooks/webhookManager.go
deleted file mode 100644
index 72a2020b0d..0000000000
--- a/pkg/webhooks/webhookManager.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package webhooks
-
-import (
-	"reflect"
-
-	"github.com/golang/glog"
-	kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1alpha1"
-	v1beta1 "k8s.io/api/admission/v1beta1"
-	"k8s.io/apimachinery/pkg/labels"
-)
-
-type policyType int
-
-const (
-	none policyType = iota
-	mutate
-	validate
-	all
-)
-
-func (ws *WebhookServer) manageWebhookConfigurations(policy kyverno.ClusterPolicy, op v1beta1.Operation) {
-	switch op {
-	case v1beta1.Create:
-		ws.registerWebhookConfigurations(policy)
-	case v1beta1.Delete:
-		ws.deregisterWebhookConfigurations(policy)
-	}
-}
-
-func (ws *WebhookServer) registerWebhookConfigurations(policy kyverno.ClusterPolicy) error {
-	if !HasMutateOrValidate(policy) {
-		return nil
-	}
-
-	if !ws.webhookRegistrationClient.MutationRegistered.IsSet() {
-		if err := ws.webhookRegistrationClient.CreateResourceMutatingWebhookConfiguration(); err != nil {
-			return err
-		}
-		glog.Infof("Mutating webhook registered")
-	}
-
-	return nil
-}
-
-func (ws *WebhookServer) deregisterWebhookConfigurations(policy kyverno.ClusterPolicy) error {
-	policies, _ := ws.pLister.List(labels.NewSelector())
-
-	// deregister webhook if no mutate/validate policy found in cluster
-	if !HasMutateOrValidatePolicies(policies) {
-		ws.webhookRegistrationClient.RemoveResourceMutatingWebhookConfiguration()
-		glog.Infoln("Mutating webhook deregistered")
-	}
-
-	return nil
-}
-
-func HasMutateOrValidatePolicies(policies []*kyverno.ClusterPolicy) bool {
-	for _, policy := range policies {
-		if HasMutateOrValidate(*policy) {
-			return true
-		}
-	}
-	return false
-}
-
-func HasMutateOrValidate(policy kyverno.ClusterPolicy) bool {
-	for _, rule := range policy.Spec.Rules {
-		if !reflect.DeepEqual(rule.Mutation, kyverno.Mutation{}) || !reflect.DeepEqual(rule.Validation, kyverno.Validation{}) {
-			glog.V(4).Infoln(rule.Name)
-			return true
-		}
-	}
-	return false
-}

From 7a43bed8e447429479abcf534762331d3c1ba883 Mon Sep 17 00:00:00 2001
From: shivkumar dudhani <shivkumar@nirmata.com>
Date: Wed, 4 Sep 2019 14:06:06 -0700
Subject: [PATCH 3/5] remove commented code + fix log param

---
 pkg/config/config.go     | 3 ---
 pkg/policy/controller.go | 3 +--
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/pkg/config/config.go b/pkg/config/config.go
index 130e7c7f6d..0fc8a9fe48 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -36,9 +36,6 @@ var (
 	ValidatingWebhookServicePath       = "/validate"
 	PolicyValidatingWebhookServicePath = "/policyvalidate"
 	PolicyMutatingWebhookServicePath   = "/policymutate"
-	// KubePolicyAppLabels                = map[string]string{
-	// 	"app": "kyverno",
-	// }
 
 	SupportedKinds = []string{
 		"ConfigMap",
diff --git a/pkg/policy/controller.go b/pkg/policy/controller.go
index 3938ea50d0..a29a91e4cd 100644
--- a/pkg/policy/controller.go
+++ b/pkg/policy/controller.go
@@ -410,7 +410,7 @@ func (pc *PolicyController) syncPolicy(key string) error {
 		// remove webhook configurations if there are not policies
 		if err := pc.removeResourceWebhookConfiguration(); err != nil {
 			// do not fail, if unable to delete resource webhook config
-			glog.V(4).Info("failed to remove resource webhook configuration: %v", err)
+			glog.V(4).Infof("failed to remove resource webhook configuration: %v", err)
 			glog.Errorln(err)
 		}
 		return nil
@@ -911,4 +911,3 @@ func convertRules(rules []RuleStatinfo) []kyverno.RuleStats {
 	}
 	return stats
 }
-

From 90a7282b978506fdb40e9b6a6516c2c80b7acd3f Mon Sep 17 00:00:00 2001
From: shivkumar dudhani <shivkumar@nirmata.com>
Date: Wed, 4 Sep 2019 14:09:42 -0700
Subject: [PATCH 4/5] remove log

---
 pkg/webhooks/policyvalidation.go | 1 -
 1 file changed, 1 deletion(-)

diff --git a/pkg/webhooks/policyvalidation.go b/pkg/webhooks/policyvalidation.go
index 0e54b64340..6a047a9c5d 100644
--- a/pkg/webhooks/policyvalidation.go
+++ b/pkg/webhooks/policyvalidation.go
@@ -35,7 +35,6 @@ func (ws *WebhookServer) handlePolicyValidation(request *v1beta1.AdmissionReques
 	hasMutateOrValidate := func() bool {
 		for _, rule := range policy.Spec.Rules {
 			if !reflect.DeepEqual(rule.Mutation, kyverno.Mutation{}) || !reflect.DeepEqual(rule.Validation, kyverno.Validation{}) {
-				glog.Infoln(rule.Name)
 				return true
 			}
 		}

From 973abe6233c79f60148dff3fe0a8b7827049f3d5 Mon Sep 17 00:00:00 2001
From: shivkumar dudhani <shivkumar@nirmata.com>
Date: Wed, 4 Sep 2019 15:30:09 -0700
Subject: [PATCH 5/5] ignore creationg of event and PV if Name is not assgined.

---
 pkg/event/controller.go        | 7 ++++++-
 pkg/policyviolation/helpers.go | 5 +++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/pkg/event/controller.go b/pkg/event/controller.go
index 2a5f3cb3ef..ac66f7356d 100644
--- a/pkg/event/controller.go
+++ b/pkg/event/controller.go
@@ -71,6 +71,12 @@ func initRecorder(client *client.Client) record.EventRecorder {
 //Add queues an event for generation
 func (gen *Generator) Add(infos ...Info) {
 	for _, info := range infos {
+		if info.Name == "" {
+			// dont create event for resources with generateName
+			// as the name is not generated yet
+			glog.V(4).Infof("recieved info %v, not creating an event as the resource has not been assigned a name yet", info)
+			continue
+		}
 		gen.queue.Add(info)
 	}
 }
@@ -140,7 +146,6 @@ func (gen *Generator) processNextWorkItem() bool {
 func (gen *Generator) syncHandler(key Info) error {
 	var robj runtime.Object
 	var err error
-
 	switch key.Kind {
 	case "Policy":
 		//TODO: policy is clustered resource so wont need namespace
diff --git a/pkg/policyviolation/helpers.go b/pkg/policyviolation/helpers.go
index cd7a6b36b3..d96f654a02 100644
--- a/pkg/policyviolation/helpers.go
+++ b/pkg/policyviolation/helpers.go
@@ -81,6 +81,11 @@ func buildPVForPolicy(er engine.EngineResponseNew) kyverno.ClusterPolicyViolatio
 func CreatePV(pvLister kyvernolister.ClusterPolicyViolationLister, client *kyvernoclient.Clientset, engineResponses []engine.EngineResponseNew) {
 	var pvs []kyverno.ClusterPolicyViolation
 	for _, er := range engineResponses {
+		// 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() {
 			if pv := buildPVForPolicy(er); !reflect.DeepEqual(pv, kyverno.ClusterPolicyViolation{}) {
 				pvs = append(pvs, pv)