mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +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:
parent
431cceae1a
commit
86008929f6
7 changed files with 53 additions and 22 deletions
|
@ -71,7 +71,7 @@ func NewServer(
|
||||||
"POST",
|
"POST",
|
||||||
config.CleanupValidatingWebhookServicePath,
|
config.CleanupValidatingWebhookServicePath,
|
||||||
handlers.FromAdmissionFunc("VALIDATE", validationHandler).
|
handlers.FromAdmissionFunc("VALIDATE", validationHandler).
|
||||||
WithDump(debugModeOpts.DumpPayload).
|
WithDump(debugModeOpts.DumpPayload, nil, nil, nil).
|
||||||
WithSubResourceFilter().
|
WithSubResourceFilter().
|
||||||
WithMetrics(policyLogger, metricsConfig.Config(), metrics.WebhookValidating).
|
WithMetrics(policyLogger, metricsConfig.Config(), metrics.WebhookValidating).
|
||||||
WithAdmission(policyLogger.WithName("validate")).
|
WithAdmission(policyLogger.WithName("validate")).
|
||||||
|
|
|
@ -524,6 +524,8 @@ func main() {
|
||||||
kubeClient.AdmissionregistrationV1().ValidatingWebhookConfigurations(),
|
kubeClient.AdmissionregistrationV1().ValidatingWebhookConfigurations(),
|
||||||
kubeClient.CoordinationV1().Leases(config.KyvernoNamespace()),
|
kubeClient.CoordinationV1().Leases(config.KyvernoNamespace()),
|
||||||
runtime,
|
runtime,
|
||||||
|
kubeInformer.Rbac().V1().RoleBindings().Lister(),
|
||||||
|
kubeInformer.Rbac().V1().ClusterRoleBindings().Lister(),
|
||||||
)
|
)
|
||||||
// start informers and wait for cache sync
|
// start informers and wait for cache sync
|
||||||
// we need to call start again because we potentially registered new informers
|
// we need to call start again because we potentially registered new informers
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
"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"
|
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
|
||||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||||
admissionv1 "k8s.io/api/admission/v1"
|
admissionv1 "k8s.io/api/admission/v1"
|
||||||
|
@ -13,25 +15,42 @@ import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"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 {
|
if !enabled {
|
||||||
return inner
|
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 {
|
return func(ctx context.Context, logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse {
|
||||||
response := inner(ctx, logger, request, startTime)
|
response := inner(ctx, logger, request, startTime)
|
||||||
dumpPayload(logger, request, response)
|
dumpPayload(logger, rbLister, crbLister, configuration, request, response)
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpPayload(logger logr.Logger, request *admissionv1.AdmissionRequest, response *admissionv1.AdmissionResponse) {
|
func dumpPayload(
|
||||||
reqPayload, err := newAdmissionRequestPayload(request)
|
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 {
|
if err != nil {
|
||||||
logger.Error(err, "Failed to extract resources")
|
logger.Error(err, "Failed to extract resources")
|
||||||
} else {
|
} else {
|
||||||
|
@ -52,13 +71,15 @@ type admissionRequestPayload struct {
|
||||||
Namespace string `json:"namespace,omitempty"`
|
Namespace string `json:"namespace,omitempty"`
|
||||||
Operation string `json:"operation"`
|
Operation string `json:"operation"`
|
||||||
UserInfo authenticationv1.UserInfo `json:"userInfo"`
|
UserInfo authenticationv1.UserInfo `json:"userInfo"`
|
||||||
|
Roles []string `json:"roles"`
|
||||||
|
ClusterRoles []string `json:"clusterRoles"`
|
||||||
Object unstructured.Unstructured `json:"object,omitempty"`
|
Object unstructured.Unstructured `json:"object,omitempty"`
|
||||||
OldObject unstructured.Unstructured `json:"oldObject,omitempty"`
|
OldObject unstructured.Unstructured `json:"oldObject,omitempty"`
|
||||||
DryRun *bool `json:"dryRun,omitempty"`
|
DryRun *bool `json:"dryRun,omitempty"`
|
||||||
Options unstructured.Unstructured `json:"options,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)
|
newResource, oldResource, err := admissionutils.ExtractResources(nil, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -70,6 +91,15 @@ func newAdmissionRequestPayload(request *admissionv1.AdmissionRequest) (*admissi
|
||||||
return nil, err
|
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{
|
return redactPayload(&admissionRequestPayload{
|
||||||
UID: request.UID,
|
UID: request.UID,
|
||||||
Kind: request.Kind,
|
Kind: request.Kind,
|
||||||
|
@ -82,6 +112,8 @@ func newAdmissionRequestPayload(request *admissionv1.AdmissionRequest) (*admissi
|
||||||
Namespace: request.Namespace,
|
Namespace: request.Namespace,
|
||||||
Operation: string(request.Operation),
|
Operation: string(request.Operation),
|
||||||
UserInfo: request.UserInfo,
|
UserInfo: request.UserInfo,
|
||||||
|
Roles: roles,
|
||||||
|
ClusterRoles: clusterRoles,
|
||||||
Object: newResource,
|
Object: newResource,
|
||||||
OldObject: oldResource,
|
OldObject: oldResource,
|
||||||
DryRun: request.DryRun,
|
DryRun: request.DryRun,
|
||||||
|
|
|
@ -141,7 +141,7 @@ func Test_RedactPayload(t *testing.T) {
|
||||||
req := new(admissionv1.AdmissionRequest)
|
req := new(admissionv1.AdmissionRequest)
|
||||||
err := json.Unmarshal(c.requestPayload, req)
|
err := json.Unmarshal(c.requestPayload, req)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
payload, err := newAdmissionRequestPayload(req)
|
payload, err := newAdmissionRequestPayload(req, nil, nil, nil)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
if payload.Object.Object != nil {
|
if payload.Object.Object != nil {
|
||||||
data, err := datautils.ToMap(payload.Object.Object["data"])
|
data, err := datautils.ToMap(payload.Object.Object["data"])
|
||||||
|
|
|
@ -49,8 +49,6 @@ func NewFakeHandlers(ctx context.Context, policyCache policycache.Cache) webhook
|
||||||
metricsConfig: metricsConfig,
|
metricsConfig: metricsConfig,
|
||||||
pCache: policyCache,
|
pCache: policyCache,
|
||||||
nsLister: informers.Core().V1().Namespaces().Lister(),
|
nsLister: informers.Core().V1().Namespaces().Lister(),
|
||||||
rbLister: rbLister,
|
|
||||||
crbLister: crbLister,
|
|
||||||
urLister: urLister,
|
urLister: urLister,
|
||||||
urGenerator: updaterequest.NewFake(),
|
urGenerator: updaterequest.NewFake(),
|
||||||
eventGen: event.NewFake(),
|
eventGen: event.NewFake(),
|
||||||
|
|
|
@ -51,10 +51,8 @@ type handlers struct {
|
||||||
pCache policycache.Cache
|
pCache policycache.Cache
|
||||||
|
|
||||||
// listers
|
// listers
|
||||||
nsLister corev1listers.NamespaceLister
|
nsLister corev1listers.NamespaceLister
|
||||||
rbLister rbacv1listers.RoleBindingLister
|
urLister kyvernov1beta1listers.UpdateRequestNamespaceLister
|
||||||
crbLister rbacv1listers.ClusterRoleBindingLister
|
|
||||||
urLister kyvernov1beta1listers.UpdateRequestNamespaceLister
|
|
||||||
|
|
||||||
urGenerator webhookgenerate.Generator
|
urGenerator webhookgenerate.Generator
|
||||||
eventGen event.Interface
|
eventGen event.Interface
|
||||||
|
@ -91,8 +89,6 @@ func NewHandlers(
|
||||||
metricsConfig: metricsConfig,
|
metricsConfig: metricsConfig,
|
||||||
pCache: pCache,
|
pCache: pCache,
|
||||||
nsLister: nsLister,
|
nsLister: nsLister,
|
||||||
rbLister: rbLister,
|
|
||||||
crbLister: crbLister,
|
|
||||||
urLister: urLister,
|
urLister: urLister,
|
||||||
urGenerator: urGenerator,
|
urGenerator: urGenerator,
|
||||||
eventGen: eventGen,
|
eventGen: eventGen,
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
coordinationv1 "k8s.io/api/coordination/v1"
|
coordinationv1 "k8s.io/api/coordination/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
rbacv1listers "k8s.io/client-go/listers/rbac/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DebugModeOptions holds the options to configure debug mode
|
// DebugModeOptions holds the options to configure debug mode
|
||||||
|
@ -78,6 +79,8 @@ func NewServer(
|
||||||
vwcClient controllerutils.DeleteCollectionClient[*admissionregistrationv1.ValidatingWebhookConfiguration],
|
vwcClient controllerutils.DeleteCollectionClient[*admissionregistrationv1.ValidatingWebhookConfiguration],
|
||||||
leaseClient controllerutils.DeleteClient[*coordinationv1.Lease],
|
leaseClient controllerutils.DeleteClient[*coordinationv1.Lease],
|
||||||
runtime runtimeutils.Runtime,
|
runtime runtimeutils.Runtime,
|
||||||
|
rbLister rbacv1listers.RoleBindingLister,
|
||||||
|
crbLister rbacv1listers.ClusterRoleBindingLister,
|
||||||
) Server {
|
) Server {
|
||||||
mux := httprouter.New()
|
mux := httprouter.New()
|
||||||
resourceLogger := logger.WithName("resource")
|
resourceLogger := logger.WithName("resource")
|
||||||
|
@ -93,7 +96,7 @@ func NewServer(
|
||||||
return handler.
|
return handler.
|
||||||
WithFilter(configuration).
|
WithFilter(configuration).
|
||||||
WithProtection(toggle.ProtectManagedResources.Enabled()).
|
WithProtection(toggle.ProtectManagedResources.Enabled()).
|
||||||
WithDump(debugModeOpts.DumpPayload).
|
WithDump(debugModeOpts.DumpPayload, rbLister, crbLister, configuration).
|
||||||
WithOperationFilter(admissionv1.Create, admissionv1.Update, admissionv1.Connect).
|
WithOperationFilter(admissionv1.Create, admissionv1.Update, admissionv1.Connect).
|
||||||
WithMetrics(resourceLogger, metricsConfig.Config(), metrics.WebhookMutating).
|
WithMetrics(resourceLogger, metricsConfig.Config(), metrics.WebhookMutating).
|
||||||
WithAdmission(resourceLogger.WithName("mutate"))
|
WithAdmission(resourceLogger.WithName("mutate"))
|
||||||
|
@ -108,7 +111,7 @@ func NewServer(
|
||||||
return handler.
|
return handler.
|
||||||
WithFilter(configuration).
|
WithFilter(configuration).
|
||||||
WithProtection(toggle.ProtectManagedResources.Enabled()).
|
WithProtection(toggle.ProtectManagedResources.Enabled()).
|
||||||
WithDump(debugModeOpts.DumpPayload).
|
WithDump(debugModeOpts.DumpPayload, rbLister, crbLister, configuration).
|
||||||
WithMetrics(resourceLogger, metricsConfig.Config(), metrics.WebhookValidating).
|
WithMetrics(resourceLogger, metricsConfig.Config(), metrics.WebhookValidating).
|
||||||
WithAdmission(resourceLogger.WithName("validate"))
|
WithAdmission(resourceLogger.WithName("validate"))
|
||||||
},
|
},
|
||||||
|
@ -117,7 +120,7 @@ func NewServer(
|
||||||
"POST",
|
"POST",
|
||||||
config.PolicyMutatingWebhookServicePath,
|
config.PolicyMutatingWebhookServicePath,
|
||||||
handlers.FromAdmissionFunc("MUTATE", policyHandlers.Mutate).
|
handlers.FromAdmissionFunc("MUTATE", policyHandlers.Mutate).
|
||||||
WithDump(debugModeOpts.DumpPayload).
|
WithDump(debugModeOpts.DumpPayload, rbLister, crbLister, configuration).
|
||||||
WithMetrics(policyLogger, metricsConfig.Config(), metrics.WebhookMutating).
|
WithMetrics(policyLogger, metricsConfig.Config(), metrics.WebhookMutating).
|
||||||
WithAdmission(policyLogger.WithName("mutate")).
|
WithAdmission(policyLogger.WithName("mutate")).
|
||||||
ToHandlerFunc(),
|
ToHandlerFunc(),
|
||||||
|
@ -126,7 +129,7 @@ func NewServer(
|
||||||
"POST",
|
"POST",
|
||||||
config.PolicyValidatingWebhookServicePath,
|
config.PolicyValidatingWebhookServicePath,
|
||||||
handlers.FromAdmissionFunc("VALIDATE", policyHandlers.Validate).
|
handlers.FromAdmissionFunc("VALIDATE", policyHandlers.Validate).
|
||||||
WithDump(debugModeOpts.DumpPayload).
|
WithDump(debugModeOpts.DumpPayload, rbLister, crbLister, configuration).
|
||||||
WithSubResourceFilter().
|
WithSubResourceFilter().
|
||||||
WithMetrics(policyLogger, metricsConfig.Config(), metrics.WebhookValidating).
|
WithMetrics(policyLogger, metricsConfig.Config(), metrics.WebhookValidating).
|
||||||
WithAdmission(policyLogger.WithName("validate")).
|
WithAdmission(policyLogger.WithName("validate")).
|
||||||
|
@ -136,7 +139,7 @@ func NewServer(
|
||||||
"POST",
|
"POST",
|
||||||
config.ExceptionValidatingWebhookServicePath,
|
config.ExceptionValidatingWebhookServicePath,
|
||||||
handlers.FromAdmissionFunc("VALIDATE", exceptionHandlers.Validate).
|
handlers.FromAdmissionFunc("VALIDATE", exceptionHandlers.Validate).
|
||||||
WithDump(debugModeOpts.DumpPayload).
|
WithDump(debugModeOpts.DumpPayload, rbLister, crbLister, configuration).
|
||||||
WithSubResourceFilter().
|
WithSubResourceFilter().
|
||||||
WithMetrics(exceptionLogger, metricsConfig.Config(), metrics.WebhookValidating).
|
WithMetrics(exceptionLogger, metricsConfig.Config(), metrics.WebhookValidating).
|
||||||
WithAdmission(exceptionLogger.WithName("validate")).
|
WithAdmission(exceptionLogger.WithName("validate")).
|
||||||
|
|
Loading…
Add table
Reference in a new issue