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:
parent
6c12a76ab2
commit
a8acc9eb5a
4 changed files with 161 additions and 27 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue