1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-28 10:28:36 +00:00

implement deletion logic

This commit is contained in:
Shuting Zhao 2019-08-08 13:09:40 -07:00
parent 6c12a76ab2
commit a8acc9eb5a
4 changed files with 161 additions and 27 deletions

View file

@ -14,13 +14,27 @@ import (
//HandlePolicyValidation performs the validation check on policy resource
func (ws *WebhookServer) HandlePolicyValidation(request *v1beta1.AdmissionRequest) *v1beta1.AdmissionResponse {
var policy *policyv1.Policy
json.Unmarshal(request.Object.Raw, &policy)
admissionResp := &v1beta1.AdmissionResponse{
Allowed: true,
}
admissionResp := ws.validateUniqueRuleName(policy)
raw := request.Object.Raw
if request.Operation == v1beta1.Delete {
raw = request.OldObject.Raw
}
if err := json.Unmarshal(raw, &policy); err != nil {
glog.Errorf("Failed to unmarshal policy admission request, err %v\n", err)
return &v1beta1.AdmissionResponse{Allowed: false}
}
if request.Operation != v1beta1.Delete {
admissionResp = ws.validateUniqueRuleName(policy)
}
if admissionResp.Allowed {
ws.registerWebhookConfigurations(*policy)
ws.manageWebhookConfigurations(*policy, request.Operation)
}
return admissionResp
}

View file

@ -55,7 +55,7 @@ func (wrc *WebhookRegistrationClient) Register() error {
}
// For the case if cluster already has this configs
wrc.Deregister()
wrc.DeregisterAll()
// register policy validating webhook during inital start
return wrc.RegisterPolicyValidatingWebhook()
@ -71,6 +71,7 @@ func (wrc *WebhookRegistrationClient) RegisterMutatingWebhook() error {
return err
}
wrc.MutationRegistered.Set()
return nil
}
@ -84,6 +85,7 @@ func (wrc *WebhookRegistrationClient) RegisterValidatingWebhook() error {
return err
}
wrc.ValidationRegistered.Set()
return nil
}
@ -101,31 +103,66 @@ func (wrc *WebhookRegistrationClient) RegisterPolicyValidatingWebhook() error {
return nil
}
// Deregister deletes webhook configs from cluster
// DeregisterAll deletes webhook configs from cluster
// This function does not fail on error:
// Register will fail if the config exists, so there is no need to fail on error
func (wrc *WebhookRegistrationClient) Deregister() {
listOpt := v1.ListOptions{LabelSelector: "app=kyverno"}
func (wrc *WebhookRegistrationClient) DeregisterAll() {
wrc.deregisterMutatingWebhook()
wrc.deregisterValidatingWebhook()
// cleanup MutatingWebhookConfigurations
mutatingWebhookConfigList, _ := wrc.registrationClient.MutatingWebhookConfigurations().List(listOpt)
for _, mwc := range mutatingWebhookConfigList.Items {
if err := wrc.registrationClient.MutatingWebhookConfigurations().Delete(mwc.ObjectMeta.Name, &v1.DeleteOptions{}); err != nil {
glog.Errorf("Failed to delete mutatingWebhookConfiguration, %s, err: %v\n", mwc.ObjectMeta.Name, err)
if wrc.serverIP != "" {
err := wrc.registrationClient.ValidatingWebhookConfigurations().Delete(config.PolicyValidatingWebhookConfigurationDebug, &v1.DeleteOptions{})
if err != nil {
glog.Error(err)
}
}
// cleanup validatingWebhookConfiguratinos
validatingWebhookConfigList, _ := wrc.registrationClient.ValidatingWebhookConfigurations().List(listOpt)
for _, mwc := range validatingWebhookConfigList.Items {
if err := wrc.registrationClient.ValidatingWebhookConfigurations().Delete(mwc.ObjectMeta.Name, &v1.DeleteOptions{}); err != nil {
glog.Errorf("Failed to delete validatingWebhookConfiguration, %s, err: %v\n", mwc.ObjectMeta.Name, err)
}
err := wrc.registrationClient.ValidatingWebhookConfigurations().Delete(config.PolicyValidatingWebhookConfigurationName, &v1.DeleteOptions{})
if err != nil {
glog.Error(err)
}
}
func (wrc *WebhookRegistrationClient) deregister() {
wrc.deregisterMutatingWebhook()
wrc.deregisterValidatingWebhook()
}
func (wrc *WebhookRegistrationClient) deregisterMutatingWebhook() {
if wrc.serverIP != "" {
err := wrc.registrationClient.MutatingWebhookConfigurations().Delete(config.MutatingWebhookConfigurationDebug, &v1.DeleteOptions{})
if err != nil {
glog.Error(err)
} else {
wrc.MutationRegistered.UnSet()
}
return
}
err := wrc.registrationClient.MutatingWebhookConfigurations().Delete(config.MutatingWebhookConfigurationName, &v1.DeleteOptions{})
if err != nil {
glog.Error(err)
} else {
wrc.MutationRegistered.UnSet()
}
}
func (wrc *WebhookRegistrationClient) deregisterValidatingWebhook() {
if wrc.serverIP != "" {
err := wrc.registrationClient.ValidatingWebhookConfigurations().Delete(config.ValidatingWebhookConfigurationDebug, &v1.DeleteOptions{})
if err != nil {
glog.Error(err)
}
wrc.ValidationRegistered.UnSet()
return
}
err := wrc.registrationClient.ValidatingWebhookConfigurations().Delete(config.ValidatingWebhookConfigurationName, &v1.DeleteOptions{})
if err != nil {
glog.Error(err)
}
wrc.ValidationRegistered.UnSet()
}
func (wrc *WebhookRegistrationClient) constructMutatingWebhookConfig(configuration *rest.Config) (*admregapi.MutatingWebhookConfiguration, error) {
var caData []byte
// Check if ca is defined in the secret tls-ca

View file

@ -99,7 +99,7 @@ func (ws *WebhookServer) serve(w http.ResponseWriter, r *http.Request) {
if !utils.SkipFilteredResourcesReq(admissionReview.Request, ws.filterK8Resources) {
// if the resource is being deleted we need to clear any existing Policy Violations
// TODO: can report to the user that we clear the violation corresponding to this resource
if admissionReview.Request.Operation == v1beta1.Delete {
if admissionReview.Request.Operation == v1beta1.Delete && admissionReview.Request.Kind.Kind != policyKind {
// Resource DELETE
err := ws.removePolicyViolation(admissionReview.Request)
if err != nil {

View file

@ -3,17 +3,34 @@ package webhooks
import (
"github.com/golang/glog"
v1alpha1 "github.com/nirmata/kyverno/pkg/apis/policy/v1alpha1"
v1beta1 "k8s.io/api/admission/v1beta1"
"k8s.io/apimachinery/pkg/labels"
)
func (ws *WebhookServer) registerWebhookConfigurations(policy v1alpha1.Policy) error {
type policyType int
const (
none policyType = iota
mutate
validate
all
)
func (ws *WebhookServer) manageWebhookConfigurations(policy v1alpha1.Policy, op v1beta1.Operation) {
switch op {
case v1beta1.Create:
ws.registerWebhookConfigurations(policy)
case v1beta1.Delete:
ws.deregisterWebhookConfigurations(policy)
}
}
func (ws *WebhookServer) registerWebhookConfigurations(policy v1alpha1.Policy) error {
for _, rule := range policy.Spec.Rules {
if rule.Mutation != nil && !ws.webhookRegistrationClient.MutationRegistered.IsSet() {
if err := ws.webhookRegistrationClient.RegisterMutatingWebhook(); err != nil {
return err
}
ws.webhookRegistrationClient.MutationRegistered.Set()
glog.Infof("Mutating webhook registered")
}
@ -21,10 +38,76 @@ func (ws *WebhookServer) registerWebhookConfigurations(policy v1alpha1.Policy) e
if err := ws.webhookRegistrationClient.RegisterValidatingWebhook(); err != nil {
return err
}
ws.webhookRegistrationClient.ValidationRegistered.Set()
glog.Infof("Validating webhook registered")
}
}
return nil
}
func (ws *WebhookServer) deregisterWebhookConfigurations(policy v1alpha1.Policy) error {
pt := none
glog.V(3).Infof("Retreiving policy type for %s\n", policy.Name)
for _, rule := range policy.Spec.Rules {
if rule.Validation != nil {
pt = pt | validate
}
if rule.Mutation != nil {
pt = pt | mutate
}
}
glog.V(3).Infof("Scanning policy type==%v\n", pt)
existPolicyType := ws.isPolicyTypeExist(pt, policy.Name)
glog.V(3).Infof("Found existing policy type==%v\n", existPolicyType)
switch existPolicyType {
case none:
ws.webhookRegistrationClient.deregister()
glog.Infoln("All webhook deregistered")
case mutate:
if pt != mutate {
ws.webhookRegistrationClient.deregisterValidatingWebhook()
glog.Infoln("Validating webhook deregistered")
}
case validate:
if pt != validate {
ws.webhookRegistrationClient.deregisterMutatingWebhook()
glog.Infoln("Mutating webhook deregistered")
}
case all:
return nil
}
return nil
}
func (ws *WebhookServer) isPolicyTypeExist(pt policyType, policyName string) policyType {
ptype := none
policies, err := ws.policyLister.List(labels.NewSelector())
if err != nil {
glog.Errorf("Failed to get policy list")
}
for _, p := range policies {
if p.Name == policyName {
glog.Infof("Skipping policy type check on %s\n", policyName)
continue
}
for _, rule := range p.Spec.Rules {
if rule.Mutation != nil {
ptype = ptype | mutate
}
if rule.Validation != nil {
ptype = ptype | validate
}
}
}
return ptype
}