Datasources: Add service function to get by group, name, and namespace (#113066)
This commit is contained in:
@@ -15,6 +15,9 @@ type DataSourceService interface {
|
||||
// GetDataSource gets a datasource.
|
||||
GetDataSource(ctx context.Context, query *GetDataSourceQuery) (*DataSource, error)
|
||||
|
||||
// GetDataSourceInNamespace gets a datasource by namespace, name (datasource uid), and group (datasource type).
|
||||
GetDataSourceInNamespace(ctx context.Context, namespace, name, group string) (*DataSource, error)
|
||||
|
||||
// GetDataSources gets datasources.
|
||||
GetDataSources(ctx context.Context, query *GetDataSourcesQuery) ([]*DataSource, error)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/grafana/authlib/types"
|
||||
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/httpclient"
|
||||
@@ -30,6 +31,19 @@ func (s *FakeDataSourceService) GetDataSource(ctx context.Context, query *dataso
|
||||
return nil, datasources.ErrDataSourceNotFound
|
||||
}
|
||||
|
||||
func (s *FakeDataSourceService) GetDataSourceInNamespace(ctx context.Context, namespace, name, group string) (*datasources.DataSource, error) {
|
||||
ns, err := types.ParseNamespace(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, dataSource := range s.DataSources {
|
||||
if name == dataSource.UID && ns.OrgID == dataSource.OrgID && group == dataSource.Type {
|
||||
return dataSource, nil
|
||||
}
|
||||
}
|
||||
return nil, datasources.ErrDataSourceNotFound
|
||||
}
|
||||
|
||||
func (s *FakeDataSourceService) GetDataSources(ctx context.Context, query *datasources.GetDataSourcesQuery) ([]*datasources.DataSource, error) {
|
||||
var dataSources []*datasources.DataSource
|
||||
for _, datasource := range s.DataSources {
|
||||
|
||||
@@ -117,6 +117,8 @@ func (s *Service) Usage(ctx context.Context, scopeParams *quota.ScopeParameters)
|
||||
type DataSourceRetriever interface {
|
||||
// GetDataSource gets a datasource.
|
||||
GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) (*datasources.DataSource, error)
|
||||
// GetDataSourceInNamespace gets a datasource by namespace, name (datasource uid), and group (datasource type).
|
||||
GetDataSourceInNamespace(ctx context.Context, namespace, name, group string) (*datasources.DataSource, error)
|
||||
}
|
||||
|
||||
// NewNameScopeResolver provides an ScopeAttributeResolver able to
|
||||
@@ -176,6 +178,10 @@ func (s *Service) GetDataSource(ctx context.Context, query *datasources.GetDataS
|
||||
return s.SQLStore.GetDataSource(ctx, query)
|
||||
}
|
||||
|
||||
func (s *Service) GetDataSourceInNamespace(ctx context.Context, namespace, name, group string) (*datasources.DataSource, error) {
|
||||
return s.SQLStore.GetDataSourceInNamespace(ctx, namespace, name, group)
|
||||
}
|
||||
|
||||
func (s *Service) GetDataSources(ctx context.Context, query *datasources.GetDataSourcesQuery) ([]*datasources.DataSource, error) {
|
||||
return s.SQLStore.GetDataSources(ctx, query)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/ini.v1"
|
||||
|
||||
"github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
@@ -63,6 +64,19 @@ func (d *dataSourceMockRetriever) GetDataSource(ctx context.Context, query *data
|
||||
return nil, datasources.ErrDataSourceNotFound
|
||||
}
|
||||
|
||||
func (d *dataSourceMockRetriever) GetDataSourceInNamespace(ctx context.Context, namespace, name, group string) (*datasources.DataSource, error) {
|
||||
ns, err := types.ParseNamespace(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, dataSource := range d.res {
|
||||
if name == dataSource.UID && ns.OrgID == dataSource.OrgID && group == dataSource.Type {
|
||||
return dataSource, nil
|
||||
}
|
||||
}
|
||||
return nil, datasources.ErrDataSourceNotFound
|
||||
}
|
||||
|
||||
func TestIntegrationService_AddDataSource(t *testing.T) {
|
||||
testutil.SkipIntegrationTestInShortMode(t)
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/util/xorm"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
@@ -24,6 +25,7 @@ import (
|
||||
// Store is the interface for the datasource Service's storage.
|
||||
type Store interface {
|
||||
GetDataSource(context.Context, *datasources.GetDataSourceQuery) (*datasources.DataSource, error)
|
||||
GetDataSourceInNamespace(context.Context, string, string, string) (*datasources.DataSource, error)
|
||||
GetDataSources(context.Context, *datasources.GetDataSourcesQuery) ([]*datasources.DataSource, error)
|
||||
GetDataSourcesByType(context.Context, *datasources.GetDataSourcesByTypeQuery) ([]*datasources.DataSource, error)
|
||||
DeleteDataSource(context.Context, *datasources.DeleteDataSourceCommand) error
|
||||
@@ -90,6 +92,41 @@ func (ss *SqlStore) getDataSource(_ context.Context, query *datasources.GetDataS
|
||||
return datasource, nil
|
||||
}
|
||||
|
||||
func (ss *SqlStore) GetDataSourceInNamespace(ctx context.Context, namespace, name, group string) (*datasources.DataSource, error) {
|
||||
var (
|
||||
dataSource *datasources.DataSource
|
||||
err error
|
||||
)
|
||||
ns, err := types.ParseNamespace(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dataSource, ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
dataSource, err = ss.getDataSourceInGroup(ctx, ns.OrgID, name, group, sess)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func (ss *SqlStore) getDataSourceInGroup(_ context.Context, orgID int64, name, group string, sess *db.Session) (*datasources.DataSource, error) {
|
||||
datasource := &datasources.DataSource{
|
||||
OrgID: orgID,
|
||||
Type: group,
|
||||
UID: name,
|
||||
}
|
||||
has, err := sess.Get(datasource)
|
||||
|
||||
if err != nil {
|
||||
ss.logger.Error("Failed getting data source", "err", err, "name", name, "orgId", orgID, "group", group)
|
||||
return nil, err
|
||||
} else if !has {
|
||||
ss.logger.Debug("Data source not found", "name", name, "orgId", orgID, "group", group)
|
||||
return nil, datasources.ErrDataSourceNotFound
|
||||
}
|
||||
|
||||
return datasource, nil
|
||||
}
|
||||
|
||||
func (ss *SqlStore) GetDataSources(ctx context.Context, query *datasources.GetDataSourcesQuery) ([]*datasources.DataSource, error) {
|
||||
var (
|
||||
sess *xorm.Session
|
||||
|
||||
@@ -407,6 +407,43 @@ func TestIntegrationDataAccess(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("GetDataSourceInGroup", func(t *testing.T) {
|
||||
t.Run("Only returns datasource of specified type", func(t *testing.T) {
|
||||
db := db.InitTestDB(t)
|
||||
ss := SqlStore{db: db, logger: log.NewNopLogger()}
|
||||
|
||||
ds, err := ss.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
|
||||
OrgID: 10,
|
||||
Name: "Elasticsearch",
|
||||
Type: datasources.DS_ES,
|
||||
Access: datasources.DS_ACCESS_DIRECT,
|
||||
URL: "http://test",
|
||||
Database: "site",
|
||||
ReadOnly: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
ds2, err := ss.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
|
||||
OrgID: 10,
|
||||
Name: "Graphite",
|
||||
Type: datasources.DS_GRAPHITE,
|
||||
Access: datasources.DS_ACCESS_DIRECT,
|
||||
URL: "http://test",
|
||||
Database: "site",
|
||||
ReadOnly: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
dataSource, err := ss.GetDataSourceInNamespace(context.Background(), "org-10", ds.UID, datasources.DS_ES)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, ds.UID, dataSource.UID)
|
||||
|
||||
_, err = ss.GetDataSourceInNamespace(context.Background(), "org-10", ds2.UID, datasources.DS_ES)
|
||||
require.Error(t, err)
|
||||
require.IsType(t, datasources.ErrDataSourceNotFound, err)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("GetDataSourcesByType", func(t *testing.T) {
|
||||
t.Run("Only returns datasources of specified type", func(t *testing.T) {
|
||||
db := db.InitTestDB(t)
|
||||
|
||||
Reference in New Issue
Block a user