1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-15 17:51:20 +00:00

fix: add roles and clusterroles when dumping admission requests (#6319)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-02-15 10:37:36 +01:00 committed by GitHub
parent 431cceae1a
commit 86008929f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 53 additions and 22 deletions

View file

@ -71,7 +71,7 @@ func NewServer(
"POST",
config.CleanupValidatingWebhookServicePath,
handlers.FromAdmissionFunc("VALIDATE", validationHandler).
WithDump(debugModeOpts.DumpPayload).
WithDump(debugModeOpts.DumpPayload, nil, nil, nil).
WithSubResourceFilter().
WithMetrics(policyLogger, metricsConfig.Config(), metrics.WebhookValidating).
WithAdmission(policyLogger.WithName("validate")).

View file

@ -524,6 +524,8 @@ func main() {
kubeClient.AdmissionregistrationV1().ValidatingWebhookConfigurations(),
kubeClient.CoordinationV1().Leases(config.KyvernoNamespace()),
runtime,
kubeInformer.Rbac().V1().RoleBindings().Lister(),
kubeInformer.Rbac().V1().ClusterRoleBindings().Lister(),
)
// start informers and wait for cache sync
// we need to call start again because we potentially registered new informers

View file

@ -6,6 +6,8 @@ import (
"time"
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/userinfo"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
admissionv1 "k8s.io/api/admission/v1"
@ -13,25 +15,42 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
rbacv1listers "k8s.io/client-go/listers/rbac/v1"
)
func (inner AdmissionHandler) WithDump(enabled bool) AdmissionHandler {
func (inner AdmissionHandler) WithDump(
enabled bool,
rbLister rbacv1listers.RoleBindingLister,
crbLister rbacv1listers.ClusterRoleBindingLister,
configuration config.Configuration,
) AdmissionHandler {
if !enabled {
return inner
}
return inner.withDump().WithTrace("DUMP")
return inner.withDump(rbLister, crbLister, configuration).WithTrace("DUMP")
}
func (inner AdmissionHandler) withDump() AdmissionHandler {
func (inner AdmissionHandler) withDump(
rbLister rbacv1listers.RoleBindingLister,
crbLister rbacv1listers.ClusterRoleBindingLister,
configuration config.Configuration,
) AdmissionHandler {
return func(ctx context.Context, logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse {
response := inner(ctx, logger, request, startTime)
dumpPayload(logger, request, response)
dumpPayload(logger, rbLister, crbLister, configuration, request, response)
return response
}
}
func dumpPayload(logger logr.Logger, request *admissionv1.AdmissionRequest, response *admissionv1.AdmissionResponse) {
reqPayload, err := newAdmissionRequestPayload(request)
func dumpPayload(
logger logr.Logger,
rbLister rbacv1listers.RoleBindingLister,
crbLister rbacv1listers.ClusterRoleBindingLister,
configuration config.Configuration,
request *admissionv1.AdmissionRequest,
response *admissionv1.AdmissionResponse,
) {
reqPayload, err := newAdmissionRequestPayload(request, rbLister, crbLister, configuration)
if err != nil {
logger.Error(err, "Failed to extract resources")
} else {
@ -52,13 +71,15 @@ type admissionRequestPayload struct {
Namespace string `json:"namespace,omitempty"`
Operation string `json:"operation"`
UserInfo authenticationv1.UserInfo `json:"userInfo"`
Roles []string `json:"roles"`
ClusterRoles []string `json:"clusterRoles"`
Object unstructured.Unstructured `json:"object,omitempty"`
OldObject unstructured.Unstructured `json:"oldObject,omitempty"`
DryRun *bool `json:"dryRun,omitempty"`
Options unstructured.Unstructured `json:"options,omitempty"`
}
func newAdmissionRequestPayload(request *admissionv1.AdmissionRequest) (*admissionRequestPayload, error) {
func newAdmissionRequestPayload(request *admissionv1.AdmissionRequest, rbLister rbacv1listers.RoleBindingLister, crbLister rbacv1listers.ClusterRoleBindingLister, configuration config.Configuration) (*admissionRequestPayload, error) {
newResource, oldResource, err := admissionutils.ExtractResources(nil, request)
if err != nil {
return nil, err
@ -70,6 +91,15 @@ func newAdmissionRequestPayload(request *admissionv1.AdmissionRequest) (*admissi
return nil, err
}
}
var roles, clusterRoles []string
if rbLister != nil && crbLister != nil && configuration != nil {
if r, cr, err := userinfo.GetRoleRef(rbLister, crbLister, request, configuration); err != nil {
return nil, err
} else {
roles = r
clusterRoles = cr
}
}
return redactPayload(&admissionRequestPayload{
UID: request.UID,
Kind: request.Kind,
@ -82,6 +112,8 @@ func newAdmissionRequestPayload(request *admissionv1.AdmissionRequest) (*admissi
Namespace: request.Namespace,
Operation: string(request.Operation),
UserInfo: request.UserInfo,
Roles: roles,
ClusterRoles: clusterRoles,
Object: newResource,
OldObject: oldResource,
DryRun: request.DryRun,

View file

@ -141,7 +141,7 @@ func Test_RedactPayload(t *testing.T) {
req := new(admissionv1.AdmissionRequest)
err := json.Unmarshal(c.requestPayload, req)
assert.NilError(t, err)
payload, err := newAdmissionRequestPayload(req)
payload, err := newAdmissionRequestPayload(req, nil, nil, nil)
assert.NilError(t, err)
if payload.Object.Object != nil {
data, err := datautils.ToMap(payload.Object.Object["data"])

View file

@ -49,8 +49,6 @@ func NewFakeHandlers(ctx context.Context, policyCache policycache.Cache) webhook
metricsConfig: metricsConfig,
pCache: policyCache,
nsLister: informers.Core().V1().Namespaces().Lister(),
rbLister: rbLister,
crbLister: crbLister,
urLister: urLister,
urGenerator: updaterequest.NewFake(),
eventGen: event.NewFake(),

View file

@ -51,10 +51,8 @@ type handlers struct {
pCache policycache.Cache
// listers
nsLister corev1listers.NamespaceLister
rbLister rbacv1listers.RoleBindingLister
crbLister rbacv1listers.ClusterRoleBindingLister
urLister kyvernov1beta1listers.UpdateRequestNamespaceLister
nsLister corev1listers.NamespaceLister
urLister kyvernov1beta1listers.UpdateRequestNamespaceLister
urGenerator webhookgenerate.Generator
eventGen event.Interface
@ -91,8 +89,6 @@ func NewHandlers(
metricsConfig: metricsConfig,
pCache: pCache,
nsLister: nsLister,
rbLister: rbLister,
crbLister: crbLister,
urLister: urLister,
urGenerator: urGenerator,
eventGen: eventGen,

View file

@ -21,6 +21,7 @@ import (
coordinationv1 "k8s.io/api/coordination/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
rbacv1listers "k8s.io/client-go/listers/rbac/v1"
)
// DebugModeOptions holds the options to configure debug mode
@ -78,6 +79,8 @@ func NewServer(
vwcClient controllerutils.DeleteCollectionClient[*admissionregistrationv1.ValidatingWebhookConfiguration],
leaseClient controllerutils.DeleteClient[*coordinationv1.Lease],
runtime runtimeutils.Runtime,
rbLister rbacv1listers.RoleBindingLister,
crbLister rbacv1listers.ClusterRoleBindingLister,
) Server {
mux := httprouter.New()
resourceLogger := logger.WithName("resource")
@ -93,7 +96,7 @@ func NewServer(
return handler.
WithFilter(configuration).
WithProtection(toggle.ProtectManagedResources.Enabled()).
WithDump(debugModeOpts.DumpPayload).
WithDump(debugModeOpts.DumpPayload, rbLister, crbLister, configuration).
WithOperationFilter(admissionv1.Create, admissionv1.Update, admissionv1.Connect).
WithMetrics(resourceLogger, metricsConfig.Config(), metrics.WebhookMutating).
WithAdmission(resourceLogger.WithName("mutate"))
@ -108,7 +111,7 @@ func NewServer(
return handler.
WithFilter(configuration).
WithProtection(toggle.ProtectManagedResources.Enabled()).
WithDump(debugModeOpts.DumpPayload).
WithDump(debugModeOpts.DumpPayload, rbLister, crbLister, configuration).
WithMetrics(resourceLogger, metricsConfig.Config(), metrics.WebhookValidating).
WithAdmission(resourceLogger.WithName("validate"))
},
@ -117,7 +120,7 @@ func NewServer(
"POST",
config.PolicyMutatingWebhookServicePath,
handlers.FromAdmissionFunc("MUTATE", policyHandlers.Mutate).
WithDump(debugModeOpts.DumpPayload).
WithDump(debugModeOpts.DumpPayload, rbLister, crbLister, configuration).
WithMetrics(policyLogger, metricsConfig.Config(), metrics.WebhookMutating).
WithAdmission(policyLogger.WithName("mutate")).
ToHandlerFunc(),
@ -126,7 +129,7 @@ func NewServer(
"POST",
config.PolicyValidatingWebhookServicePath,
handlers.FromAdmissionFunc("VALIDATE", policyHandlers.Validate).
WithDump(debugModeOpts.DumpPayload).
WithDump(debugModeOpts.DumpPayload, rbLister, crbLister, configuration).
WithSubResourceFilter().
WithMetrics(policyLogger, metricsConfig.Config(), metrics.WebhookValidating).
WithAdmission(policyLogger.WithName("validate")).
@ -136,7 +139,7 @@ func NewServer(
"POST",
config.ExceptionValidatingWebhookServicePath,
handlers.FromAdmissionFunc("VALIDATE", exceptionHandlers.Validate).
WithDump(debugModeOpts.DumpPayload).
WithDump(debugModeOpts.DumpPayload, rbLister, crbLister, configuration).
WithSubResourceFilter().
WithMetrics(exceptionLogger, metricsConfig.Config(), metrics.WebhookValidating).
WithAdmission(exceptionLogger.WithName("validate")).