From 3dfa49b37654469a53952934c10317ab781636ea Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Thu, 3 Nov 2022 16:35:20 -0700 Subject: [PATCH] Playlist: cleanup object store implementation (#58201) --- pkg/services/export/object_store.go | 4 +- .../playlist/playlistimpl/object_store.go | 47 ++++++++++--------- pkg/services/store/auth.go | 6 +++ public/app/features/playlist/PlaylistForm.tsx | 17 +++++-- 4 files changed, 48 insertions(+), 26 deletions(-) diff --git a/pkg/services/export/object_store.go b/pkg/services/export/object_store.go index 360021ed8ea..990c4aca0c3 100644 --- a/pkg/services/export/object_store.go +++ b/pkg/services/export/object_store.go @@ -113,6 +113,8 @@ func (e *objectStoreJob) start() { e.status.Status = "error: " + err.Error() return } + e.status.Last = fmt.Sprintf("export %d dashboards", len(dashInfo)) + e.broadcaster(e.status) for _, dash := range dashInfo { rowUser.OrgID = dash.OrgID @@ -261,7 +263,7 @@ func (e *objectStoreJob) getDashboards(ctx context.Context) ([]dashInfo, error) e.broadcaster(e.status) dash := make([]dashInfo, 0) - rows, err := e.sess.Query(ctx, "SELECT org_id,uid,data,updated_by FROM dashboard WHERE is_folder=0") + rows, err := e.sess.Query(ctx, "SELECT org_id,uid,data,updated_by FROM dashboard WHERE is_folder=false") if err != nil { return nil, err } diff --git a/pkg/services/playlist/playlistimpl/object_store.go b/pkg/services/playlist/playlistimpl/object_store.go index 45a3903eec1..ad7b867c0a0 100644 --- a/pkg/services/playlist/playlistimpl/object_store.go +++ b/pkg/services/playlist/playlistimpl/object_store.go @@ -27,7 +27,12 @@ type objectStoreImpl struct { var _ playlist.Service = &objectStoreImpl{} func (s *objectStoreImpl) sync() { - rows, err := s.sess.Query(context.Background(), "SELECT org_id,uid FROM playlist ORDER BY org_id asc") + type Info struct { + OrgID int64 `db:"org_id"` + UID string `db:"uid"` + } + results := []Info{} + err := s.sess.Select(context.Background(), &results, "SELECT org_id,uid FROM playlist ORDER BY org_id asc") if err != nil { fmt.Printf("error loading playlists") return @@ -35,22 +40,15 @@ func (s *objectStoreImpl) sync() { // Change the org_id with each row rowUser := &user.SignedInUser{ - Login: "?", - OrgID: 0, // gets filled in from each row - UserID: 0, + OrgID: 0, // gets filled in from each row + UserID: 0, // Admin user + IsGrafanaAdmin: true, } ctx := objectstore.ContextWithUser(context.Background(), rowUser) - uid := "" - for rows.Next() { - err = rows.Scan(&rowUser.OrgID, &uid) - if err != nil { - fmt.Printf("error loading playlists: %v", err) - return - } - + for _, info := range results { dto, err := s.sqlimpl.Get(ctx, &playlist.GetPlaylistByUidQuery{ - OrgId: rowUser.OrgID, - UID: uid, + OrgId: info.OrgID, + UID: info.UID, }) if err != nil { fmt.Printf("error loading playlist: %v", err) @@ -59,8 +57,10 @@ func (s *objectStoreImpl) sync() { body, _ := json.Marshal(dto) _, _ = s.objectstore.Write(ctx, &object.WriteObjectRequest{ GRN: &object.GRN{ - UID: uid, - Kind: models.StandardKindPlaylist, + TenantId: info.OrgID, + UID: info.UID, + Kind: models.StandardKindPlaylist, + Scope: models.ObjectStoreScopeEntity, }, Body: body, }) @@ -98,8 +98,9 @@ func (s *objectStoreImpl) Update(ctx context.Context, cmd *playlist.UpdatePlayli } _, err = s.objectstore.Write(ctx, &object.WriteObjectRequest{ GRN: &object.GRN{ - UID: rsp.Uid, - Kind: models.StandardKindPlaylist, + UID: rsp.Uid, + Kind: models.StandardKindPlaylist, + Scope: models.ObjectStoreScopeEntity, }, Body: body, }) @@ -115,8 +116,9 @@ func (s *objectStoreImpl) Delete(ctx context.Context, cmd *playlist.DeletePlayli if err == nil { _, err = s.objectstore.Delete(ctx, &object.DeleteObjectRequest{ GRN: &object.GRN{ - UID: cmd.UID, - Kind: models.StandardKindPlaylist, + UID: cmd.UID, + Kind: models.StandardKindPlaylist, + Scope: models.ObjectStoreScopeEntity, }, }) if err != nil { @@ -146,8 +148,9 @@ func (s *objectStoreImpl) GetWithoutItems(ctx context.Context, q *playlist.GetPl func (s *objectStoreImpl) Get(ctx context.Context, q *playlist.GetPlaylistByUidQuery) (*playlist.PlaylistDTO, error) { rsp, err := s.objectstore.Read(ctx, &object.ReadObjectRequest{ GRN: &object.GRN{ - UID: q.UID, - Kind: models.StandardKindPlaylist, + UID: q.UID, + Kind: models.StandardKindPlaylist, + Scope: models.ObjectStoreScopeEntity, }, WithBody: true, }) diff --git a/pkg/services/store/auth.go b/pkg/services/store/auth.go index d7258280f89..b9d7cb8bf9b 100644 --- a/pkg/services/store/auth.go +++ b/pkg/services/store/auth.go @@ -44,6 +44,12 @@ func GetUserIDString(user *user.SignedInUser) string { if user == nil { return "" } + if user.IsAnonymous { + return "anon" + } + if user.ApiKeyID > 0 { + return fmt.Sprintf("key:%d", user.UserID) + } if user.IsRealUser() { return fmt.Sprintf("user:%d:%s", user.UserID, user.Login) } diff --git a/public/app/features/playlist/PlaylistForm.tsx b/public/app/features/playlist/PlaylistForm.tsx index c930acf4ef1..9e667d5183f 100644 --- a/public/app/features/playlist/PlaylistForm.tsx +++ b/public/app/features/playlist/PlaylistForm.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from 'react'; +import React, { useMemo, useState } from 'react'; import { selectors } from '@grafana/e2e-selectors'; import { config } from '@grafana/runtime'; @@ -18,6 +18,7 @@ interface Props { } export const PlaylistForm = ({ onSubmit, playlist }: Props) => { + const [saving, setSaving] = useState(false); const { name, interval, items: propItems } = playlist; const tagOptions = useMemo(() => { return () => getGrafanaSearcher().tags({ kind: ['dashboard'] }); @@ -25,9 +26,14 @@ export const PlaylistForm = ({ onSubmit, playlist }: Props) => { const { items, addById, addByTag, deleteItem, moveItem } = usePlaylistItems(propItems); + const doSubmit = (list: Playlist) => { + setSaving(true); + onSubmit({ ...list, items }); + }; + return (
-
onSubmit({ ...list, items })} validateOn={'onBlur'}> + {({ register, errors }) => { const isDisabled = items.length === 0 || Object.keys(errors).length > 0; return ( @@ -73,7 +79,12 @@ export const PlaylistForm = ({ onSubmit, playlist }: Props) => {
-