mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-15 17:51:20 +00:00
refactor webhook configuration
This commit is contained in:
parent
b66c1b7f0c
commit
c2e822c887
8 changed files with 176 additions and 200 deletions
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
71
pkg/policy/webhookregistration.go
Normal file
71
pkg/policy/webhookregistration.go
Normal file
|
@ -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
|
||||
}
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in a new issue