mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-08-19 04:26:45 +00:00
feat: grant global patch privileges and add patch handler
This commit is contained in:
committed by
Dario Tranchitella
parent
e0b339d68a
commit
cac2920827
@@ -269,6 +269,21 @@ func (in *NetworkPolicySpec) DeepCopy() *NetworkPolicySpec {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NonLimitedResourceError) DeepCopyInto(out *NonLimitedResourceError) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NonLimitedResourceError.
|
||||
func (in *NonLimitedResourceError) DeepCopy() *NonLimitedResourceError {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(NonLimitedResourceError)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in OwnerListSpec) DeepCopyInto(out *OwnerListSpec) {
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@ var (
|
||||
{
|
||||
APIGroups: []string{""},
|
||||
Resources: []string{"namespaces"},
|
||||
Verbs: []string{"create"},
|
||||
Verbs: []string{"create", "patch"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -51,7 +51,7 @@ require (
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 // indirect
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
||||
|
||||
@@ -696,6 +696,8 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
|
||||
|
||||
@@ -198,7 +198,7 @@ func main() {
|
||||
webhooksList := append(
|
||||
make([]webhook.Webhook, 0),
|
||||
route.Pod(pod.ImagePullPolicy(), pod.ContainerRegistry(), pod.PriorityClass()),
|
||||
route.Namespace(utils.InCapsuleGroups(cfg, namespacewebhook.QuotaHandler(), namespacewebhook.FreezeHandler(cfg), namespacewebhook.PrefixHandler(cfg), namespacewebhook.UserMetadataHandler())),
|
||||
route.Namespace(utils.InCapsuleGroups(cfg, namespacewebhook.PatchHandler(), namespacewebhook.QuotaHandler(), namespacewebhook.FreezeHandler(cfg), namespacewebhook.PrefixHandler(cfg), namespacewebhook.UserMetadataHandler())),
|
||||
route.Ingress(ingress.Class(cfg), ingress.Hostnames(cfg), ingress.Collision(cfg), ingress.Wildcard()),
|
||||
route.PVC(pvc.Handler()),
|
||||
route.Service(service.Handler()),
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright 2020-2021 Clastix Labs
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
package namespace
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
|
||||
type patchHandler struct{}
|
||||
|
||||
func PatchHandler() capsulewebhook.Handler {
|
||||
return &patchHandler{}
|
||||
}
|
||||
|
||||
func (r *patchHandler) OnCreate(client.Client, *admission.Decoder, record.EventRecorder) capsulewebhook.Func {
|
||||
return func(ctx context.Context, req admission.Request) *admission.Response {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (r *patchHandler) OnDelete(client.Client, *admission.Decoder, record.EventRecorder) capsulewebhook.Func {
|
||||
return func(ctx context.Context, req admission.Request) *admission.Response {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (r *patchHandler) OnUpdate(c client.Client, decoder *admission.Decoder, recorder record.EventRecorder) capsulewebhook.Func {
|
||||
return func(ctx context.Context, req admission.Request) *admission.Response {
|
||||
// Decode Namespace
|
||||
ns := &corev1.Namespace{}
|
||||
if err := decoder.DecodeRaw(req.OldObject, ns); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
// Get Tenant Label
|
||||
ln, err := capsulev1beta1.GetTypeLabel(&capsulev1beta1.Tenant{})
|
||||
if err != nil {
|
||||
response := admission.Errored(http.StatusBadRequest, err)
|
||||
|
||||
return &response
|
||||
}
|
||||
|
||||
// Extract Tenant from namespace
|
||||
e := fmt.Sprintf("namespace/%s can not be patched", ns.Name)
|
||||
|
||||
if label, ok := ns.ObjectMeta.Labels[ln]; ok {
|
||||
// retrieving the selected Tenant
|
||||
tnt := &capsulev1beta1.Tenant{}
|
||||
if err = c.Get(ctx, types.NamespacedName{Name: label}, tnt); err != nil {
|
||||
response := admission.Errored(http.StatusBadRequest, err)
|
||||
|
||||
return &response
|
||||
}
|
||||
|
||||
if !utils.IsTenantOwner(tnt.Spec.Owners, req.UserInfo) {
|
||||
recorder.Eventf(tnt, corev1.EventTypeWarning, "NamespacePatch", e)
|
||||
response := admission.Denied(e)
|
||||
|
||||
return &response
|
||||
}
|
||||
} else {
|
||||
recorder.Eventf(ns, corev1.EventTypeWarning, "NamespacePatch", e)
|
||||
response := admission.Denied(e)
|
||||
|
||||
return &response
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user