1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-31 03:45:17 +00:00

fix: add logs in webhook middlewares (#6797)

This commit is contained in:
Charles-Edouard Brétéché 2023-04-06 16:28:13 +02:00 committed by GitHub
parent a3147758e4
commit 58d4d3c28a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 50 additions and 40 deletions

View file

@ -197,27 +197,13 @@ func (cd *configuration) ToFilter(gvk schema.GroupVersionKind, subresource, name
defer cd.mux.RUnlock()
if !cd.skipResourceFilters {
for _, f := range cd.filters {
if wildcard.Match(f.Group, gvk.Group) &&
wildcard.Match(f.Version, gvk.Version) &&
wildcard.Match(f.Kind, gvk.Kind) &&
wildcard.Match(f.Subresource, subresource) &&
wildcard.Match(f.Namespace, namespace) &&
wildcard.Match(f.Name, name) {
return true
}
// [Namespace,kube-system,*] || [*,kube-system,*]
if gvk.Group == "" && gvk.Version == "v1" && gvk.Kind == "Namespace" {
if wildcard.Match(f.Group, gvk.Group) &&
wildcard.Match(f.Version, gvk.Version) &&
wildcard.Match(f.Kind, gvk.Kind) &&
wildcard.Match(f.Namespace, name) {
if wildcard.Match(f.Group, gvk.Group) && wildcard.Match(f.Version, gvk.Version) && wildcard.Match(f.Kind, gvk.Kind) && wildcard.Match(f.Subresource, subresource) {
if wildcard.Match(f.Namespace, namespace) && wildcard.Match(f.Name, name) {
return true
}
// [Namespace,kube-system,*] || [*,kube-system,*]
if gvk.Group == "" && gvk.Version == "v1" && gvk.Kind == "Namespace" {
if wildcard.Match(f.Group, gvk.Group) &&
wildcard.Match(f.Version, gvk.Version) &&
wildcard.Match(f.Kind, gvk.Kind) &&
wildcard.Match(f.Namespace, name) {
if wildcard.Match(f.Namespace, name) {
return true
}
}

View file

@ -123,7 +123,7 @@ func Test_namespacedResourceResolverChain_Get(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
resolver, _ := NewNamespacedResourceResolver(tt.fields.resolvers...)
got, err := resolver.Get(context.TODO(), tt.args.namespace, tt.args.name)
if !reflect.DeepEqual(err, tt.wantErr) {
if !reflect.DeepEqual(err, tt.wantErr) { //nolint:deepequalerrors
t.Errorf("ConfigmapResolver.Get() error = %v, wantErr %v", err, tt.wantErr)
return
}

View file

@ -43,6 +43,12 @@ const (
RequestUserNameKey = attribute.Key("admission.request.user.name")
RequestUserUidKey = attribute.Key("admission.request.user.uid")
RequestUserGroupsKey = attribute.Key("admission.request.user.groups")
RequestRolesKey = attribute.Key("admission.request.roles")
RequestClusterRolesKey = attribute.Key("admission.request.clusterroles")
RequestGroupKey = attribute.Key("admission.request.group")
RequestVersionKey = attribute.Key("admission.request.version")
RequestKindKey = attribute.Key("admission.request.kind")
RequestFilteredKey = attribute.Key("admission.request.filtered")
// admission response attributes
ResponseUidKey = attribute.Key("admission.response.uid")
ResponseAllowedKey = attribute.Key("admission.response.allowed")

View file

@ -4,6 +4,7 @@ import (
"context"
"net/http"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
"go.opentelemetry.io/otel/trace"
@ -43,3 +44,7 @@ func IsInSpan(ctx context.Context) bool {
func CurrentSpan(ctx context.Context) trace.Span {
return trace.SpanFromContext(ctx)
}
func SetAttributes(ctx context.Context, kv ...attribute.KeyValue) {
CurrentSpan(ctx).SetAttributes(kv...)
}

View file

@ -62,10 +62,5 @@ func (inner AdmissionHandler) withAdmission(logger logr.Logger) HttpHandler {
HttpError(request.Context(), writer, request, logger, err, http.StatusInternalServerError)
return
}
if admissionReview.Request.Kind.Kind == "Lease" {
logger.V(6).Info("admission review request processed", "time", time.Since(startTime).String())
} else {
logger.V(4).Info("admission review request processed", "time", time.Since(startTime).String())
}
}
}

View file

@ -40,8 +40,8 @@ func dumpPayload(
if err != nil {
logger.Error(err, "Failed to extract resources")
} else {
logger = logger.WithValues("AdmissionResponse", response, "AdmissionRequest", reqPayload)
logger.Info("Logging admission request and response payload ")
logger = logger.WithValues("admission.response", response, "admission.request", reqPayload)
logger.Info("admission request dump")
}
}

View file

@ -32,6 +32,7 @@ func (inner AdmissionHandler) withRoles(
return func(ctx context.Context, logger logr.Logger, request AdmissionRequest, startTime time.Time) AdmissionResponse {
roles, clusterRoles, err := userinfo.GetRoleRef(rbLister, crbLister, request.UserInfo)
if err != nil {
logger.Error(err, "failed to get roles/cluster roles from user infos")
return admissionutils.Response(request.UID, err)
}
request.Roles = roles
@ -50,6 +51,7 @@ func (inner AdmissionHandler) withTopLevelGVK(
return func(ctx context.Context, logger logr.Logger, request AdmissionRequest, startTime time.Time) AdmissionResponse {
gvk, err := client.GetGVKFromGVR(schema.GroupVersionResource(request.Resource))
if err != nil {
logger.Error(err, "failed to get top level GVK from GVR")
return admissionutils.Response(request.UID, err)
}
request.GroupVersionKind = gvk

View file

@ -6,6 +6,7 @@ import (
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/tracing"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
wildcard "github.com/kyverno/kyverno/pkg/utils/wildcard"
webhookutils "github.com/kyverno/kyverno/pkg/webhooks/utils"
@ -25,45 +26,55 @@ func (inner AdmissionHandler) WithSubResourceFilter(subresources ...string) Admi
return inner.withSubResourceFilter(subresources...).WithTrace("SUBRESOURCE")
}
func filtered(ctx context.Context, logger logr.Logger, request AdmissionRequest, message string, keysAndValues ...interface{}) AdmissionResponse {
logger.V(2).Info(message, keysAndValues...)
tracing.SetAttributes(ctx, tracing.RequestFilteredKey.Bool(true))
return admissionutils.ResponseSuccess(request.UID)
}
func (inner AdmissionHandler) withFilter(c config.Configuration) AdmissionHandler {
return func(ctx context.Context, logger logr.Logger, request AdmissionRequest, startTime time.Time) AdmissionResponse {
// filter by username
for _, username := range c.GetExcludedUsernames() {
excludeUsernames := c.GetExcludedUsernames()
for _, username := range excludeUsernames {
if wildcard.Match(username, request.UserInfo.Username) {
return admissionutils.ResponseSuccess(request.UID)
return filtered(ctx, logger, request, "admission request filtered because user is excluded", "config.exlude.usernames", excludeUsernames)
}
}
// filter by groups
for _, group := range c.GetExcludedGroups() {
excludeGroups := c.GetExcludedGroups()
for _, group := range excludeGroups {
for _, candidate := range request.UserInfo.Groups {
if wildcard.Match(group, candidate) {
return admissionutils.ResponseSuccess(request.UID)
return filtered(ctx, logger, request, "admission request filtered because group is excluded", "config.exlude.groups", excludeGroups)
}
}
}
// filter by roles
for _, role := range c.GetExcludedRoles() {
excludeRoles := c.GetExcludedRoles()
for _, role := range excludeRoles {
for _, candidate := range request.Roles {
if wildcard.Match(role, candidate) {
return admissionutils.ResponseSuccess(request.UID)
return filtered(ctx, logger, request, "admission request filtered because role is excluded", "config.exlude.roles", excludeRoles)
}
}
}
// filter by cluster roles
for _, clusterRole := range c.GetExcludedClusterRoles() {
excludeClusterRoles := c.GetExcludedClusterRoles()
for _, clusterRole := range excludeClusterRoles {
for _, candidate := range request.ClusterRoles {
if wildcard.Match(clusterRole, candidate) {
return admissionutils.ResponseSuccess(request.UID)
return filtered(ctx, logger, request, "admission request filtered because role is excluded", "config.exlude.cluster-roles", excludeClusterRoles)
}
}
}
// filter by resource filters
if c.ToFilter(request.GroupVersionKind, request.SubResource, request.Namespace, request.Name) {
return admissionutils.ResponseSuccess(request.UID)
return filtered(ctx, logger, request, "admission request filtered because it apears in configmap resource filters")
}
// filter kyverno resources
if webhookutils.ExcludeKyvernoResources(request.Kind.Kind) {
return admissionutils.ResponseSuccess(request.UID)
return filtered(ctx, logger, request, "admission request filtered because it is for a kyverno resource")
}
return inner(ctx, logger, request, startTime)
}
@ -78,7 +89,7 @@ func (inner AdmissionHandler) withOperationFilter(operations ...admissionv1.Oper
if allowed.Has(string(request.Operation)) {
return inner(ctx, logger, request, startTime)
}
return admissionutils.ResponseSuccess(request.UID)
return filtered(ctx, logger, request, "admission request filtered because operation is excluded")
}
}
@ -88,6 +99,6 @@ func (inner AdmissionHandler) withSubResourceFilter(subresources ...string) Admi
if request.SubResource == "" || allowed.Has(request.SubResource) {
return inner(ctx, logger, request, startTime)
}
return admissionutils.ResponseSuccess(request.UID)
return filtered(ctx, logger, request, "admission request filtered because subresource is excluded")
}
}

View file

@ -33,14 +33,14 @@ func (inner AdmissionHandler) withProtection() AdmissionHandler {
}
newResource, oldResource, err := admissionutils.ExtractResources(nil, request.AdmissionRequest)
if err != nil {
logger.Error(err, "Failed to extract resources")
logger.Error(err, "failed to extract resources")
return admissionutils.Response(request.UID, err)
}
for _, resource := range []unstructured.Unstructured{newResource, oldResource} {
resLabels := resource.GetLabels()
if resLabels[kyvernov1.LabelAppManagedBy] == kyvernov1.ValueKyvernoApp {
if request.UserInfo.Username != kyvernoUsername {
logger.Info("Access to the resource not authorized, this is a kyverno managed resource and should be altered only by kyverno")
logger.V(2).Info("access to the resource not authorized, this is a kyverno managed resource and should be altered only by kyverno")
return admissionutils.Response(request.UID, errors.New("A kyverno managed resource can only be modified by kyverno"))
}
}

View file

@ -83,6 +83,11 @@ func (inner AdmissionHandler) WithTrace(name string) AdmissionHandler {
tracing.RequestRequestResourceResourceKey.String(tracing.StringValue(request.RequestResource.Resource)),
tracing.RequestUserNameKey.String(tracing.StringValue(request.UserInfo.Username)),
tracing.RequestUserUidKey.String(tracing.StringValue(request.UserInfo.UID)),
tracing.RequestRolesKey.StringSlice(request.Roles),
tracing.RequestClusterRolesKey.StringSlice(request.ClusterRoles),
tracing.RequestGroupKey.String(request.GroupVersionKind.Group),
tracing.RequestVersionKey.String(request.GroupVersionKind.Version),
tracing.RequestKindKey.String(request.GroupVersionKind.Kind),
tracing.RequestUserGroupsKey.StringSlice(request.UserInfo.Groups),
),
)