package client import ( "context" "go.opentelemetry.io/otel" "google.golang.org/grpc" authzlib "github.com/grafana/authlib/authz" authzv1 "github.com/grafana/authlib/authz/proto/v1" authlib "github.com/grafana/authlib/types" "github.com/prometheus/client_golang/prometheus" "github.com/grafana/grafana/pkg/infra/log" authzextv1 "github.com/grafana/grafana/pkg/services/authz/proto/v1" "github.com/grafana/grafana/pkg/services/authz/zanzana" ) var _ authlib.AccessClient = (*Client)(nil) var _ zanzana.Client = (*Client)(nil) var tracer = otel.Tracer("github.com/grafana/grafana/pkg/services/authz/zanzana/client") type Client struct { logger log.Logger authz authzv1.AuthzServiceClient authzext authzextv1.AuthzExtentionServiceClient authzlibclient *authzlib.ClientImpl metrics *clientMetrics } func New(cc grpc.ClientConnInterface, reg prometheus.Registerer) (*Client, error) { authzlibclient := authzlib.NewClient(cc, authzlib.WithTracerClientOption(tracer)) c := &Client{ authzlibclient: authzlibclient, authz: authzv1.NewAuthzServiceClient(cc), authzext: authzextv1.NewAuthzExtentionServiceClient(cc), logger: log.New("zanzana.client"), metrics: newClientMetrics(reg), } return c, nil } func (c *Client) Check(ctx context.Context, id authlib.AuthInfo, req authlib.CheckRequest, folder string) (authlib.CheckResponse, error) { ctx, span := tracer.Start(ctx, "authlib.zanzana.client.Check") defer span.End() timer := prometheus.NewTimer(c.metrics.requestDurationSeconds.WithLabelValues("Check", req.Namespace)) defer timer.ObserveDuration() return c.authzlibclient.Check(ctx, id, req, folder) } func (c *Client) Compile(ctx context.Context, id authlib.AuthInfo, req authlib.ListRequest) (authlib.ItemChecker, authlib.Zookie, error) { ctx, span := tracer.Start(ctx, "authlib.zanzana.client.Compile") defer span.End() timer := prometheus.NewTimer(c.metrics.requestDurationSeconds.WithLabelValues("Compile", req.Namespace)) defer timer.ObserveDuration() return c.authzlibclient.Compile(ctx, id, req) } func (c *Client) Read(ctx context.Context, req *authzextv1.ReadRequest) (*authzextv1.ReadResponse, error) { ctx, span := tracer.Start(ctx, "authlib.zanzana.client.Read") defer span.End() return c.authzext.Read(ctx, req) } func (c *Client) Write(ctx context.Context, req *authzextv1.WriteRequest) error { ctx, span := tracer.Start(ctx, "authlib.zanzana.client.Write") defer span.End() timer := prometheus.NewTimer(c.metrics.requestDurationSeconds.WithLabelValues("Write", req.Namespace)) defer timer.ObserveDuration() _, err := c.authzext.Write(ctx, req) return err } func (c *Client) BatchCheck(ctx context.Context, req *authzextv1.BatchCheckRequest) (*authzextv1.BatchCheckResponse, error) { ctx, span := tracer.Start(ctx, "authlib.zanzana.client.Check") defer span.End() timer := prometheus.NewTimer(c.metrics.requestDurationSeconds.WithLabelValues("BatchCheck", req.Namespace)) defer timer.ObserveDuration() return c.authzext.BatchCheck(ctx, req) } func (c *Client) WriteNew(ctx context.Context, req *authzextv1.WriteRequest) error { ctx, span := tracer.Start(ctx, "authlib.zanzana.client.Write") defer span.End() _, err := c.authzext.Write(ctx, req) return err } func (c *Client) Mutate(ctx context.Context, req *authzextv1.MutateRequest) error { ctx, span := tracer.Start(ctx, "authlib.zanzana.client.Mutate") defer span.End() timer := prometheus.NewTimer(c.metrics.requestDurationSeconds.WithLabelValues("Mutate", req.Namespace)) defer timer.ObserveDuration() _, err := c.authzext.Mutate(ctx, req) return err } func (c *Client) Query(ctx context.Context, req *authzextv1.QueryRequest) (*authzextv1.QueryResponse, error) { ctx, span := tracer.Start(ctx, "authlib.zanzana.client.Query") defer span.End() timer := prometheus.NewTimer(c.metrics.requestDurationSeconds.WithLabelValues("Query", req.Namespace)) defer timer.ObserveDuration() return c.authzext.Query(ctx, req) }