From fbf17df21bdf37cb186f25fa48a59e530b024323 Mon Sep 17 00:00:00 2001 From: Artur Wierzbicki Date: Sat, 5 Mar 2022 01:16:41 +0400 Subject: [PATCH] to revert: testing fs api in grafana ds --- .../manager/manager_integration_test.go | 2 +- pkg/tsdb/grafanads/grafana.go | 123 ++++++++++++++---- pkg/tsdb/grafanads/grafana_test.go | 27 ++-- pkg/tsdb/grafanads/testdata/jslib.golden.txt | 2 +- pkg/tsdb/grafanads/testdata/list.golden.txt | 28 ++-- .../dimensions/editors/FolderPickerTab.tsx | 2 +- 6 files changed, 133 insertions(+), 51 deletions(-) diff --git a/pkg/plugins/manager/manager_integration_test.go b/pkg/plugins/manager/manager_integration_test.go index 1bb2651f8d2..fe61b232729 100644 --- a/pkg/plugins/manager/manager_integration_test.go +++ b/pkg/plugins/manager/manager_integration_test.go @@ -87,7 +87,7 @@ func TestPluginManager_int_init(t *testing.T) { my := mysql.ProvideService(cfg, hcp) ms := mssql.ProvideService(cfg) sv2 := searchV2.ProvideService(sqlstore.InitTestDB(t)) - graf := grafanads.ProvideService(cfg, sv2) + graf := grafanads.ProvideService(cfg, sv2, nil) coreRegistry := coreplugin.ProvideCoreRegistry(am, cw, cm, es, grap, idb, lk, otsdb, pr, tmpo, td, pg, my, ms, graf) diff --git a/pkg/tsdb/grafanads/grafana.go b/pkg/tsdb/grafanads/grafana.go index 39cae38f1c8..8dabeceadd5 100644 --- a/pkg/tsdb/grafanads/grafana.go +++ b/pkg/tsdb/grafanads/grafana.go @@ -3,6 +3,7 @@ package grafanads import ( "context" "encoding/json" + "errors" "fmt" "os" "path/filepath" @@ -10,8 +11,8 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/data" - "github.com/grafana/grafana-plugin-sdk-go/experimental" "github.com/grafana/grafana/pkg/components/simplejson" + "github.com/grafana/grafana/pkg/infra/filestorage" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/searchV2" @@ -31,6 +32,8 @@ const DatasourceID = -1 // Grafana DS command. const DatasourceUID = "grafana" +const publicFilestorageBackend = "public" + // Make sure Service implements required interfaces. // This is important to do since otherwise we will only get a // not implemented error response from plugin at runtime. @@ -40,12 +43,14 @@ var ( logger = log.New("tsdb.grafana") ) -func ProvideService(cfg *setting.Cfg, search searchV2.SearchService) *Service { - return newService(cfg, search) +func ProvideService(cfg *setting.Cfg, search searchV2.SearchService, fs filestorage.FileStorage) *Service { + return newService(cfg, search, fs) } -func newService(cfg *setting.Cfg, search searchV2.SearchService) *Service { +func newService(cfg *setting.Cfg, search searchV2.SearchService, fs filestorage.FileStorage) *Service { s := &Service{ + fs: fs, + search: search, staticRootPath: cfg.StaticRootPath, roots: []string{ "testdata", @@ -55,7 +60,7 @@ func newService(cfg *setting.Cfg, search searchV2.SearchService) *Service { "maps", "upload", // does not exist yet }, - search: search, + log: log.New("grafanads"), } return s @@ -67,6 +72,8 @@ type Service struct { staticRootPath string roots []string search searchV2.SearchService + fs filestorage.FileStorage + log log.Logger } func DataSourceModel(orgId int64) *models.DataSource { @@ -111,22 +118,63 @@ func (s *Service) CheckHealth(_ context.Context, _ *backend.CheckHealthRequest) }, nil } -func (s *Service) publicPath(path string) (string, error) { - if strings.Contains(path, "..") { - return "", fmt.Errorf("invalid string") +func (s *Service) getDirectoryFrame(path string, details bool) (*data.Frame, error) { + // Name() string // base name of the file + // Size() int64 // length in bytes for regular files; system-dependent for others + // Mode() FileMode // file mode bits + // ModTime() time.Time // modification time + // IsDir() bool // abbreviation for Mode().IsDir() + ctx := context.Background() + folders, err := s.fs.ListFolders(ctx, path, &filestorage.ListOptions{Recursive: false}) + if err != nil { + s.log.Error("failed when listing folders", "path", path, "err", err) + return nil, errors.New("unknown error") } - ok := false - for _, root := range s.roots { - if strings.HasPrefix(path, root) { - ok = true - break + filesResp, err := s.fs.ListFiles(ctx, path, nil, &filestorage.ListOptions{Recursive: false}) + if err != nil { + s.log.Error("failed when listing files", "path", path, "err", err) + return nil, errors.New("unknown error") + } + + count := len(filesResp.Files) + len(folders) + names := data.NewFieldFromFieldType(data.FieldTypeString, count) + mtype := data.NewFieldFromFieldType(data.FieldTypeString, count) + size := data.NewFieldFromFieldType(data.FieldTypeInt64, count) + modified := data.NewFieldFromFieldType(data.FieldTypeTime, count) + + names.Name = "name" + mtype.Name = "media-type" + size.Name = "size" + size.Config = &data.FieldConfig{ + Unit: "bytes", + } + modified.Name = "modified" + + for i, f := range filesResp.Files { + names.Set(i, f.Name) + mtype.Set(i, f.MimeType) + if details { + size.Set(i, f.Size) + modified.Set(i, f.Modified) } } - if !ok { - return "", fmt.Errorf("bad root path") + + for i, f := range folders { + names.Set(i, f.FullPath) + mtype.Set(i, "directory") } - return filepath.Join(s.staticRootPath, path), nil + + frame := data.NewFrame("", names, mtype) + frame.SetMeta(&data.FrameMeta{ + PathSeparator: filestorage.Delimiter, + Type: data.FrameTypeDirectoryListing, + }) + if details { + frame.Fields = append(frame.Fields, size) + frame.Fields = append(frame.Fields, modified) + } + return frame, nil } func (s *Service) doListQuery(query backend.DataQuery) backend.DataResponse { @@ -138,14 +186,23 @@ func (s *Service) doListQuery(query backend.DataQuery) backend.DataResponse { return response } - if q.Path == "" { - count := len(s.roots) + path := q.Path + if path == "" { + folders, err := s.fs.ListFolders(context.Background(), publicFilestorageBackend, nil) + if err != nil { + s.log.Error("failed when listing folders", "path", publicFilestorageBackend, "err", err) + response.Error = errors.New("unknown error") + return response + } + + count := len(folders) names := data.NewFieldFromFieldType(data.FieldTypeString, count) mtype := data.NewFieldFromFieldType(data.FieldTypeString, count) names.Name = "name" mtype.Name = "mediaType" - for i, f := range s.roots { - names.Set(i, f) + for i, f := range folders { + names.Set(i, f.FullPath) + s.log.Info("setting full path", "name", f.Name, "path", f.FullPath) mtype.Set(i, "directory") } frame := data.NewFrame("", names, mtype) @@ -154,12 +211,7 @@ func (s *Service) doListQuery(query backend.DataQuery) backend.DataResponse { }) response.Frames = data.Frames{frame} } else { - path, err := s.publicPath(q.Path) - if err != nil { - response.Error = err - return response - } - frame, err := experimental.GetDirectoryFrame(path, false) + frame, err := s.getDirectoryFrame(path, false) if err != nil { response.Error = err return response @@ -170,6 +222,24 @@ func (s *Service) doListQuery(query backend.DataQuery) backend.DataResponse { return response } +func (s *Service) publicPath(path string) (string, error) { + if strings.Contains(path, "..") { + return "", fmt.Errorf("invalid string") + } + + ok := false + for _, root := range s.roots { + if strings.HasPrefix(path, root) { + ok = true + break + } + } + if !ok { + return "", fmt.Errorf("bad root path") + } + return filepath.Join(s.staticRootPath, path), nil +} + func (s *Service) doReadQuery(query backend.DataQuery) backend.DataResponse { q := &listQueryModel{} response := backend.DataResponse{} @@ -194,6 +264,7 @@ func (s *Service) doReadQuery(query backend.DataQuery) backend.DataResponse { // nolint:gosec fileReader, err := os.Open(path) if err != nil { + s.log.Error("Failed to read file", "err", err, "path", path) response.Error = fmt.Errorf("failed to read file") return response } diff --git a/pkg/tsdb/grafanads/grafana_test.go b/pkg/tsdb/grafanads/grafana_test.go index d85b7029938..eb6086664f6 100644 --- a/pkg/tsdb/grafanads/grafana_test.go +++ b/pkg/tsdb/grafanads/grafana_test.go @@ -5,11 +5,12 @@ import ( "path" "testing" - "github.com/grafana/grafana/pkg/services/searchV2" - "github.com/grafana/grafana/pkg/setting" - "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/experimental" + "github.com/grafana/grafana/pkg/infra/filestorage" + "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/searchV2" + "github.com/grafana/grafana/pkg/setting" "github.com/stretchr/testify/require" ) @@ -19,25 +20,35 @@ func asJSON(v interface{}) json.RawMessage { } func TestReadFolderListing(t *testing.T) { - ds := newService(&setting.Cfg{StaticRootPath: "../../../public"}, searchV2.NewStubSearchService()) + features := featuremgmt.WithFeatures(featuremgmt.FlagFileStoreApi, true) + cfg := &setting.Cfg{StaticRootPath: "./../../../public"} + fs, err := filestorage.ProvideService(features, cfg) + require.NoError(t, err) + + ds := newService(&setting.Cfg{StaticRootPath: "../../../public"}, searchV2.NewStubSearchService(), fs) dr := ds.doListQuery(backend.DataQuery{ QueryType: "x", JSON: asJSON(listQueryModel{ - Path: "testdata", + Path: filestorage.Join("public", "testdata"), }), }) - err := experimental.CheckGoldenDataResponse(path.Join("testdata", "list.golden.txt"), &dr, true) + err = experimental.CheckGoldenDataResponse(path.Join("testdata", "list.golden.txt"), &dr, true) require.NoError(t, err) } func TestReadCSVFile(t *testing.T) { - ds := newService(&setting.Cfg{StaticRootPath: "../../../public"}, searchV2.NewStubSearchService()) + features := featuremgmt.WithFeatures(featuremgmt.FlagFileStoreApi, true) + cfg := &setting.Cfg{StaticRootPath: "./../../../public"} + fs, err := filestorage.ProvideService(features, cfg) + require.NoError(t, err) + + ds := newService(&setting.Cfg{StaticRootPath: "../../../public"}, searchV2.NewStubSearchService(), fs) dr := ds.doReadQuery(backend.DataQuery{ QueryType: "x", JSON: asJSON(readQueryModel{ Path: "testdata/js_libraries.csv", }), }) - err := experimental.CheckGoldenDataResponse(path.Join("testdata", "jslib.golden.txt"), &dr, true) + err = experimental.CheckGoldenDataResponse(path.Join("testdata", "jslib.golden.txt"), &dr, true) require.NoError(t, err) } diff --git a/pkg/tsdb/grafanads/testdata/jslib.golden.txt b/pkg/tsdb/grafanads/testdata/jslib.golden.txt index 08f17e7b79e..0d9d7ed4a38 100644 --- a/pkg/tsdb/grafanads/testdata/jslib.golden.txt +++ b/pkg/tsdb/grafanads/testdata/jslib.golden.txt @@ -18,4 +18,4 @@ Dimensions: 4 Fields by 6 Rows ====== TEST DATA RESPONSE (arrow base64) ====== -FRAME=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 +FRAME=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 diff --git a/pkg/tsdb/grafanads/testdata/list.golden.txt b/pkg/tsdb/grafanads/testdata/list.golden.txt index ea6cad48869..81821c75235 100644 --- a/pkg/tsdb/grafanads/testdata/list.golden.txt +++ b/pkg/tsdb/grafanads/testdata/list.golden.txt @@ -6,20 +6,20 @@ Frame[0] { } Name: Dimensions: 2 Fields by 7 Rows -+--------------------------+------------------+ -| Name: name | Name: media-type | -| Labels: | Labels: | -| Type: []string | Type: []string | -+--------------------------+------------------+ -| browser_marketshare.csv | | -| flight_info_by_state.csv | | -| gdp_per_capita.csv | | -| js_libraries.csv | | -| ohlc_dogecoin.csv | | -| population_by_state.csv | | -| weight_height.csv | | -+--------------------------+------------------+ ++--------------------------+-------------------------+ +| Name: name | Name: media-type | +| Labels: | Labels: | +| Type: []string | Type: []string | ++--------------------------+-------------------------+ +| browser_marketshare.csv | text/csv; charset=utf-8 | +| flight_info_by_state.csv | text/csv; charset=utf-8 | +| gdp_per_capita.csv | text/csv; charset=utf-8 | +| js_libraries.csv | text/csv; charset=utf-8 | +| ohlc_dogecoin.csv | text/csv; charset=utf-8 | +| population_by_state.csv | text/csv; charset=utf-8 | +| weight_height.csv | text/csv; charset=utf-8 | ++--------------------------+-------------------------+ ====== TEST DATA RESPONSE (arrow base64) ====== -FRAME=QVJST1cxAAD/////uAEAABAAAAAAAAoADgAMAAsABAAKAAAAFAAAAAAAAAEDAAoADAAAAAgABAAKAAAACAAAAKQAAAADAAAATAAAACgAAAAEAAAA0P7//wgAAAAMAAAAAAAAAAAAAAAFAAAAcmVmSWQAAADw/v//CAAAAAwAAAAAAAAAAAAAAAQAAABuYW1lAAAAABD///8IAAAAPAAAADAAAAB7InR5cGUiOiJkaXJlY3RvcnktbGlzdGluZyIsInBhdGhTZXBhcmF0b3IiOiIvIn0AAAAABAAAAG1ldGEAAAAAAgAAAHwAAAAEAAAAnv///xQAAABAAAAAQAAAAAAAAAU8AAAAAQAAAAQAAACM////CAAAABQAAAAKAAAAbWVkaWEtdHlwZQAABAAAAG5hbWUAAAAAAAAAAIj///8KAAAAbWVkaWEtdHlwZQAAAAASABgAFAAAABMADAAAAAgABAASAAAAFAAAAEQAAABIAAAAAAAABUQAAAABAAAADAAAAAgADAAIAAQACAAAAAgAAAAQAAAABAAAAG5hbWUAAAAABAAAAG5hbWUAAAAAAAAAAAQABAAEAAAABAAAAG5hbWUAAAAA/////9gAAAAUAAAAAAAAAAwAFgAUABMADAAEAAwAAADQAAAAAAAAABQAAAAAAAADAwAKABgADAAIAAQACgAAABQAAAB4AAAABwAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAAACQAAAAAAAAALAAAAAAAAAAAAAAAAAAAACwAAAAAAAAACAAAAAAAAAA0AAAAAAAAAAAAAAAAAAAAAAAAAACAAAABwAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAFwAAAC8AAABBAAAAUQAAAGIAAAB5AAAAigAAAGJyb3dzZXJfbWFya2V0c2hhcmUuY3N2ZmxpZ2h0X2luZm9fYnlfc3RhdGUuY3N2Z2RwX3Blcl9jYXBpdGEuY3N2anNfbGlicmFyaWVzLmNzdm9obGNfZG9nZWNvaW4uY3N2cG9wdWxhdGlvbl9ieV9zdGF0ZS5jc3Z3ZWlnaHRfaGVpZ2h0LmNzdgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAwAFAASAAwACAAEAAwAAAAQAAAALAAAADwAAAAAAAMAAQAAAMgBAAAAAAAA4AAAAAAAAADQAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAMAAAACAAEAAoAAAAIAAAApAAAAAMAAABMAAAAKAAAAAQAAADQ/v//CAAAAAwAAAAAAAAAAAAAAAUAAAByZWZJZAAAAPD+//8IAAAADAAAAAAAAAAAAAAABAAAAG5hbWUAAAAAEP///wgAAAA8AAAAMAAAAHsidHlwZSI6ImRpcmVjdG9yeS1saXN0aW5nIiwicGF0aFNlcGFyYXRvciI6Ii8ifQAAAAAEAAAAbWV0YQAAAAACAAAAfAAAAAQAAACe////FAAAAEAAAABAAAAAAAAABTwAAAABAAAABAAAAIz///8IAAAAFAAAAAoAAABtZWRpYS10eXBlAAAEAAAAbmFtZQAAAAAAAAAAiP///woAAABtZWRpYS10eXBlAAAAABIAGAAUAAAAEwAMAAAACAAEABIAAAAUAAAARAAAAEgAAAAAAAAFRAAAAAEAAAAMAAAACAAMAAgABAAIAAAACAAAABAAAAAEAAAAbmFtZQAAAAAEAAAAbmFtZQAAAAAAAAAABAAEAAQAAAAEAAAAbmFtZQAAAADoAQAAQVJST1cx +FRAME=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 diff --git a/public/app/features/dimensions/editors/FolderPickerTab.tsx b/public/app/features/dimensions/editors/FolderPickerTab.tsx index c3e9ae05155..5f52a623e6c 100644 --- a/public/app/features/dimensions/editors/FolderPickerTab.tsx +++ b/public/app/features/dimensions/editors/FolderPickerTab.tsx @@ -73,7 +73,7 @@ export const FolderPickerTab = (props: Props) => { getDatasourceSrv() .get('-- Grafana --') .then((ds) => { - (ds as GrafanaDatasource).listFiles(folder).subscribe({ + (ds as GrafanaDatasource).listFiles(`/public/${folder}`).subscribe({ next: (frame) => { const cards: ResourceItem[] = []; frame.forEach((item) => {