62 lines
1.7 KiB
Go
62 lines
1.7 KiB
Go
/*
|
|
* Please refer to the LICENSE file in the root directory of the project.
|
|
* https://github.com/kubesphere/kubesphere/blob/master/LICENSE
|
|
*/
|
|
|
|
package resourceprotection
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
admissionv1 "k8s.io/api/admission/v1"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
|
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
|
|
|
"kubesphere.io/kubesphere/pkg/constants"
|
|
kscontroller "kubesphere.io/kubesphere/pkg/controller"
|
|
)
|
|
|
|
const webhookName = "resource-protection-webhook"
|
|
|
|
func (w *Webhook) Name() string {
|
|
return webhookName
|
|
}
|
|
|
|
type Webhook struct {
|
|
client.Client
|
|
}
|
|
|
|
func (w *Webhook) SetupWithManager(mgr *kscontroller.Manager) error {
|
|
w.Client = mgr.GetClient()
|
|
mgr.GetWebhookServer().Register("/resource-protector", &webhook.Admission{Handler: w})
|
|
return nil
|
|
}
|
|
|
|
func (w *Webhook) Handle(ctx context.Context, req admission.Request) admission.Response {
|
|
if req.Operation == admissionv1.Delete {
|
|
gvr := req.RequestResource
|
|
gvk, err := w.RESTMapper().KindFor(schema.GroupVersionResource{
|
|
Group: gvr.Group,
|
|
Version: gvr.Version,
|
|
Resource: gvr.Resource,
|
|
})
|
|
if err != nil {
|
|
return webhook.Errored(http.StatusInternalServerError, err)
|
|
}
|
|
obj := &unstructured.Unstructured{}
|
|
obj.SetGroupVersionKind(gvk)
|
|
if err = w.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: req.Name}, obj); err != nil {
|
|
return webhook.Errored(http.StatusInternalServerError, err)
|
|
}
|
|
|
|
if obj.GetLabels()[constants.ProtectedResourceLabel] == "true" {
|
|
return webhook.Denied("this resource may not be deleted")
|
|
}
|
|
}
|
|
return admission.Allowed("")
|
|
}
|