* first round of entityapi updates - quote column names and clean up insert/update queries - replace grn with guid - streamline table structure fixes streamline entity history move EntitySummary into proto remove EntitySummary add guid to json fix tests change DB_Uuid to DB_NVarchar fix folder test convert interface to any more cleanup start entity store under grafana-apiserver dskit target CRUD working, kind of rough cut of wiring entity api to kube-apiserver fake grafana user in context add key to entity list working revert unnecessary changes move entity storage files to their own package, clean up use accessor to read/write grafana annotations implement separate Create and Update functions * go mod tidy * switch from Kind to resource * basic grpc storage server * basic support for grpc entity store * don't connect to database unless it's needed, pass user identity over grpc * support getting user from k8s context, fix some mysql issues * assign owner to snowflake dependency * switch from ulid to uuid for guids * cleanup, rename Search to List * remove entityListResult * EntityAPI: remove extra user abstraction (#79033) * remove extra user abstraction * add test stub (but * move grpc context setup into client wrapper, fix lint issue * remove unused constants * remove custom json stuff * basic list filtering, add todo * change target to storage-server, allow entityStore flag in prod mode * fix issue with Update * EntityAPI: make test work, need to resolve expected differences (#79123) * make test work, need to resolve expected differences * remove the fields not supported by legacy * sanitize out the bits legacy does not support * sanitize out the bits legacy does not support --------- Co-authored-by: Ryan McKinley <ryantxu@gmail.com> * update feature toggle generated files * remove unused http headers * update feature flag strategy * devmode * update readme * spelling * readme --------- Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
111 lines
3.4 KiB
Go
111 lines
3.4 KiB
Go
package entity
|
|
|
|
import (
|
|
context "context"
|
|
"strconv"
|
|
|
|
grpc "google.golang.org/grpc"
|
|
codes "google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/metadata"
|
|
status "google.golang.org/grpc/status"
|
|
|
|
"github.com/grafana/grafana/pkg/infra/appcontext"
|
|
)
|
|
|
|
var _ EntityStoreServer = (*entityStoreClientWrapper)(nil)
|
|
|
|
// wrapper for EntityStoreClient that implements EntityStore interface
|
|
type entityStoreClientWrapper struct {
|
|
EntityStoreClient
|
|
}
|
|
|
|
func (c *entityStoreClientWrapper) Read(ctx context.Context, in *ReadEntityRequest) (*Entity, error) {
|
|
ctx, err := c.wrapContext(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return c.EntityStoreClient.Read(ctx, in)
|
|
}
|
|
func (c *entityStoreClientWrapper) BatchRead(ctx context.Context, in *BatchReadEntityRequest) (*BatchReadEntityResponse, error) {
|
|
ctx, err := c.wrapContext(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return c.EntityStoreClient.BatchRead(ctx, in)
|
|
}
|
|
func (c *entityStoreClientWrapper) Write(ctx context.Context, in *WriteEntityRequest) (*WriteEntityResponse, error) {
|
|
ctx, err := c.wrapContext(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return c.EntityStoreClient.Write(ctx, in)
|
|
}
|
|
func (c *entityStoreClientWrapper) Create(ctx context.Context, in *CreateEntityRequest) (*CreateEntityResponse, error) {
|
|
ctx, err := c.wrapContext(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return c.EntityStoreClient.Create(ctx, in)
|
|
}
|
|
func (c *entityStoreClientWrapper) Update(ctx context.Context, in *UpdateEntityRequest) (*UpdateEntityResponse, error) {
|
|
ctx, err := c.wrapContext(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return c.EntityStoreClient.Update(ctx, in)
|
|
}
|
|
func (c *entityStoreClientWrapper) Delete(ctx context.Context, in *DeleteEntityRequest) (*DeleteEntityResponse, error) {
|
|
ctx, err := c.wrapContext(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return c.EntityStoreClient.Delete(ctx, in)
|
|
}
|
|
func (c *entityStoreClientWrapper) History(ctx context.Context, in *EntityHistoryRequest) (*EntityHistoryResponse, error) {
|
|
ctx, err := c.wrapContext(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return c.EntityStoreClient.History(ctx, in)
|
|
}
|
|
func (c *entityStoreClientWrapper) List(ctx context.Context, in *EntityListRequest) (*EntityListResponse, error) {
|
|
ctx, err := c.wrapContext(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return c.EntityStoreClient.List(ctx, in)
|
|
}
|
|
func (c *entityStoreClientWrapper) Watch(*EntityWatchRequest, EntityStore_WatchServer) error {
|
|
return status.Errorf(codes.Unimplemented, "method Watch not implemented")
|
|
}
|
|
|
|
func (c *entityStoreClientWrapper) wrapContext(ctx context.Context) (context.Context, error) {
|
|
user, err := appcontext.User(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// set grpc metadata into the context to pass to the grpc server
|
|
ctx = metadata.NewOutgoingContext(ctx, metadata.Pairs(
|
|
"grafana-idtoken", user.IDToken,
|
|
"grafana-userid", strconv.FormatInt(user.UserID, 10),
|
|
"grafana-orgid", strconv.FormatInt(user.OrgID, 10),
|
|
"grafana-login", user.Login,
|
|
))
|
|
|
|
return ctx, nil
|
|
}
|
|
|
|
// TEMPORARY... while we split this into a new service (see below)
|
|
func (c *entityStoreClientWrapper) AdminWrite(ctx context.Context, in *AdminWriteEntityRequest) (*WriteEntityResponse, error) {
|
|
ctx, err := c.wrapContext(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return c.EntityStoreClient.AdminWrite(ctx, in)
|
|
}
|
|
|
|
func NewEntityStoreClientWrapper(cc grpc.ClientConnInterface) EntityStoreServer {
|
|
return &entityStoreClientWrapper{&entityStoreClient{cc}}
|
|
}
|