From ba5c38b0782c5c184ff109dcd01ccf2f20758a05 Mon Sep 17 00:00:00 2001 From: Todd Treece <360020+toddtreece@users.noreply.github.com> Date: Wed, 2 Apr 2025 14:59:54 -0400 Subject: [PATCH] K8s: Remove new context from client (#103069) --- pkg/services/apiserver/client/client.go | 119 +++--------------------- 1 file changed, 12 insertions(+), 107 deletions(-) diff --git a/pkg/services/apiserver/client/client.go b/pkg/services/apiserver/client/client.go index 2d42823693b..9c1e3ea66b4 100644 --- a/pkg/services/apiserver/client/client.go +++ b/pkg/services/apiserver/client/client.go @@ -5,18 +5,13 @@ import ( "fmt" "strconv" "strings" - "time" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" - k8sUser "k8s.io/apiserver/pkg/authentication/user" - k8sRequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/client-go/dynamic" "k8s.io/client-go/rest" - "github.com/grafana/grafana/pkg/apimachinery/identity" - "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/registry/apis/dashboard/legacysearcher" "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" "github.com/grafana/grafana/pkg/services/dashboards" @@ -68,111 +63,57 @@ func (h *k8sHandler) GetNamespace(orgID int64) string { } func (h *k8sHandler) Get(ctx context.Context, name string, orgID int64, options v1.GetOptions, subresource ...string) (*unstructured.Unstructured, error) { - // create a new context - prevents issues when the request stems from the k8s api itself - // otherwise the context goes through the handlers twice and causes issues - newCtx, cancel, err := h.getK8sContext(ctx) - if err != nil { - return nil, err - } else if cancel != nil { - defer cancel() - } - - client, err := h.getClient(newCtx, orgID) + client, err := h.getClient(ctx, orgID) if err != nil { return nil, err } - return client.Get(newCtx, name, options, subresource...) + return client.Get(ctx, name, options, subresource...) } func (h *k8sHandler) Create(ctx context.Context, obj *unstructured.Unstructured, orgID int64) (*unstructured.Unstructured, error) { - // create a new context - prevents issues when the request stems from the k8s api itself - // otherwise the context goes through the handlers twice and causes issues - newCtx, cancel, err := h.getK8sContext(ctx) - if err != nil { - return nil, err - } else if cancel != nil { - defer cancel() - } - - client, err := h.getClient(newCtx, orgID) + client, err := h.getClient(ctx, orgID) if err != nil { return nil, err } - return client.Create(newCtx, obj, v1.CreateOptions{}) + return client.Create(ctx, obj, v1.CreateOptions{}) } func (h *k8sHandler) Update(ctx context.Context, obj *unstructured.Unstructured, orgID int64) (*unstructured.Unstructured, error) { - // create a new context - prevents issues when the request stems from the k8s api itself - // otherwise the context goes through the handlers twice and causes issues - newCtx, cancel, err := h.getK8sContext(ctx) - if err != nil { - return nil, err - } else if cancel != nil { - defer cancel() - } - - client, err := h.getClient(newCtx, orgID) + client, err := h.getClient(ctx, orgID) if err != nil { return nil, err } - return client.Update(newCtx, obj, v1.UpdateOptions{}) + return client.Update(ctx, obj, v1.UpdateOptions{}) } func (h *k8sHandler) Delete(ctx context.Context, name string, orgID int64, options v1.DeleteOptions) error { - // create a new context - prevents issues when the request stems from the k8s api itself - // otherwise the context goes through the handlers twice and causes issues - newCtx, cancel, err := h.getK8sContext(ctx) - if err != nil { - return err - } else if cancel != nil { - defer cancel() - } - - client, err := h.getClient(newCtx, orgID) + client, err := h.getClient(ctx, orgID) if err != nil { return err } - return client.Delete(newCtx, name, options) + return client.Delete(ctx, name, options) } func (h *k8sHandler) DeleteCollection(ctx context.Context, orgID int64) error { - // create a new context - prevents issues when the request stems from the k8s api itself - // otherwise the context goes through the handlers twice and causes issues - newCtx, cancel, err := h.getK8sContext(ctx) - if err != nil { - return err - } else if cancel != nil { - defer cancel() - } - - client, err := h.getClient(newCtx, orgID) + client, err := h.getClient(ctx, orgID) if err != nil { return err } - return client.DeleteCollection(newCtx, v1.DeleteOptions{}, v1.ListOptions{}) + return client.DeleteCollection(ctx, v1.DeleteOptions{}, v1.ListOptions{}) } func (h *k8sHandler) List(ctx context.Context, orgID int64, options v1.ListOptions) (*unstructured.UnstructuredList, error) { - // create a new context - prevents issues when the request stems from the k8s api itself - // otherwise the context goes through the handlers twice and causes issues - newCtx, cancel, err := h.getK8sContext(ctx) - if err != nil { - return nil, err - } else if cancel != nil { - defer cancel() - } - - client, err := h.getClient(newCtx, orgID) + client, err := h.getClient(ctx, orgID) if err != nil { return nil, err } - return client.List(newCtx, options) + return client.List(ctx, options) } func (h *k8sHandler) Search(ctx context.Context, orgID int64, in *resource.ResourceSearchRequest) (*resource.ResourceSearchResponse, error) { @@ -262,39 +203,3 @@ func (h *k8sHandler) getClient(ctx context.Context, orgID int64) (dynamic.Resour return dyn.Resource(h.gvr).Namespace(h.GetNamespace(orgID)), nil } - -func (h *k8sHandler) getK8sContext(ctx context.Context) (context.Context, context.CancelFunc, error) { - requester, requesterErr := identity.GetRequester(ctx) - if requesterErr != nil { - return nil, nil, requesterErr - } - - user, exists := k8sRequest.UserFrom(ctx) - if !exists { - // add in k8s user if not there yet - var ok bool - user, ok = requester.(k8sUser.Info) - if !ok { - return nil, nil, fmt.Errorf("could not convert user to k8s user") - } - } - - newCtx := k8sRequest.WithUser(context.Background(), user) - newCtx = log.WithContextualAttributes(newCtx, log.FromContext(ctx)) - // TODO: after GLSA token workflow is removed, make this return early - // and move the else below to be unconditional - if requesterErr == nil { - newCtxWithRequester := identity.WithRequester(newCtx, requester) - newCtx = newCtxWithRequester - } - - // inherit the deadline from the original context, if it exists - deadline, ok := ctx.Deadline() - if ok { - var newCancel context.CancelFunc - newCtx, newCancel = context.WithTimeout(newCtx, time.Until(deadline)) - return newCtx, newCancel, nil - } - - return newCtx, nil, nil -}