mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-05 07:26:55 +00:00
122 lines
4.1 KiB
Go
122 lines
4.1 KiB
Go
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/go-logr/logr"
|
|
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
|
|
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
|
authenticationv1 "k8s.io/api/authentication/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
)
|
|
|
|
func (inner AdmissionHandler) WithDump(
|
|
enabled bool,
|
|
) AdmissionHandler {
|
|
if !enabled {
|
|
return inner
|
|
}
|
|
return inner.withDump().WithTrace("DUMP")
|
|
}
|
|
|
|
func (inner AdmissionHandler) withDump() AdmissionHandler {
|
|
return func(ctx context.Context, logger logr.Logger, request AdmissionRequest, startTime time.Time) AdmissionResponse {
|
|
response := inner(ctx, logger, request, startTime)
|
|
dumpPayload(logger, request, response)
|
|
return response
|
|
}
|
|
}
|
|
|
|
func dumpPayload(
|
|
logger logr.Logger,
|
|
request AdmissionRequest,
|
|
response AdmissionResponse,
|
|
) {
|
|
reqPayload, err := newAdmissionRequestPayload(request)
|
|
if err != nil {
|
|
logger.Error(err, "Failed to extract resources")
|
|
} else {
|
|
logger = logger.WithValues("admission.response", response, "admission.request", reqPayload)
|
|
logger.Info("admission request dump")
|
|
}
|
|
}
|
|
|
|
// admissionRequestPayload holds a copy of the AdmissionRequest payload
|
|
type admissionRequestPayload struct {
|
|
UID types.UID `json:"uid"`
|
|
Kind metav1.GroupVersionKind `json:"kind"`
|
|
Resource metav1.GroupVersionResource `json:"resource"`
|
|
SubResource string `json:"subResource,omitempty"`
|
|
RequestKind *metav1.GroupVersionKind `json:"requestKind,omitempty"`
|
|
RequestResource *metav1.GroupVersionResource `json:"requestResource,omitempty"`
|
|
RequestSubResource string `json:"requestSubResource,omitempty"`
|
|
Name string `json:"name,omitempty"`
|
|
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 AdmissionRequest,
|
|
) (*admissionRequestPayload, error) {
|
|
newResource, oldResource, err := admissionutils.ExtractResources(nil, request.AdmissionRequest)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
options := new(unstructured.Unstructured)
|
|
if request.Options.Raw != nil {
|
|
options, err = kubeutils.BytesToUnstructured(request.Options.Raw)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return redactPayload(&admissionRequestPayload{
|
|
UID: request.UID,
|
|
Kind: request.Kind,
|
|
Resource: request.Resource,
|
|
SubResource: request.SubResource,
|
|
RequestKind: request.RequestKind,
|
|
RequestResource: request.RequestResource,
|
|
RequestSubResource: request.RequestSubResource,
|
|
Name: request.Name,
|
|
Namespace: request.Namespace,
|
|
Operation: string(request.Operation),
|
|
UserInfo: request.UserInfo,
|
|
Roles: request.Roles,
|
|
ClusterRoles: request.ClusterRoles,
|
|
Object: newResource,
|
|
OldObject: oldResource,
|
|
DryRun: request.DryRun,
|
|
Options: *options,
|
|
})
|
|
}
|
|
|
|
func redactPayload(payload *admissionRequestPayload) (*admissionRequestPayload, error) {
|
|
if strings.EqualFold(payload.Kind.Kind, "Secret") {
|
|
if payload.Object.Object != nil {
|
|
obj, err := kubeutils.RedactSecret(&payload.Object)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
payload.Object = obj
|
|
}
|
|
if payload.OldObject.Object != nil {
|
|
oldObj, err := kubeutils.RedactSecret(&payload.OldObject)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
payload.OldObject = oldObj
|
|
}
|
|
}
|
|
return payload, nil
|
|
}
|