mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-13 19:28:55 +00:00
[Feat]: Perform permissions check when TTL label is observed (#8128)
* added permissions check Signed-off-by: Ved Ratan <vedratan8@gmail.com> * lint fix Signed-off-by: Ved Ratan <vedratan8@gmail.com> * lint fix Signed-off-by: Ved Ratan <vedratan8@gmail.com> * issue_8091 Signed-off-by: Ved Ratan <vedratan8@gmail.com> * log fix Signed-off-by: Ved Ratan <vedratan8@gmail.com> * refactor Signed-off-by: Ved Ratan <vedratan8@gmail.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Ved Ratan <vedratan8@gmail.com> Signed-off-by: Ved Ratan <82467006+VedRatan@users.noreply.github.com> Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
94aa1f18c6
commit
daadd36c72
5 changed files with 32 additions and 14 deletions
|
@ -11,17 +11,17 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/webhooks/handlers"
|
||||
)
|
||||
|
||||
type cleanupHandlers struct {
|
||||
type validationHandlers struct {
|
||||
client dclient.Interface
|
||||
}
|
||||
|
||||
func New(client dclient.Interface) *cleanupHandlers {
|
||||
return &cleanupHandlers{
|
||||
func New(client dclient.Interface) *validationHandlers {
|
||||
return &validationHandlers{
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *cleanupHandlers) Validate(ctx context.Context, logger logr.Logger, request handlers.AdmissionRequest, _ time.Time) handlers.AdmissionResponse {
|
||||
func (h *validationHandlers) Validate(ctx context.Context, logger logr.Logger, request handlers.AdmissionRequest, _ time.Time) handlers.AdmissionResponse {
|
||||
policy, _, err := admissionutils.GetCleanupPolicies(request.AdmissionRequest)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to unmarshal policies from admission request")
|
||||
|
|
|
@ -6,17 +6,33 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/kyverno/kyverno/pkg/auth/checker"
|
||||
manager "github.com/kyverno/kyverno/pkg/controllers/ttl"
|
||||
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
|
||||
validation "github.com/kyverno/kyverno/pkg/validation/resource"
|
||||
"github.com/kyverno/kyverno/pkg/webhooks/handlers"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func Validate(ctx context.Context, logger logr.Logger, request handlers.AdmissionRequest, _ time.Time) handlers.AdmissionResponse {
|
||||
type validationHandlers struct {
|
||||
checker checker.AuthChecker
|
||||
}
|
||||
|
||||
func New(checker checker.AuthChecker) *validationHandlers {
|
||||
return &validationHandlers{
|
||||
checker: checker,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *validationHandlers) Validate(ctx context.Context, logger logr.Logger, request handlers.AdmissionRequest, _ time.Time) handlers.AdmissionResponse {
|
||||
metadata, _, err := admissionutils.GetPartialObjectMetadatas(request.AdmissionRequest)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to unmarshal metadatas from admission request")
|
||||
return admissionutils.ResponseSuccess(request.UID, err.Error())
|
||||
}
|
||||
if !manager.HasResourcePermissions(logger, schema.GroupVersionResource(request.AdmissionRequest.Resource), h.checker) {
|
||||
logger.Info("doesn't have required permissions for deletion", "gvr", request.AdmissionRequest.Resource)
|
||||
}
|
||||
if err := validation.ValidateTtlLabel(ctx, metadata); err != nil {
|
||||
logger.Error(err, "metadatas validation errors")
|
||||
return admissionutils.ResponseSuccess(request.UID, fmt.Sprintf("cleanup.kyverno.io/ttl label value cannot be parsed as any recognizable format (%s)", err.Error()))
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
resourcehandlers "github.com/kyverno/kyverno/cmd/cleanup-controller/handlers/admission/resource"
|
||||
cleanuphandlers "github.com/kyverno/kyverno/cmd/cleanup-controller/handlers/cleanup"
|
||||
"github.com/kyverno/kyverno/cmd/internal"
|
||||
"github.com/kyverno/kyverno/pkg/auth/checker"
|
||||
kyvernoinformer "github.com/kyverno/kyverno/pkg/client/informers/externalversions"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/controllers/certmanager"
|
||||
|
@ -101,6 +102,7 @@ func main() {
|
|||
setup.Logger.Error(errors.New("failed to wait for cache sync"), "failed to wait for cache sync")
|
||||
os.Exit(1)
|
||||
}
|
||||
checker := checker.NewSelfChecker(setup.KubeClient.AuthorizationV1().SelfSubjectAccessReviews())
|
||||
// setup leader election
|
||||
le, err := leaderelection.New(
|
||||
setup.Logger.WithName("leader-election"),
|
||||
|
@ -229,7 +231,7 @@ func main() {
|
|||
ttlcontroller.NewManager(
|
||||
setup.MetadataClient,
|
||||
setup.KubeClient.Discovery(),
|
||||
setup.KubeClient.AuthorizationV1(),
|
||||
checker,
|
||||
interval,
|
||||
),
|
||||
ttlcontroller.Workers,
|
||||
|
@ -289,7 +291,8 @@ func main() {
|
|||
var wg sync.WaitGroup
|
||||
go eventGenerator.Run(ctx, 3, &wg)
|
||||
// create handlers
|
||||
admissionHandlers := policyhandlers.New(setup.KyvernoDynamicClient)
|
||||
policyHandlers := policyhandlers.New(setup.KyvernoDynamicClient)
|
||||
resourceHandlers := resourcehandlers.New(checker)
|
||||
cmResolver := internal.NewConfigMapResolver(ctx, setup.Logger, setup.KubeClient, resyncPeriod)
|
||||
cleanupHandlers := cleanuphandlers.New(
|
||||
setup.Logger.WithName("cleanup-handler"),
|
||||
|
@ -310,8 +313,8 @@ func main() {
|
|||
}
|
||||
return secret.Data[corev1.TLSCertKey], secret.Data[corev1.TLSPrivateKeyKey], nil
|
||||
},
|
||||
admissionHandlers.Validate,
|
||||
resourcehandlers.Validate,
|
||||
policyHandlers.Validate,
|
||||
resourceHandlers.Validate,
|
||||
cleanupHandlers.Cleanup,
|
||||
setup.MetricsManager,
|
||||
webhooks.DebugModeOptions{
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/discovery"
|
||||
authorizationv1client "k8s.io/client-go/kubernetes/typed/authorization/v1"
|
||||
"k8s.io/client-go/metadata"
|
||||
"k8s.io/client-go/metadata/metadatainformer"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
@ -47,7 +46,7 @@ type manager struct {
|
|||
func NewManager(
|
||||
metadataInterface metadata.Interface,
|
||||
discoveryInterface discovery.DiscoveryInterface,
|
||||
authorizationInterface authorizationv1client.AuthorizationV1Interface,
|
||||
checker checker.AuthChecker,
|
||||
timeInterval time.Duration,
|
||||
) controllers.Controller {
|
||||
logger := logging.WithName(ControllerName)
|
||||
|
@ -63,7 +62,7 @@ func NewManager(
|
|||
mgr := &manager{
|
||||
metadataClient: metadataInterface,
|
||||
discoveryClient: discoveryInterface,
|
||||
checker: checker.NewSelfChecker(authorizationInterface.SelfSubjectAccessReviews()),
|
||||
checker: checker,
|
||||
resController: map[schema.GroupVersionResource]stopFunc{},
|
||||
logger: logger,
|
||||
interval: timeInterval,
|
||||
|
@ -182,7 +181,7 @@ func (m *manager) filterPermissionsResource(resources []schema.GroupVersionResou
|
|||
validResources := []schema.GroupVersionResource{}
|
||||
for _, resource := range resources {
|
||||
// Check if the service account has the necessary permissions
|
||||
if hasResourcePermissions(m.logger, resource, m.checker) {
|
||||
if HasResourcePermissions(m.logger, resource, m.checker) {
|
||||
validResources = append(validResources, resource)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ func discoverResources(logger logr.Logger, discoveryClient discovery.DiscoveryIn
|
|||
return resources, nil
|
||||
}
|
||||
|
||||
func hasResourcePermissions(logger logr.Logger, resource schema.GroupVersionResource, s checker.AuthChecker) bool {
|
||||
func HasResourcePermissions(logger logr.Logger, resource schema.GroupVersionResource, s checker.AuthChecker) bool {
|
||||
can, err := checker.Check(context.TODO(), s, resource.Group, resource.Version, resource.Resource, "", "", "watch", "list", "delete")
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to check permissions")
|
||||
|
|
Loading…
Add table
Reference in a new issue