backend/datasources: move datasources models into the datasources service package (#51267)

* backend/datasources: move datasources models into the datasources service pkg
This commit is contained in:
Kristin Laemmert 2022-06-27 12:23:15 -04:00 committed by GitHub
parent 78c012df65
commit 945f015770
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
77 changed files with 728 additions and 660 deletions

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
"github.com/grafana/grafana/pkg/services/search"
@ -151,7 +152,7 @@ func (hs *HTTPServer) AlertTest(c *models.ReqContext) response.Response {
if errors.As(err, &validationErr) {
return response.Error(422, validationErr.Error(), nil)
}
if errors.Is(err, models.ErrDataSourceAccessDenied) {
if errors.Is(err, datasources.ErrDataSourceAccessDenied) {
return response.Error(403, "Access denied to datasource", err)
}
return response.Error(500, "Failed to test rule", err)

View File

@ -11,25 +11,25 @@ import (
"testing"
"github.com/gofrs/uuid"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/localcache"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/datasources"
fakeDatasources "github.com/grafana/grafana/pkg/services/datasources/fakes"
"github.com/grafana/grafana/pkg/services/datasources/service"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/query"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web/webtest"
fakeDatasources "github.com/grafana/grafana/pkg/services/datasources/fakes"
)
func TestAPIGetPublicDashboard(t *testing.T) {
@ -259,7 +259,7 @@ func TestAPIQueryPublicDashboard(t *testing.T) {
qds := query.ProvideService(
nil,
&fakeDatasources.FakeCacheService{
DataSources: []*models.DataSource{
DataSources: []*datasources.DataSource{
{Uid: "mysqlds"},
{Uid: "promds"},
{Uid: "promds2"},
@ -547,12 +547,12 @@ func TestIntegrationUnauthenticatedUserCanGetPubdashPanelQueryData(t *testing.T)
)
scenario.hs.queryDataService = qds
_ = db.AddDataSource(context.Background(), &models.AddDataSourceCommand{
_ = db.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
Uid: "ds1",
OrgId: 1,
Name: "laban",
Type: models.DS_MYSQL,
Access: models.DS_ACCESS_DIRECT,
Type: datasources.DS_MYSQL,
Access: datasources.DS_ACCESS_DIRECT,
Url: "http://test",
Database: "site",
ReadOnly: true,

View File

@ -8,7 +8,7 @@ import (
"strings"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/tsdb/mssql"
)
@ -16,20 +16,20 @@ var logger = log.New("datasource")
// requiredURL contains the set of data sources that require a URL.
var requiredURL = map[string]bool{
models.DS_GRAPHITE: true,
models.DS_INFLUXDB: true,
models.DS_INFLUXDB_08: true,
models.DS_ES: true,
models.DS_PROMETHEUS: true,
models.DS_ALERTMANAGER: true,
models.DS_JAEGER: true,
models.DS_LOKI: true,
models.DS_OPENTSDB: true,
models.DS_TEMPO: true,
models.DS_ZIPKIN: true,
models.DS_MYSQL: true,
models.DS_POSTGRES: true,
models.DS_MSSQL: true,
datasources.DS_GRAPHITE: true,
datasources.DS_INFLUXDB: true,
datasources.DS_INFLUXDB_08: true,
datasources.DS_ES: true,
datasources.DS_PROMETHEUS: true,
datasources.DS_ALERTMANAGER: true,
datasources.DS_JAEGER: true,
datasources.DS_LOKI: true,
datasources.DS_OPENTSDB: true,
datasources.DS_TEMPO: true,
datasources.DS_ZIPKIN: true,
datasources.DS_MYSQL: true,
datasources.DS_POSTGRES: true,
datasources.DS_MSSQL: true,
}
// URLValidationError represents an error from validating a data source URL.

View File

@ -10,6 +10,7 @@ import (
"strconv"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/api/datasource"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
@ -24,10 +25,10 @@ import (
)
var datasourcesLogger = log.New("datasources")
var secretsPluginError models.ErrDatasourceSecretsPluginUserFriendly
var secretsPluginError datasources.ErrDatasourceSecretsPluginUserFriendly
func (hs *HTTPServer) GetDataSources(c *models.ReqContext) response.Response {
query := models.GetDataSourcesQuery{OrgId: c.OrgId, DataSourceLimit: hs.Cfg.DataSourceLimit}
query := datasources.GetDataSourcesQuery{OrgId: c.OrgId, DataSourceLimit: hs.Cfg.DataSourceLimit}
if err := hs.DataSourcesService.GetDataSources(c.Req.Context(), &query); err != nil {
return response.Error(500, "Failed to query datasources", err)
@ -78,16 +79,16 @@ func (hs *HTTPServer) GetDataSourceById(c *models.ReqContext) response.Response
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
query := models.GetDataSourceQuery{
query := datasources.GetDataSourceQuery{
Id: id,
OrgId: c.OrgId,
}
if err := hs.DataSourcesService.GetDataSource(c.Req.Context(), &query); err != nil {
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
return response.Error(404, "Data source not found", nil)
}
if errors.Is(err, models.ErrDataSourceIdentifierNotSet) {
if errors.Is(err, datasources.ErrDataSourceIdentifierNotSet) {
return response.Error(400, "Datasource id is missing", nil)
}
return response.Error(500, "Failed to query datasources", err)
@ -114,7 +115,7 @@ func (hs *HTTPServer) DeleteDataSourceById(c *models.ReqContext) response.Respon
ds, err := hs.getRawDataSourceById(c.Req.Context(), id, c.OrgId)
if err != nil {
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
return response.Error(404, "Data source not found", nil)
}
return response.Error(400, "Failed to delete datasource", nil)
@ -124,7 +125,7 @@ func (hs *HTTPServer) DeleteDataSourceById(c *models.ReqContext) response.Respon
return response.Error(403, "Cannot delete read-only data source", nil)
}
cmd := &models.DeleteDataSourceCommand{ID: id, OrgID: c.OrgId, Name: ds.Name}
cmd := &datasources.DeleteDataSourceCommand{ID: id, OrgID: c.OrgId, Name: ds.Name}
err = hs.DataSourcesService.DeleteDataSource(c.Req.Context(), cmd)
if err != nil {
@ -144,7 +145,7 @@ func (hs *HTTPServer) GetDataSourceByUID(c *models.ReqContext) response.Response
ds, err := hs.getRawDataSourceByUID(c.Req.Context(), web.Params(c.Req)[":uid"], c.OrgId)
if err != nil {
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
return response.Error(http.StatusNotFound, "Data source not found", nil)
}
return response.Error(http.StatusInternalServerError, "Failed to query datasource", err)
@ -168,7 +169,7 @@ func (hs *HTTPServer) DeleteDataSourceByUID(c *models.ReqContext) response.Respo
ds, err := hs.getRawDataSourceByUID(c.Req.Context(), uid, c.OrgId)
if err != nil {
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
return response.Error(404, "Data source not found", nil)
}
return response.Error(400, "Failed to delete datasource", nil)
@ -178,7 +179,7 @@ func (hs *HTTPServer) DeleteDataSourceByUID(c *models.ReqContext) response.Respo
return response.Error(403, "Cannot delete read-only data source", nil)
}
cmd := &models.DeleteDataSourceCommand{UID: uid, OrgID: c.OrgId, Name: ds.Name}
cmd := &datasources.DeleteDataSourceCommand{UID: uid, OrgID: c.OrgId, Name: ds.Name}
err = hs.DataSourcesService.DeleteDataSource(c.Req.Context(), cmd)
if err != nil {
@ -204,9 +205,9 @@ func (hs *HTTPServer) DeleteDataSourceByName(c *models.ReqContext) response.Resp
return response.Error(400, "Missing valid datasource name", nil)
}
getCmd := &models.GetDataSourceQuery{Name: name, OrgId: c.OrgId}
getCmd := &datasources.GetDataSourceQuery{Name: name, OrgId: c.OrgId}
if err := hs.DataSourcesService.GetDataSource(c.Req.Context(), getCmd); err != nil {
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
return response.Error(404, "Data source not found", nil)
}
return response.Error(500, "Failed to delete datasource", err)
@ -216,7 +217,7 @@ func (hs *HTTPServer) DeleteDataSourceByName(c *models.ReqContext) response.Resp
return response.Error(403, "Cannot delete read-only data source", nil)
}
cmd := &models.DeleteDataSourceCommand{Name: name, OrgID: c.OrgId}
cmd := &datasources.DeleteDataSourceCommand{Name: name, OrgID: c.OrgId}
err := hs.DataSourcesService.DeleteDataSource(c.Req.Context(), cmd)
if err != nil {
if errors.As(err, &secretsPluginError) {
@ -243,7 +244,7 @@ func validateURL(cmdType string, url string) response.Response {
// POST /api/datasources/
func (hs *HTTPServer) AddDataSource(c *models.ReqContext) response.Response {
cmd := models.AddDataSourceCommand{}
cmd := datasources.AddDataSourceCommand{}
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
@ -258,7 +259,7 @@ func (hs *HTTPServer) AddDataSource(c *models.ReqContext) response.Response {
}
if err := hs.DataSourcesService.AddDataSource(c.Req.Context(), &cmd); err != nil {
if errors.Is(err, models.ErrDataSourceNameExists) || errors.Is(err, models.ErrDataSourceUidExists) {
if errors.Is(err, datasources.ErrDataSourceNameExists) || errors.Is(err, datasources.ErrDataSourceUidExists) {
return response.Error(409, err.Error(), err)
}
@ -280,7 +281,7 @@ func (hs *HTTPServer) AddDataSource(c *models.ReqContext) response.Response {
// PUT /api/datasources/:id
func (hs *HTTPServer) UpdateDataSourceByID(c *models.ReqContext) response.Response {
cmd := models.UpdateDataSourceCommand{}
cmd := datasources.UpdateDataSourceCommand{}
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
@ -296,7 +297,7 @@ func (hs *HTTPServer) UpdateDataSourceByID(c *models.ReqContext) response.Respon
ds, err := hs.getRawDataSourceById(c.Req.Context(), cmd.Id, cmd.OrgId)
if err != nil {
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
return response.Error(404, "Data source not found", nil)
}
return response.Error(500, "Failed to update datasource", err)
@ -306,7 +307,7 @@ func (hs *HTTPServer) UpdateDataSourceByID(c *models.ReqContext) response.Respon
// PUT /api/datasources/:uid
func (hs *HTTPServer) UpdateDataSourceByUID(c *models.ReqContext) response.Response {
cmd := models.UpdateDataSourceCommand{}
cmd := datasources.UpdateDataSourceCommand{}
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
@ -318,7 +319,7 @@ func (hs *HTTPServer) UpdateDataSourceByUID(c *models.ReqContext) response.Respo
ds, err := hs.getRawDataSourceByUID(c.Req.Context(), web.Params(c.Req)[":uid"], c.OrgId)
if err != nil {
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
return response.Error(http.StatusNotFound, "Data source not found", nil)
}
return response.Error(http.StatusInternalServerError, "Failed to update datasource", err)
@ -327,14 +328,14 @@ func (hs *HTTPServer) UpdateDataSourceByUID(c *models.ReqContext) response.Respo
return hs.updateDataSourceByID(c, ds, cmd)
}
func (hs *HTTPServer) updateDataSourceByID(c *models.ReqContext, ds *models.DataSource, cmd models.UpdateDataSourceCommand) response.Response {
func (hs *HTTPServer) updateDataSourceByID(c *models.ReqContext, ds *datasources.DataSource, cmd datasources.UpdateDataSourceCommand) response.Response {
if ds.ReadOnly {
return response.Error(403, "Cannot update read-only data source", nil)
}
err := hs.DataSourcesService.UpdateDataSource(c.Req.Context(), &cmd)
if err != nil {
if errors.Is(err, models.ErrDataSourceUpdatingOldVersion) {
if errors.Is(err, datasources.ErrDataSourceUpdatingOldVersion) {
return response.Error(409, "Datasource has already been updated by someone else. Please reload and try again", err)
}
@ -344,13 +345,13 @@ func (hs *HTTPServer) updateDataSourceByID(c *models.ReqContext, ds *models.Data
return response.Error(500, "Failed to update datasource", err)
}
query := models.GetDataSourceQuery{
query := datasources.GetDataSourceQuery{
Id: cmd.Id,
OrgId: c.OrgId,
}
if err := hs.DataSourcesService.GetDataSource(c.Req.Context(), &query); err != nil {
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
return response.Error(404, "Data source not found", nil)
}
return response.Error(500, "Failed to query datasource", err)
@ -368,8 +369,8 @@ func (hs *HTTPServer) updateDataSourceByID(c *models.ReqContext, ds *models.Data
})
}
func (hs *HTTPServer) getRawDataSourceById(ctx context.Context, id int64, orgID int64) (*models.DataSource, error) {
query := models.GetDataSourceQuery{
func (hs *HTTPServer) getRawDataSourceById(ctx context.Context, id int64, orgID int64) (*datasources.DataSource, error) {
query := datasources.GetDataSourceQuery{
Id: id,
OrgId: orgID,
}
@ -381,8 +382,8 @@ func (hs *HTTPServer) getRawDataSourceById(ctx context.Context, id int64, orgID
return query.Result, nil
}
func (hs *HTTPServer) getRawDataSourceByUID(ctx context.Context, uid string, orgID int64) (*models.DataSource, error) {
query := models.GetDataSourceQuery{
func (hs *HTTPServer) getRawDataSourceByUID(ctx context.Context, uid string, orgID int64) (*datasources.DataSource, error) {
query := datasources.GetDataSourceQuery{
Uid: uid,
OrgId: orgID,
}
@ -396,10 +397,10 @@ func (hs *HTTPServer) getRawDataSourceByUID(ctx context.Context, uid string, org
// Get /api/datasources/name/:name
func (hs *HTTPServer) GetDataSourceByName(c *models.ReqContext) response.Response {
query := models.GetDataSourceQuery{Name: web.Params(c.Req)[":name"], OrgId: c.OrgId}
query := datasources.GetDataSourceQuery{Name: web.Params(c.Req)[":name"], OrgId: c.OrgId}
if err := hs.DataSourcesService.GetDataSource(c.Req.Context(), &query); err != nil {
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
return response.Error(404, "Data source not found", nil)
}
return response.Error(500, "Failed to query datasources", err)
@ -411,10 +412,10 @@ func (hs *HTTPServer) GetDataSourceByName(c *models.ReqContext) response.Respons
// Get /api/datasources/id/:name
func (hs *HTTPServer) GetDataSourceIdByName(c *models.ReqContext) response.Response {
query := models.GetDataSourceQuery{Name: web.Params(c.Req)[":name"], OrgId: c.OrgId}
query := datasources.GetDataSourceQuery{Name: web.Params(c.Req)[":name"], OrgId: c.OrgId}
if err := hs.DataSourcesService.GetDataSource(c.Req.Context(), &query); err != nil {
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
return response.Error(404, "Data source not found", nil)
}
return response.Error(500, "Failed to query datasources", err)
@ -437,7 +438,7 @@ func (hs *HTTPServer) CallDatasourceResource(c *models.ReqContext) {
}
ds, err := hs.DataSourceCache.GetDatasource(c.Req.Context(), datasourceID, c.SignedInUser, c.SkipCache)
if err != nil {
if errors.Is(err, models.ErrDataSourceAccessDenied) {
if errors.Is(err, datasources.ErrDataSourceAccessDenied) {
c.JsonApiErr(403, "Access denied to datasource", err)
return
}
@ -464,7 +465,7 @@ func (hs *HTTPServer) CallDatasourceResourceWithUID(c *models.ReqContext) {
ds, err := hs.DataSourceCache.GetDatasourceByUID(c.Req.Context(), dsUID, c.SignedInUser, c.SkipCache)
if err != nil {
if errors.Is(err, models.ErrDataSourceAccessDenied) {
if errors.Is(err, datasources.ErrDataSourceAccessDenied) {
c.JsonApiErr(http.StatusForbidden, "Access denied to datasource", err)
return
}
@ -481,7 +482,7 @@ func (hs *HTTPServer) CallDatasourceResourceWithUID(c *models.ReqContext) {
hs.callPluginResourceWithDataSource(c, plugin.ID, ds)
}
func (hs *HTTPServer) convertModelToDtos(ctx context.Context, ds *models.DataSource) dtos.DataSource {
func (hs *HTTPServer) convertModelToDtos(ctx context.Context, ds *datasources.DataSource) dtos.DataSource {
dto := dtos.DataSource{
Id: ds.Id,
UID: ds.Uid,
@ -526,7 +527,7 @@ func (hs *HTTPServer) CheckDatasourceHealthWithUID(c *models.ReqContext) respons
ds, err := hs.DataSourceCache.GetDatasourceByUID(c.Req.Context(), dsUID, c.SignedInUser, c.SkipCache)
if err != nil {
if errors.Is(err, models.ErrDataSourceAccessDenied) {
if errors.Is(err, datasources.ErrDataSourceAccessDenied) {
return response.Error(http.StatusForbidden, "Access denied to datasource", err)
}
return response.Error(http.StatusInternalServerError, "Unable to load datasource metadata", err)
@ -544,7 +545,7 @@ func (hs *HTTPServer) CheckDatasourceHealth(c *models.ReqContext) response.Respo
ds, err := hs.DataSourceCache.GetDatasource(c.Req.Context(), datasourceID, c.SignedInUser, c.SkipCache)
if err != nil {
if errors.Is(err, models.ErrDataSourceAccessDenied) {
if errors.Is(err, datasources.ErrDataSourceAccessDenied) {
return response.Error(http.StatusForbidden, "Access denied to datasource", err)
}
return response.Error(http.StatusInternalServerError, "Unable to load datasource metadata", err)
@ -552,7 +553,7 @@ func (hs *HTTPServer) CheckDatasourceHealth(c *models.ReqContext) response.Respo
return hs.checkDatasourceHealth(c, ds)
}
func (hs *HTTPServer) checkDatasourceHealth(c *models.ReqContext, ds *models.DataSource) response.Response {
func (hs *HTTPServer) checkDatasourceHealth(c *models.ReqContext, ds *datasources.DataSource) response.Response {
plugin, exists := hs.pluginStore.Plugin(c.Req.Context(), ds.Type)
if !exists {
return response.Error(http.StatusInternalServerError, "Unable to find datasource plugin", nil)
@ -625,8 +626,8 @@ func (hs *HTTPServer) checkDatasourceHealth(c *models.ReqContext, ds *models.Dat
return response.JSON(http.StatusOK, payload)
}
func (hs *HTTPServer) decryptSecureJsonDataFn(ctx context.Context) func(ds *models.DataSource) map[string]string {
return func(ds *models.DataSource) map[string]string {
func (hs *HTTPServer) decryptSecureJsonDataFn(ctx context.Context) func(ds *datasources.DataSource) map[string]string {
return func(ds *datasources.DataSource) map[string]string {
decryptedJsonData, err := hs.DataSourcesService.DecryptedValues(ctx, ds)
if err != nil {
hs.log.Error("Failed to decrypt secure json data", "error", err)
@ -635,18 +636,18 @@ func (hs *HTTPServer) decryptSecureJsonDataFn(ctx context.Context) func(ds *mode
}
}
func (hs *HTTPServer) filterDatasourcesByQueryPermission(ctx context.Context, user *models.SignedInUser, datasources []*models.DataSource) ([]*models.DataSource, error) {
query := models.DatasourcesPermissionFilterQuery{
func (hs *HTTPServer) filterDatasourcesByQueryPermission(ctx context.Context, user *models.SignedInUser, ds []*datasources.DataSource) ([]*datasources.DataSource, error) {
query := datasources.DatasourcesPermissionFilterQuery{
User: user,
Datasources: datasources,
Datasources: ds,
}
query.Result = datasources
query.Result = ds
if err := hs.DatasourcePermissionsService.FilterDatasourcesBasedOnQueryPermissions(ctx, &query); err != nil {
if !errors.Is(err, permissions.ErrNotImplemented) {
return nil, err
}
return datasources, nil
return ds, nil
}
return query.Result, nil

View File

@ -34,7 +34,7 @@ func TestDataSourcesProxy_userLoggedIn(t *testing.T) {
mockDatasourcePermissionService := permissions.NewMockDatasourcePermissionService()
loggedInUserScenario(t, "When calling GET on", "/api/datasources/", "/api/datasources/", func(sc *scenarioContext) {
// Stubs the database query
ds := []*models.DataSource{
ds := []*datasources.DataSource{
{Name: "mmm"},
{Name: "ZZZ"},
{Name: "BBB"},
@ -85,7 +85,7 @@ func TestAddDataSource_InvalidURL(t *testing.T) {
}
sc.m.Post(sc.url, routing.Wrap(func(c *models.ReqContext) response.Response {
c.Req.Body = mockRequestBody(models.AddDataSourceCommand{
c.Req.Body = mockRequestBody(datasources.AddDataSourceCommand{
Name: "Test",
Url: "invalid:url",
Access: "direct",
@ -106,14 +106,14 @@ func TestAddDataSource_URLWithoutProtocol(t *testing.T) {
hs := &HTTPServer{
DataSourcesService: &dataSourcesServiceMock{
expectedDatasource: &models.DataSource{},
expectedDatasource: &datasources.DataSource{},
},
}
sc := setupScenarioContext(t, "/api/datasources")
sc.m.Post(sc.url, routing.Wrap(func(c *models.ReqContext) response.Response {
c.Req.Body = mockRequestBody(models.AddDataSourceCommand{
c.Req.Body = mockRequestBody(datasources.AddDataSourceCommand{
Name: name,
Url: url,
Access: "direct",
@ -135,7 +135,7 @@ func TestUpdateDataSource_InvalidURL(t *testing.T) {
sc := setupScenarioContext(t, "/api/datasources/1234")
sc.m.Put(sc.url, routing.Wrap(func(c *models.ReqContext) response.Response {
c.Req.Body = mockRequestBody(models.AddDataSourceCommand{
c.Req.Body = mockRequestBody(datasources.AddDataSourceCommand{
Name: "Test",
Url: "invalid:url",
Access: "direct",
@ -156,14 +156,14 @@ func TestUpdateDataSource_URLWithoutProtocol(t *testing.T) {
hs := &HTTPServer{
DataSourcesService: &dataSourcesServiceMock{
expectedDatasource: &models.DataSource{},
expectedDatasource: &datasources.DataSource{},
},
}
sc := setupScenarioContext(t, "/api/datasources/1234")
sc.m.Put(sc.url, routing.Wrap(func(c *models.ReqContext) response.Response {
c.Req.Body = mockRequestBody(models.AddDataSourceCommand{
c.Req.Body = mockRequestBody(datasources.AddDataSourceCommand{
Name: name,
Url: url,
Access: "direct",
@ -178,7 +178,7 @@ func TestUpdateDataSource_URLWithoutProtocol(t *testing.T) {
}
func TestAPI_Datasources_AccessControl(t *testing.T) {
testDatasource := models.DataSource{
testDatasource := datasources.DataSource{
Id: 3,
Uid: "testUID",
OrgId: testOrgID,
@ -187,7 +187,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
Type: "postgresql",
Access: "Proxy",
}
testDatasourceReadOnly := models.DataSource{
testDatasourceReadOnly := datasources.DataSource{
Id: 4,
Uid: "testUID",
OrgId: testOrgID,
@ -199,7 +199,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
}
addDatasourceBody := func() io.Reader {
s, _ := json.Marshal(models.AddDataSourceCommand{
s, _ := json.Marshal(datasources.AddDataSourceCommand{
Name: "test",
Url: "http://localhost:5432",
Type: "postgresql",
@ -212,12 +212,12 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
expectedDatasource: &testDatasource,
}
dsPermissionService := permissions.NewMockDatasourcePermissionService()
dsPermissionService.DsResult = []*models.DataSource{
dsPermissionService.DsResult = []*datasources.DataSource{
&testDatasource,
}
updateDatasourceBody := func() io.Reader {
s, _ := json.Marshal(models.UpdateDataSourceCommand{
s, _ := json.Marshal(datasources.UpdateDataSourceCommand{
Name: "test",
Url: "http://localhost:5432",
Type: "postgresql",
@ -228,7 +228,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
type acTestCaseWithHandler struct {
body func() io.Reader
accessControlTestCase
expectedDS *models.DataSource
expectedDS *datasources.DataSource
expectedSQLError error
}
tests := []acTestCaseWithHandler{
@ -246,7 +246,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
},
},
},
expectedSQLError: models.ErrDataSourceNotFound,
expectedSQLError: datasources.ErrDataSourceNotFound,
},
{
accessControlTestCase: accessControlTestCase{
@ -507,7 +507,7 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
// mock sqlStore and datasource permission service
dsServiceMock.expectedError = test.expectedSQLError
dsServiceMock.expectedDatasource = test.expectedDS
dsPermissionService.DsResult = []*models.DataSource{test.expectedDS}
dsPermissionService.DsResult = []*datasources.DataSource{test.expectedDS}
if test.expectedDS == nil {
dsPermissionService.DsResult = nil
}
@ -547,44 +547,44 @@ func TestAPI_Datasources_AccessControl(t *testing.T) {
type dataSourcesServiceMock struct {
datasources.DataSourceService
expectedDatasources []*models.DataSource
expectedDatasource *models.DataSource
expectedDatasources []*datasources.DataSource
expectedDatasource *datasources.DataSource
expectedError error
}
func (m *dataSourcesServiceMock) GetDataSource(ctx context.Context, query *models.GetDataSourceQuery) error {
func (m *dataSourcesServiceMock) GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) error {
query.Result = m.expectedDatasource
return m.expectedError
}
func (m *dataSourcesServiceMock) GetDataSources(ctx context.Context, query *models.GetDataSourcesQuery) error {
func (m *dataSourcesServiceMock) GetDataSources(ctx context.Context, query *datasources.GetDataSourcesQuery) error {
query.Result = m.expectedDatasources
return m.expectedError
}
func (m *dataSourcesServiceMock) GetDataSourcesByType(ctx context.Context, query *models.GetDataSourcesByTypeQuery) error {
func (m *dataSourcesServiceMock) GetDataSourcesByType(ctx context.Context, query *datasources.GetDataSourcesByTypeQuery) error {
return m.expectedError
}
func (m *dataSourcesServiceMock) GetDefaultDataSource(ctx context.Context, query *models.GetDefaultDataSourceQuery) error {
func (m *dataSourcesServiceMock) GetDefaultDataSource(ctx context.Context, query *datasources.GetDefaultDataSourceQuery) error {
return m.expectedError
}
func (m *dataSourcesServiceMock) DeleteDataSource(ctx context.Context, cmd *models.DeleteDataSourceCommand) error {
func (m *dataSourcesServiceMock) DeleteDataSource(ctx context.Context, cmd *datasources.DeleteDataSourceCommand) error {
return m.expectedError
}
func (m *dataSourcesServiceMock) AddDataSource(ctx context.Context, cmd *models.AddDataSourceCommand) error {
func (m *dataSourcesServiceMock) AddDataSource(ctx context.Context, cmd *datasources.AddDataSourceCommand) error {
cmd.Result = m.expectedDatasource
return m.expectedError
}
func (m *dataSourcesServiceMock) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSourceCommand) error {
func (m *dataSourcesServiceMock) UpdateDataSource(ctx context.Context, cmd *datasources.UpdateDataSourceCommand) error {
cmd.Result = m.expectedDatasource
return m.expectedError
}
func (m *dataSourcesServiceMock) DecryptedValues(ctx context.Context, ds *models.DataSource) (map[string]string, error) {
func (m *dataSourcesServiceMock) DecryptedValues(ctx context.Context, ds *datasources.DataSource) (map[string]string, error) {
decryptedValues := make(map[string]string)
return decryptedValues, m.expectedError
}

View File

@ -2,7 +2,7 @@ package definitions
import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
)
// swagger:route GET /datasources datasources getDatasources
@ -457,14 +457,14 @@ type DatasourceProxyPOSTByUIDcallsParams struct {
type AddDatasourceParams struct {
// in:body
// required:true
Body models.AddDataSourceCommand
Body datasources.AddDataSourceCommand
}
// swagger:parameters updateDatasourceByID
type UpdateDatasourceParams struct {
// in:body
// required:true
Body models.UpdateDataSourceCommand
Body datasources.UpdateDataSourceCommand
// in:path
// required:true
DatasourceID string `json:"id"`
@ -474,7 +474,7 @@ type UpdateDatasourceParams struct {
type UpdateDatasourceByUIDParams struct {
// in:body
// required:true
Body models.UpdateDataSourceCommand
Body datasources.UpdateDataSourceCommand
// in:path
// required:true
DatasourceUID string `json:"uid"`

View File

@ -4,8 +4,8 @@ import (
"strings"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
)
type DataSource struct {
@ -15,7 +15,7 @@ type DataSource struct {
Name string `json:"name"`
Type string `json:"type"`
TypeLogoUrl string `json:"typeLogoUrl"`
Access models.DsAccess `json:"access"`
Access datasources.DsAccess `json:"access"`
Url string `json:"url"`
User string `json:"user"`
Database string `json:"database"`
@ -31,21 +31,21 @@ type DataSource struct {
}
type DataSourceListItemDTO struct {
Id int64 `json:"id"`
UID string `json:"uid"`
OrgId int64 `json:"orgId"`
Name string `json:"name"`
Type string `json:"type"`
TypeName string `json:"typeName"`
TypeLogoUrl string `json:"typeLogoUrl"`
Access models.DsAccess `json:"access"`
Url string `json:"url"`
User string `json:"user"`
Database string `json:"database"`
BasicAuth bool `json:"basicAuth"`
IsDefault bool `json:"isDefault"`
JsonData *simplejson.Json `json:"jsonData,omitempty"`
ReadOnly bool `json:"readOnly"`
Id int64 `json:"id"`
UID string `json:"uid"`
OrgId int64 `json:"orgId"`
Name string `json:"name"`
Type string `json:"type"`
TypeName string `json:"typeName"`
TypeLogoUrl string `json:"typeLogoUrl"`
Access datasources.DsAccess `json:"access"`
Url string `json:"url"`
User string `json:"user"`
Database string `json:"database"`
BasicAuth bool `json:"basicAuth"`
IsDefault bool `json:"isDefault"`
JsonData *simplejson.Json `json:"jsonData,omitempty"`
ReadOnly bool `json:"readOnly"`
}
type DataSourceList []DataSourceListItemDTO

View File

@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/licensing"
"github.com/grafana/grafana/pkg/services/pluginsettings"
"github.com/grafana/grafana/pkg/setting"
@ -191,10 +192,10 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i
}
func (hs *HTTPServer) getFSDataSources(c *models.ReqContext, enabledPlugins EnabledPlugins) (map[string]plugins.DataSourceDTO, error) {
orgDataSources := make([]*models.DataSource, 0)
orgDataSources := make([]*datasources.DataSource, 0)
if c.OrgId != 0 {
query := models.GetDataSourcesQuery{OrgId: c.OrgId, DataSourceLimit: hs.Cfg.DataSourceLimit}
query := datasources.GetDataSourcesQuery{OrgId: c.OrgId, DataSourceLimit: hs.Cfg.DataSourceLimit}
err := hs.SQLStore.GetDataSources(c.Req.Context(), &query)
if err != nil {
@ -214,7 +215,7 @@ func (hs *HTTPServer) getFSDataSources(c *models.ReqContext, enabledPlugins Enab
for _, ds := range orgDataSources {
url := ds.Url
if ds.Access == models.DS_ACCESS_PROXY {
if ds.Access == datasources.DS_ACCESS_PROXY {
url = "/api/datasources/proxy/" + strconv.FormatInt(ds.Id, 10)
}
@ -248,7 +249,7 @@ func (hs *HTTPServer) getFSDataSources(c *models.ReqContext, enabledPlugins Enab
dsDTO.JSONData = ds.JsonData.MustMap()
}
if ds.Access == models.DS_ACCESS_DIRECT {
if ds.Access == datasources.DS_ACCESS_DIRECT {
if ds.BasicAuth {
password, err := hs.DataSourcesService.DecryptedBasicAuthPassword(c.Req.Context(), ds)
if err != nil {
@ -264,7 +265,7 @@ func (hs *HTTPServer) getFSDataSources(c *models.ReqContext, enabledPlugins Enab
dsDTO.WithCredentials = ds.WithCredentials
}
if ds.Type == models.DS_INFLUXDB_08 {
if ds.Type == datasources.DS_INFLUXDB_08 {
password, err := hs.DataSourcesService.DecryptedPassword(c.Req.Context(), ds)
if err != nil {
return nil, err
@ -275,7 +276,7 @@ func (hs *HTTPServer) getFSDataSources(c *models.ReqContext, enabledPlugins Enab
dsDTO.URL = url + "/db/" + ds.Database
}
if ds.Type == models.DS_INFLUXDB {
if ds.Type == datasources.DS_INFLUXDB {
password, err := hs.DataSourcesService.DecryptedPassword(c.Req.Context(), ds)
if err != nil {
return nil, err
@ -287,11 +288,11 @@ func (hs *HTTPServer) getFSDataSources(c *models.ReqContext, enabledPlugins Enab
}
}
if (ds.Type == models.DS_INFLUXDB) || (ds.Type == models.DS_ES) {
if (ds.Type == datasources.DS_INFLUXDB) || (ds.Type == datasources.DS_ES) {
dsDTO.Database = ds.Database
}
if ds.Type == models.DS_PROMETHEUS {
if ds.Type == datasources.DS_PROMETHEUS {
// add unproxied server URL for link to Prometheus web UI
ds.JsonData.Set("directUrl", ds.Url)
}

View File

@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/query"
"github.com/grafana/grafana/pkg/util"
@ -17,10 +18,10 @@ import (
)
func (hs *HTTPServer) handleQueryMetricsError(err error) *response.NormalResponse {
if errors.Is(err, models.ErrDataSourceAccessDenied) {
if errors.Is(err, datasources.ErrDataSourceAccessDenied) {
return response.Error(http.StatusForbidden, "Access denied to data source", err)
}
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
return response.Error(http.StatusNotFound, "Data source not found", err)
}
var badQuery *query.ErrBadQuery

View File

@ -8,9 +8,11 @@ import (
"testing"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/web/webtest"
"github.com/stretchr/testify/require"
"golang.org/x/oauth2"
@ -51,7 +53,7 @@ func (ts *fakeOAuthTokenService) GetCurrentOAuthToken(context.Context, *models.S
return ts.token
}
func (ts *fakeOAuthTokenService) IsOAuthPassThruEnabled(*models.DataSource) bool {
func (ts *fakeOAuthTokenService) IsOAuthPassThruEnabled(*datasources.DataSource) bool {
return ts.passThruEnabled
}

View File

@ -12,8 +12,10 @@ import (
"sync"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/util/proxyutil"
"github.com/grafana/grafana/pkg/web"
)
@ -47,7 +49,7 @@ func (hs *HTTPServer) callPluginResource(c *models.ReqContext, pluginID string)
}
}
func (hs *HTTPServer) callPluginResourceWithDataSource(c *models.ReqContext, pluginID string, ds *models.DataSource) {
func (hs *HTTPServer) callPluginResourceWithDataSource(c *models.ReqContext, pluginID string, ds *datasources.DataSource) {
pCtx, found, err := hs.PluginContextProvider.GetWithDataSource(c.Req.Context(), pluginID, c.SignedInUser, ds)
if err != nil {
c.JsonApiErr(500, "Failed to get plugin settings", err)

View File

@ -11,6 +11,8 @@ import (
"strings"
"time"
"go.opentelemetry.io/otel/attribute"
"github.com/grafana/grafana/pkg/api/datasource"
"github.com/grafana/grafana/pkg/infra/httpclient"
glog "github.com/grafana/grafana/pkg/infra/log"
@ -22,7 +24,6 @@ import (
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/util/proxyutil"
"go.opentelemetry.io/otel/attribute"
)
var (
@ -31,7 +32,7 @@ var (
)
type DataSourceProxy struct {
ds *models.DataSource
ds *datasources.DataSource
ctx *models.ReqContext
targetUrl *url.URL
proxyPath string
@ -49,7 +50,7 @@ type httpClient interface {
}
// NewDataSourceProxy creates a new Datasource proxy
func NewDataSourceProxy(ds *models.DataSource, pluginRoutes []*plugins.Route, ctx *models.ReqContext,
func NewDataSourceProxy(ds *datasources.DataSource, pluginRoutes []*plugins.Route, ctx *models.ReqContext,
proxyPath string, cfg *setting.Cfg, clientProvider httpclient.Provider,
oAuthTokenService oauthtoken.OAuthTokenService, dsService datasources.DataSourceService,
tracer tracing.Tracer) (*DataSourceProxy, error) {
@ -167,7 +168,7 @@ func (proxy *DataSourceProxy) director(req *http.Request) {
reqQueryVals := req.URL.Query()
switch proxy.ds.Type {
case models.DS_INFLUXDB_08:
case datasources.DS_INFLUXDB_08:
password, err := proxy.dataSourcesService.DecryptedPassword(req.Context(), proxy.ds)
if err != nil {
logger.Error("Error interpolating proxy url", "error", err)
@ -178,7 +179,7 @@ func (proxy *DataSourceProxy) director(req *http.Request) {
reqQueryVals.Add("u", proxy.ds.User)
reqQueryVals.Add("p", password)
req.URL.RawQuery = reqQueryVals.Encode()
case models.DS_INFLUXDB:
case datasources.DS_INFLUXDB:
password, err := proxy.dataSourcesService.DecryptedPassword(req.Context(), proxy.ds)
if err != nil {
logger.Error("Error interpolating proxy url", "error", err)
@ -266,7 +267,7 @@ func (proxy *DataSourceProxy) validateRequest() error {
return errors.New("target URL is not a valid target")
}
if proxy.ds.Type == models.DS_ES {
if proxy.ds.Type == datasources.DS_ES {
if proxy.ctx.Req.Method == "DELETE" {
return errors.New("deletes not allowed on proxied Elasticsearch datasource")
}
@ -301,7 +302,7 @@ func (proxy *DataSourceProxy) validateRequest() error {
}
// Trailing validation below this point for routes that were not matched
if proxy.ds.Type == models.DS_PROMETHEUS {
if proxy.ds.Type == datasources.DS_PROMETHEUS {
if proxy.ctx.Req.Method == "DELETE" {
return errors.New("non allow-listed DELETEs not allowed on proxied Prometheus datasource")
}

View File

@ -13,6 +13,10 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/oauth2"
"github.com/grafana/grafana/pkg/api/datasource"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/httpclient"
@ -20,6 +24,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
"github.com/grafana/grafana/pkg/services/datasources"
datasourceservice "github.com/grafana/grafana/pkg/services/datasources/service"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/oauthtoken"
@ -29,9 +34,6 @@ import (
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/oauth2"
)
func TestDataSourceProxy_routeRule(t *testing.T) {
@ -96,7 +98,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
key, err := secretsService.Encrypt(context.Background(), []byte("123"), secrets.WithoutScope())
require.NoError(t, err)
ds := &models.DataSource{
ds := &datasources.DataSource{
JsonData: simplejson.NewFromAny(map[string]interface{}{
"clientId": "asd",
"dynamicUrl": "https://dynamic.grafana.com",
@ -249,7 +251,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
key, err := secretsService.Encrypt(context.Background(), []byte("123"), secrets.WithoutScope())
require.NoError(t, err)
ds := &models.DataSource{
ds := &datasources.DataSource{
JsonData: simplejson.NewFromAny(map[string]interface{}{
"clientId": "asd",
"tenantId": "mytenantId",
@ -340,7 +342,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("When proxying graphite", func(t *testing.T) {
var routes []*plugins.Route
ds := &models.DataSource{Url: "htttp://graphite:8080", Type: models.DS_GRAPHITE}
ds := &datasources.DataSource{Url: "htttp://graphite:8080", Type: datasources.DS_GRAPHITE}
ctx := &models.ReqContext{}
secretsStore := kvstore.SetupTestService(t)
@ -360,8 +362,8 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
})
t.Run("When proxying InfluxDB", func(t *testing.T) {
ds := &models.DataSource{
Type: models.DS_INFLUXDB_08,
ds := &datasources.DataSource{
Type: datasources.DS_INFLUXDB_08,
Url: "http://influxdb:8083",
Database: "site",
User: "user",
@ -386,8 +388,8 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
json, err := simplejson.NewJson([]byte(`{"keepCookies": []}`))
require.NoError(t, err)
ds := &models.DataSource{
Type: models.DS_GRAPHITE,
ds := &datasources.DataSource{
Type: datasources.DS_GRAPHITE,
Url: "http://graphite:8086",
JsonData: json,
}
@ -415,8 +417,8 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
json, err := simplejson.NewJson([]byte(`{"keepCookies": ["JSESSION_ID"]}`))
require.NoError(t, err)
ds := &models.DataSource{
Type: models.DS_GRAPHITE,
ds := &datasources.DataSource{
Type: datasources.DS_GRAPHITE,
Url: "http://graphite:8086",
JsonData: json,
}
@ -441,7 +443,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
})
t.Run("When proxying a custom datasource", func(t *testing.T) {
ds := &models.DataSource{
ds := &datasources.DataSource{
Type: "custom-datasource",
Url: "http://host/root/",
}
@ -466,7 +468,7 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
})
t.Run("When proxying a datasource that has OAuth token pass-through enabled", func(t *testing.T) {
ds := &models.DataSource{
ds := &datasources.DataSource{
Type: "custom-datasource",
Url: "http://host/root/",
JsonData: simplejson.NewFromAny(map[string]interface{}{
@ -555,18 +557,18 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
tests := []*testCase{
createAuthTest(t, secretsStore, models.DS_INFLUXDB_08, "http://localhost:9090", authTypePassword, authCheckQuery),
createAuthTest(t, secretsStore, models.DS_INFLUXDB_08, "http://localhost:9090", authTypePassword, authCheckQuery),
createAuthTest(t, secretsStore, models.DS_INFLUXDB, "http://localhost:9090", authTypePassword, authCheckHeader),
createAuthTest(t, secretsStore, models.DS_INFLUXDB, "http://localhost:9090", authTypePassword, authCheckHeader),
createAuthTest(t, secretsStore, models.DS_INFLUXDB, "http://localhost:9090", authTypeBasic, authCheckHeader),
createAuthTest(t, secretsStore, models.DS_INFLUXDB, "http://localhost:9090", authTypeBasic, authCheckHeader),
createAuthTest(t, secretsStore, datasources.DS_INFLUXDB_08, "http://localhost:9090", authTypePassword, authCheckQuery),
createAuthTest(t, secretsStore, datasources.DS_INFLUXDB_08, "http://localhost:9090", authTypePassword, authCheckQuery),
createAuthTest(t, secretsStore, datasources.DS_INFLUXDB, "http://localhost:9090", authTypePassword, authCheckHeader),
createAuthTest(t, secretsStore, datasources.DS_INFLUXDB, "http://localhost:9090", authTypePassword, authCheckHeader),
createAuthTest(t, secretsStore, datasources.DS_INFLUXDB, "http://localhost:9090", authTypeBasic, authCheckHeader),
createAuthTest(t, secretsStore, datasources.DS_INFLUXDB, "http://localhost:9090", authTypeBasic, authCheckHeader),
// These two should be enough for any other datasource at the moment. Proxy has special handling
// only for Influx, others have the same path and only BasicAuth. Non BasicAuth datasources
// do not go through proxy but through TSDB API which is not tested here.
createAuthTest(t, secretsStore, models.DS_ES, "http://localhost:9200", authTypeBasic, authCheckHeader),
createAuthTest(t, secretsStore, models.DS_ES, "http://localhost:9200", authTypeBasic, authCheckHeader),
createAuthTest(t, secretsStore, datasources.DS_ES, "http://localhost:9200", authTypeBasic, authCheckHeader),
createAuthTest(t, secretsStore, datasources.DS_ES, "http://localhost:9200", authTypeBasic, authCheckHeader),
}
for _, test := range tests {
runDatasourceAuthTest(t, secretsService, secretsStore, cfg, test)
@ -585,7 +587,7 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
writeCb func(w http.ResponseWriter, r *http.Request)
}
setUp := func(t *testing.T, cfgs ...setUpCfg) (*models.ReqContext, *models.DataSource) {
setUp := func(t *testing.T, cfgs ...setUpCfg) (*models.ReqContext, *datasources.DataSource) {
writeErr = nil
backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@ -606,7 +608,7 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
}))
t.Cleanup(backend.Close)
ds := &models.DataSource{Url: backend.URL, Type: models.DS_GRAPHITE}
ds := &datasources.DataSource{Url: backend.URL, Type: datasources.DS_GRAPHITE}
responseWriter := web.NewResponseWriter("GET", httptest.NewRecorder())
@ -758,7 +760,7 @@ func TestNewDataSourceProxy_InvalidURL(t *testing.T) {
Context: &web.Context{},
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_EDITOR},
}
ds := models.DataSource{
ds := datasources.DataSource{
Type: "test",
Url: "://host/root",
}
@ -778,7 +780,7 @@ func TestNewDataSourceProxy_ProtocolLessURL(t *testing.T) {
Context: &web.Context{},
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_EDITOR},
}
ds := models.DataSource{
ds := datasources.DataSource{
Type: "test",
Url: "127.0.01:5432",
}
@ -823,7 +825,7 @@ func TestNewDataSourceProxy_MSSQL(t *testing.T) {
for _, tc := range tcs {
t.Run(tc.description, func(t *testing.T) {
cfg := &setting.Cfg{}
ds := models.DataSource{
ds := datasources.DataSource{
Type: "mssql",
Url: tc.url,
}
@ -849,7 +851,7 @@ func TestNewDataSourceProxy_MSSQL(t *testing.T) {
// getDatasourceProxiedRequest is a helper for easier setup of tests based on global config and ReqContext.
func getDatasourceProxiedRequest(t *testing.T, ctx *models.ReqContext, cfg *setting.Cfg) *http.Request {
ds := &models.DataSource{
ds := &datasources.DataSource{
Type: "custom",
Url: "http://host/root/",
}
@ -897,7 +899,7 @@ func newFakeHTTPClient(t *testing.T, fakeBody []byte) httpClient {
}
type testCase struct {
datasource *models.DataSource
datasource *datasources.DataSource
checkReq func(req *http.Request)
}
@ -916,7 +918,7 @@ func createAuthTest(t *testing.T, secretsStore kvstore.SecretsKVStore, dsType st
base64AuthHeader := "Basic dXNlcjpwYXNzd29yZA=="
test := &testCase{
datasource: &models.DataSource{
datasource: &datasources.DataSource{
Id: 1,
OrgId: 1,
Name: fmt.Sprintf("%s,%s,%s,%s", dsType, url, authType, authCheck),
@ -1019,7 +1021,7 @@ func Test_PathCheck(t *testing.T) {
secretsStore := kvstore.SetupTestService(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
proxy, err := NewDataSourceProxy(&models.DataSource{}, routes, ctx, "b", &setting.Cfg{}, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer)
proxy, err := NewDataSourceProxy(&datasources.DataSource{}, routes, ctx, "b", &setting.Cfg{}, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
require.Nil(t, proxy.validateRequest())
@ -1035,6 +1037,6 @@ func (m *mockOAuthTokenService) GetCurrentOAuthToken(ctx context.Context, user *
return m.token
}
func (m *mockOAuthTokenService) IsOAuthPassThruEnabled(ds *models.DataSource) bool {
func (m *mockOAuthTokenService) IsOAuthPassThruEnabled(ds *datasources.DataSource) bool {
return m.oAuthEnabled
}

View File

@ -5,13 +5,14 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/commands/commandstest"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPasswordMigrationCommand(t *testing.T) {
@ -20,7 +21,7 @@ func TestPasswordMigrationCommand(t *testing.T) {
session := sqlstore.NewSession(context.Background())
defer session.Close()
datasources := []*models.DataSource{
ds := []*datasources.DataSource{
{Type: "influxdb", Name: "influxdb", Password: "foobar", Uid: "influx"},
{Type: "graphite", Name: "graphite", BasicAuthPassword: "foobar", Uid: "graphite"},
{Type: "prometheus", Name: "prometheus", Uid: "prom"},
@ -28,7 +29,7 @@ func TestPasswordMigrationCommand(t *testing.T) {
}
// set required default values
for _, ds := range datasources {
for _, ds := range ds {
ds.Created = time.Now()
ds.Updated = time.Now()
@ -42,7 +43,7 @@ func TestPasswordMigrationCommand(t *testing.T) {
}
}
_, err := session.Insert(&datasources)
_, err := session.Insert(&ds)
require.NoError(t, err)
// force secure_json_data to be null to verify that migration can handle that
@ -56,7 +57,7 @@ func TestPasswordMigrationCommand(t *testing.T) {
require.NoError(t, err)
// verify that no datasources still have password or basic_auth
var dss []*models.DataSource
var dss []*datasources.DataSource
err = session.SQL("select * from data_source").Find(&dss)
require.NoError(t, err)
assert.Equal(t, len(dss), 4)
@ -95,7 +96,7 @@ func TestPasswordMigrationCommand(t *testing.T) {
}
}
func DecryptSecureJsonData(ds *models.DataSource) (map[string]string, error) {
func DecryptSecureJsonData(ds *datasources.DataSource) (map[string]string, error) {
decrypted := make(map[string]string)
for key, data := range ds.SecureJsonData {
decryptedData, err := util.Decrypt(data, setting.SecretKey)

View File

@ -4,8 +4,9 @@ import (
"encoding/json"
"testing"
"github.com/grafana/grafana/pkg/models"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/services/datasources"
)
func TestServicebuildPipeLine(t *testing.T) {
@ -30,7 +31,7 @@ func TestServicebuildPipeLine(t *testing.T) {
},
{
RefID: "B",
DataSource: &models.DataSource{
DataSource: &datasources.DataSource{
Uid: "Fake",
},
},
@ -140,7 +141,7 @@ func TestServicebuildPipeLine(t *testing.T) {
},
{
RefID: "C",
DataSource: &models.DataSource{
DataSource: &datasources.DataSource{
Uid: "Fake",
},
},
@ -194,7 +195,7 @@ func TestServicebuildPipeLine(t *testing.T) {
},
{
RefID: "C",
DataSource: &models.DataSource{
DataSource: &datasources.DataSource{
Uid: "Fake",
},
},
@ -217,7 +218,7 @@ func TestServicebuildPipeLine(t *testing.T) {
},
{
RefID: "B",
DataSource: &models.DataSource{
DataSource: &datasources.DataSource{
Uid: "Fake",
},
},

View File

@ -12,8 +12,8 @@ import (
"github.com/grafana/grafana/pkg/expr/classic"
"github.com/grafana/grafana/pkg/expr/mathexp"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins/adapters"
"github.com/grafana/grafana/pkg/services/datasources"
"gonum.org/v1/gonum/graph/simple"
)
@ -46,7 +46,7 @@ type rawNode struct {
Query map[string]interface{}
QueryType string
TimeRange TimeRange
DataSource *models.DataSource
DataSource *datasources.DataSource
}
func (rn *rawNode) GetCommandType() (c CommandType, err error) {
@ -138,7 +138,7 @@ const (
type DSNode struct {
baseNode
query json.RawMessage
datasource *models.DataSource
datasource *datasources.DataSource
orgID int64
queryType string
@ -268,7 +268,7 @@ func (dn *DSNode) Execute(ctx context.Context, vars mathexp.Vars, s *Service) (m
// Check for TimeSeriesTypeNot in InfluxDB queries. A data frame of this type will cause
// the WideToMany() function to error out, which results in unhealthy alerts.
// This check should be removed once inconsistencies in data source responses are solved.
if frame.TimeSeriesSchema().Type == data.TimeSeriesTypeNot && dataSource == models.DS_INFLUXDB {
if frame.TimeSeriesSchema().Type == data.TimeSeriesTypeNot && dataSource == datasources.DS_INFLUXDB {
logger.Warn("ignoring InfluxDB data frame due to missing numeric fields", "frame", frame)
continue
}

View File

@ -4,8 +4,8 @@ import (
"context"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/setting"
@ -76,8 +76,8 @@ func (s *Service) ExecutePipeline(ctx context.Context, pipeline DataPipeline) (*
return res, nil
}
func DataSourceModel() *models.DataSource {
return &models.DataSource{
func DataSourceModel() *datasources.DataSource {
return &datasources.DataSource{
Id: DatasourceID,
Uid: DatasourceUID,
Name: DatasourceUID,

View File

@ -10,10 +10,11 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/models"
datasources "github.com/grafana/grafana/pkg/services/datasources/fakes"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/services/datasources"
datafakes "github.com/grafana/grafana/pkg/services/datasources/fakes"
"github.com/grafana/grafana/pkg/setting"
)
func TestService(t *testing.T) {
@ -30,13 +31,13 @@ func TestService(t *testing.T) {
s := Service{
cfg: cfg,
dataService: me,
dataSourceService: &datasources.FakeDataSourceService{},
dataSourceService: &datafakes.FakeDataSourceService{},
}
queries := []Query{
{
RefID: "A",
DataSource: &models.DataSource{
DataSource: &datasources.DataSource{
OrgId: 1,
Uid: "test",
Type: "test",

View File

@ -7,8 +7,9 @@ import (
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/models"
"github.com/prometheus/client_golang/prometheus"
"github.com/grafana/grafana/pkg/services/datasources"
)
var (
@ -41,7 +42,7 @@ type Request struct {
type Query struct {
RefID string
TimeRange TimeRange
DataSource *models.DataSource `json:"datasource"`
DataSource *datasources.DataSource `json:"datasource"`
JSON json.RawMessage
Interval time.Duration
QueryType string
@ -126,8 +127,8 @@ func hiddenRefIDs(queries []Query) (map[string]struct{}, error) {
return hidden, nil
}
func (s *Service) decryptSecureJsonDataFn(ctx context.Context) func(ds *models.DataSource) map[string]string {
return func(ds *models.DataSource) map[string]string {
func (s *Service) decryptSecureJsonDataFn(ctx context.Context) func(ds *datasources.DataSource) map[string]string {
return func(ds *datasources.DataSource) map[string]string {
decryptedJsonData, err := s.dataSourceService.DecryptedValues(ctx, ds)
if err != nil {
logger.Error("Failed to decrypt secure json data", "error", err)

View File

@ -7,13 +7,15 @@ import (
"path"
"testing"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/require"
)
func TestApi_getUsageStats(t *testing.T) {
@ -49,7 +51,7 @@ func TestApi_getUsageStats(t *testing.T) {
sqlStore.ExpectedSystemStats = &models.SystemStats{}
sqlStore.ExpectedDataSourceStats = []*models.DataSourceStats{}
sqlStore.ExpectedDataSources = []*models.DataSource{}
sqlStore.ExpectedDataSources = []*datasources.DataSource{}
sqlStore.ExpectedDataSourcesAccessStats = []*models.DataSourceAccessStats{}
sqlStore.ExpectedNotifierUsageStats = []*models.NotifierUsageStats{}

View File

@ -7,7 +7,7 @@ import (
"net/http"
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
)
const promFlavorCacheLifetime = time.Hour
@ -37,7 +37,7 @@ func (s *Service) detectPrometheusVariants(ctx context.Context) (map[string]int6
return s.promFlavorCache.variants, nil
}
dsProm := &models.GetDataSourcesByTypeQuery{Type: "prometheus"}
dsProm := &datasources.GetDataSourcesByTypeQuery{Type: "prometheus"}
err := s.datasources.GetDataSourcesByType(ctx, dsProm)
if err != nil {
s.log.Error("Failed to read all Prometheus data sources", "error", err)
@ -65,7 +65,7 @@ func (s *Service) detectPrometheusVariants(ctx context.Context) (map[string]int6
return variants, nil
}
func (s *Service) detectPrometheusVariant(ctx context.Context, ds *models.DataSource) (string, error) {
func (s *Service) detectPrometheusVariant(ctx context.Context, ds *datasources.DataSource) (string, error) {
type buildInfo struct {
Data struct {
Application *string `json:"application"`

View File

@ -11,7 +11,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/setting"
)
@ -37,7 +37,7 @@ func TestDetectPrometheusVariant(t *testing.T) {
t,
setting.NewCfg(),
sqlStore,
withDatasources(mockDatasourceService{datasources: []*models.DataSource{
withDatasources(mockDatasourceService{datasources: []*datasources.DataSource{
{
Id: 1,
OrgId: 1,

View File

@ -256,7 +256,7 @@ func (s *Service) collectDatasourceStats(ctx context.Context) (map[string]interf
func (s *Service) collectElasticStats(ctx context.Context) (map[string]interface{}, error) {
m := map[string]interface{}{}
esDataSourcesQuery := models.GetDataSourcesByTypeQuery{Type: models.DS_ES}
esDataSourcesQuery := datasources.GetDataSourcesByTypeQuery{Type: datasources.DS_ES}
if err := s.sqlstore.GetDataSourcesByType(ctx, &esDataSourcesQuery); err != nil {
s.log.Error("Failed to get elasticsearch json data", "error", err)
return nil, err

View File

@ -190,11 +190,11 @@ func TestDatasourceStats(t *testing.T) {
sqlStore.ExpectedDataSourceStats = []*models.DataSourceStats{
{
Type: models.DS_ES,
Type: datasources.DS_ES,
Count: 9,
},
{
Type: models.DS_PROMETHEUS,
Type: datasources.DS_PROMETHEUS,
Count: 10,
},
{
@ -207,7 +207,7 @@ func TestDatasourceStats(t *testing.T) {
},
}
sqlStore.ExpectedDataSources = []*models.DataSource{
sqlStore.ExpectedDataSources = []*datasources.DataSource{
{
JsonData: simplejson.NewFromAny(map[string]interface{}{
"esVersion": 2,
@ -227,17 +227,17 @@ func TestDatasourceStats(t *testing.T) {
sqlStore.ExpectedDataSourcesAccessStats = []*models.DataSourceAccessStats{
{
Type: models.DS_ES,
Type: datasources.DS_ES,
Access: "direct",
Count: 1,
},
{
Type: models.DS_ES,
Type: datasources.DS_ES,
Access: "proxy",
Count: 2,
},
{
Type: models.DS_PROMETHEUS,
Type: datasources.DS_PROMETHEUS,
Access: "proxy",
Count: 3,
},
@ -272,8 +272,8 @@ func TestDatasourceStats(t *testing.T) {
db, err := s.collectDatasourceStats(context.Background())
require.NoError(t, err)
assert.EqualValues(t, 9, db["stats.ds."+models.DS_ES+".count"])
assert.EqualValues(t, 10, db["stats.ds."+models.DS_PROMETHEUS+".count"])
assert.EqualValues(t, 9, db["stats.ds."+datasources.DS_ES+".count"])
assert.EqualValues(t, 10, db["stats.ds."+datasources.DS_PROMETHEUS+".count"])
assert.EqualValues(t, 11+12, db["stats.ds.other.count"])
}
@ -281,9 +281,9 @@ func TestDatasourceStats(t *testing.T) {
dba, err := s.collectDatasourceAccess(context.Background())
require.NoError(t, err)
assert.EqualValues(t, 1, dba["stats.ds_access."+models.DS_ES+".direct.count"])
assert.EqualValues(t, 2, dba["stats.ds_access."+models.DS_ES+".proxy.count"])
assert.EqualValues(t, 3, dba["stats.ds_access."+models.DS_PROMETHEUS+".proxy.count"])
assert.EqualValues(t, 1, dba["stats.ds_access."+datasources.DS_ES+".direct.count"])
assert.EqualValues(t, 2, dba["stats.ds_access."+datasources.DS_ES+".proxy.count"])
assert.EqualValues(t, 3, dba["stats.ds_access."+datasources.DS_PROMETHEUS+".proxy.count"])
assert.EqualValues(t, 6+7, dba["stats.ds_access.other.direct.count"])
assert.EqualValues(t, 4+8, dba["stats.ds_access.other.proxy.count"])
}
@ -383,16 +383,16 @@ func setupSomeDataSourcePlugins(t *testing.T, s *Service) {
s.plugins = &fakePluginStore{
plugins: map[string]plugins.PluginDTO{
models.DS_ES: {
datasources.DS_ES: {
Signature: "internal",
},
models.DS_PROMETHEUS: {
datasources.DS_PROMETHEUS: {
Signature: "internal",
},
models.DS_GRAPHITE: {
datasources.DS_GRAPHITE: {
Signature: "internal",
},
models.DS_MYSQL: {
datasources.DS_MYSQL: {
Signature: "internal",
},
},
@ -446,14 +446,14 @@ func withDatasources(ds datasources.DataSourceService) func(*serviceOptions) {
type mockDatasourceService struct {
datasources.DataSourceService
datasources []*models.DataSource
datasources []*datasources.DataSource
}
func (s mockDatasourceService) GetDataSourcesByType(ctx context.Context, query *models.GetDataSourcesByTypeQuery) error {
func (s mockDatasourceService) GetDataSourcesByType(ctx context.Context, query *datasources.GetDataSourcesByTypeQuery) error {
query.Result = s.datasources
return nil
}
func (s mockDatasourceService) GetHTTPTransport(ctx context.Context, ds *models.DataSource, provider httpclient.Provider, customMiddlewares ...sdkhttpclient.Middleware) (http.RoundTripper, error) {
func (s mockDatasourceService) GetHTTPTransport(ctx context.Context, ds *datasources.DataSource, provider httpclient.Provider, customMiddlewares ...sdkhttpclient.Middleware) (http.RoundTripper, error) {
return provider.GetTransport()
}

View File

@ -5,11 +5,13 @@ import (
"encoding/json"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
)
// ModelToInstanceSettings converts a models.DataSource to a backend.DataSourceInstanceSettings.
func ModelToInstanceSettings(ds *models.DataSource, decryptFn func(ds *models.DataSource) map[string]string,
// ModelToInstanceSettings converts a datasources.DataSource to a backend.DataSourceInstanceSettings.
func ModelToInstanceSettings(ds *datasources.DataSource, decryptFn func(ds *datasources.DataSource) map[string]string,
) (*backend.DataSourceInstanceSettings, error) {
var jsonDataBytes json.RawMessage
if ds.JsonData != nil {

View File

@ -49,7 +49,7 @@ func (p *Provider) Get(ctx context.Context, pluginID string, user *models.Signed
// GetWithDataSource allows getting plugin context by its ID and PluginContext.DataSourceInstanceSettings will be
// resolved and appended to the returned context.
func (p *Provider) GetWithDataSource(ctx context.Context, pluginID string, user *models.SignedInUser, ds *models.DataSource) (backend.PluginContext, bool, error) {
func (p *Provider) GetWithDataSource(ctx context.Context, pluginID string, user *models.SignedInUser, ds *datasources.DataSource) (backend.PluginContext, bool, error) {
pCtx, exists, err := p.pluginContext(ctx, pluginID, user)
if err != nil {
return pCtx, exists, err
@ -127,8 +127,8 @@ func (p *Provider) getCachedPluginSettings(ctx context.Context, pluginID string,
return ps, nil
}
func (p *Provider) decryptSecureJsonDataFn(ctx context.Context) func(ds *models.DataSource) map[string]string {
return func(ds *models.DataSource) map[string]string {
func (p *Provider) decryptSecureJsonDataFn(ctx context.Context) func(ds *datasources.DataSource) map[string]string {
return func(ds *datasources.DataSource) map[string]string {
decryptedJsonData, err := p.dataSourceService.DecryptedValues(ctx, ds)
if err != nil {
p.logger.Error("Failed to decrypt secure json data", "error", err)

View File

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
@ -75,11 +76,11 @@ func setupResourceBenchmark(b *testing.B, dsNum, usersNum int) (*AccessControlSt
func GenerateDatasourcePermissions(b *testing.B, db *sqlstore.SQLStore, ac *AccessControlStore, dsNum, usersNum, permissionsPerDs int) []int64 {
dataSources := make([]int64, 0)
for i := 0; i < dsNum; i++ {
addDSCommand := &models.AddDataSourceCommand{
addDSCommand := &datasources.AddDataSourceCommand{
OrgId: 0,
Name: fmt.Sprintf("ds_%d", i),
Type: models.DS_GRAPHITE,
Access: models.DS_ACCESS_DIRECT,
Type: datasources.DS_GRAPHITE,
Access: datasources.DS_ACCESS_DIRECT,
Url: "http://test",
}

View File

@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
@ -39,7 +40,7 @@ func benchmarkFilter(b *testing.B, numDs, numPermissions int) {
)
require.NoError(b, err)
var datasources []models.DataSource
var datasources []datasources.DataSource
sess := store.NewSession(context.Background())
err = sess.SQL(baseSql+acFilter.Where, acFilter.Args...).Find(&datasources)
require.NoError(b, err)
@ -53,7 +54,7 @@ func setupFilterBenchmark(b *testing.B, numDs, numPermissions int) (*sqlstore.SQ
store := sqlstore.InitTestDB(b)
for i := 1; i <= numDs; i++ {
err := store.AddDataSource(context.Background(), &models.AddDataSourceCommand{
err := store.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
Name: fmt.Sprintf("ds:%d", i),
OrgId: 1,
})

View File

@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
@ -170,7 +171,7 @@ func TestFilter_Datasources(t *testing.T) {
// seed 10 data sources
for i := 1; i <= 10; i++ {
err := store.AddDataSource(context.Background(), &models.AddDataSourceCommand{Name: fmt.Sprintf("ds:%d", i), Uid: fmt.Sprintf("uid%d", i)})
err := store.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{Name: fmt.Sprintf("ds:%d", i), Uid: fmt.Sprintf("uid%d", i)})
require.NoError(t, err)
}
@ -187,7 +188,7 @@ func TestFilter_Datasources(t *testing.T) {
if !tt.expectErr {
require.NoError(t, err)
var datasources []models.DataSource
var datasources []datasources.DataSource
err = sess.SQL(baseSql+acFilter.Where, acFilter.Args...).Find(&datasources)
require.NoError(t, err)

View File

@ -1,40 +1,43 @@
package accesscontrol
package accesscontrol_test
import (
"context"
"testing"
"github.com/grafana/grafana/pkg/models"
"github.com/stretchr/testify/assert"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
)
func TestResolveKeywordScope(t *testing.T) {
tests := []struct {
name string
user *models.SignedInUser
permission Permission
want Permission
permission accesscontrol.Permission
want accesscontrol.Permission
wantErr bool
}{
{
name: "no scope",
user: testUser,
permission: Permission{Action: "users:read"},
want: Permission{Action: "users:read"},
permission: accesscontrol.Permission{Action: "users:read"},
want: accesscontrol.Permission{Action: "users:read"},
wantErr: false,
},
{
name: "user if resolution",
user: testUser,
permission: Permission{Action: "users:read", Scope: "users:self"},
want: Permission{Action: "users:read", Scope: "users:id:2"},
permission: accesscontrol.Permission{Action: "users:read", Scope: "users:self"},
want: accesscontrol.Permission{Action: "users:read", Scope: "users:id:2"},
wantErr: false,
},
}
for _, tt := range tests {
var err error
t.Run(tt.name, func(t *testing.T) {
resolvers := NewScopeResolvers()
resolvers := accesscontrol.NewScopeResolvers()
scopeModifier := resolvers.GetScopeKeywordMutator(tt.user)
tt.permission.Scope, err = scopeModifier(context.TODO(), tt.permission.Scope)
if tt.wantErr {
@ -60,64 +63,64 @@ var testUser = &models.SignedInUser{
func TestResolveAttributeScope(t *testing.T) {
// Calls allow us to see how many times the fakeDataSourceResolution has been called
calls := 0
fakeDataSourceResolver := ScopeAttributeResolverFunc(func(ctx context.Context, orgID int64, initialScope string) ([]string, error) {
fakeDataSourceResolver := accesscontrol.ScopeAttributeResolverFunc(func(ctx context.Context, orgID int64, initialScope string) ([]string, error) {
calls++
if initialScope == "datasources:name:testds" {
return []string{Scope("datasources", "id", "1")}, nil
return []string{accesscontrol.Scope("datasources", "id", "1")}, nil
} else if initialScope == "datasources:name:testds2" {
return []string{Scope("datasources", "id", "2")}, nil
return []string{accesscontrol.Scope("datasources", "id", "2")}, nil
} else if initialScope == "datasources:name:test:ds4" {
return []string{Scope("datasources", "id", "4")}, nil
return []string{accesscontrol.Scope("datasources", "id", "4")}, nil
} else if initialScope == "datasources:name:testds5*" {
return []string{Scope("datasources", "id", "5")}, nil
return []string{accesscontrol.Scope("datasources", "id", "5")}, nil
} else {
return nil, models.ErrDataSourceNotFound
return nil, datasources.ErrDataSourceNotFound
}
})
tests := []struct {
name string
orgID int64
evaluator Evaluator
wantEvaluator Evaluator
evaluator accesscontrol.Evaluator
wantEvaluator accesscontrol.Evaluator
wantCalls int
wantErr error
}{
{
name: "should work with scope less permissions",
evaluator: EvalPermission("datasources:read"),
wantEvaluator: EvalPermission("datasources:read"),
evaluator: accesscontrol.EvalPermission("datasources:read"),
wantEvaluator: accesscontrol.EvalPermission("datasources:read"),
wantCalls: 0,
},
{
name: "should handle an error",
orgID: 1,
evaluator: EvalPermission("datasources:read", Scope("datasources", "name", "testds3")),
wantErr: models.ErrDataSourceNotFound,
evaluator: accesscontrol.EvalPermission("datasources:read", accesscontrol.Scope("datasources", "name", "testds3")),
wantErr: datasources.ErrDataSourceNotFound,
wantCalls: 1,
},
{
name: "should resolve a scope",
orgID: 1,
evaluator: EvalPermission("datasources:read", Scope("datasources", "name", "testds")),
wantEvaluator: EvalPermission("datasources:read", Scope("datasources", "id", "1")),
evaluator: accesscontrol.EvalPermission("datasources:read", accesscontrol.Scope("datasources", "name", "testds")),
wantEvaluator: accesscontrol.EvalPermission("datasources:read", accesscontrol.Scope("datasources", "id", "1")),
wantCalls: 1,
},
{
name: "should resolve nested scopes with cache",
orgID: 1,
evaluator: EvalAll(
EvalPermission("datasources:read", Scope("datasources", "name", "testds")),
EvalAny(
EvalPermission("datasources:read", Scope("datasources", "name", "testds")),
EvalPermission("datasources:read", Scope("datasources", "name", "testds2")),
evaluator: accesscontrol.EvalAll(
accesscontrol.EvalPermission("datasources:read", accesscontrol.Scope("datasources", "name", "testds")),
accesscontrol.EvalAny(
accesscontrol.EvalPermission("datasources:read", accesscontrol.Scope("datasources", "name", "testds")),
accesscontrol.EvalPermission("datasources:read", accesscontrol.Scope("datasources", "name", "testds2")),
),
),
wantEvaluator: EvalAll(
EvalPermission("datasources:read", Scope("datasources", "id", "1")),
EvalAny(
EvalPermission("datasources:read", Scope("datasources", "id", "1")),
EvalPermission("datasources:read", Scope("datasources", "id", "2")),
wantEvaluator: accesscontrol.EvalAll(
accesscontrol.EvalPermission("datasources:read", accesscontrol.Scope("datasources", "id", "1")),
accesscontrol.EvalAny(
accesscontrol.EvalPermission("datasources:read", accesscontrol.Scope("datasources", "id", "1")),
accesscontrol.EvalPermission("datasources:read", accesscontrol.Scope("datasources", "id", "2")),
),
),
wantCalls: 2,
@ -125,20 +128,20 @@ func TestResolveAttributeScope(t *testing.T) {
{
name: "should resolve name with colon",
orgID: 1,
evaluator: EvalPermission("datasources:read", Scope("datasources", "name", "test:ds4")),
wantEvaluator: EvalPermission("datasources:read", Scope("datasources", "id", "4")),
evaluator: accesscontrol.EvalPermission("datasources:read", accesscontrol.Scope("datasources", "name", "test:ds4")),
wantEvaluator: accesscontrol.EvalPermission("datasources:read", accesscontrol.Scope("datasources", "id", "4")),
wantCalls: 1,
},
{
name: "should resolve names with '*'",
orgID: 1,
evaluator: EvalPermission("datasources:read", Scope("datasources", "name", "testds5*")),
wantEvaluator: EvalPermission("datasources:read", Scope("datasources", "id", "5")),
evaluator: accesscontrol.EvalPermission("datasources:read", accesscontrol.Scope("datasources", "name", "testds5*")),
wantEvaluator: accesscontrol.EvalPermission("datasources:read", accesscontrol.Scope("datasources", "id", "5")),
wantCalls: 1,
},
}
for _, tt := range tests {
resolvers := NewScopeResolvers()
resolvers := accesscontrol.NewScopeResolvers()
// Reset calls counter
calls = 0

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
)
// DatasourceAlertUsage is a hash where the key represents the
@ -62,7 +63,7 @@ func (e *AlertEngine) mapRulesToUsageStats(ctx context.Context, rules []*models.
// map of datsource types and frequency
result := map[string]int{}
for k, v := range typeCount {
query := &models.GetDataSourceQuery{Id: k}
query := &datasources.GetDataSourceQuery{Id: k}
err := e.sqlStore.GetDataSource(ctx, query)
if err != nil {
return map[string]int{}, nil

View File

@ -7,9 +7,11 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/services/datasources"
)
func TestAlertingUsageStats(t *testing.T) {
@ -39,8 +41,8 @@ func TestAlertingUsageStats(t *testing.T) {
return nil
}
store.getDataSource = func(ctx context.Context, query *models.GetDataSourceQuery) error {
ds := map[int64]*models.DataSource{
store.getDataSource = func(ctx context.Context, query *datasources.GetDataSourceQuery) error {
ds := map[int64]*datasources.DataSource{
1: {Type: "influxdb"},
2: {Type: "graphite"},
3: {Type: "prometheus"},
@ -49,7 +51,7 @@ func TestAlertingUsageStats(t *testing.T) {
r, exist := ds[query.Id]
if !exist {
return models.ErrDataSourceNotFound
return datasources.ErrDataSourceNotFound
}
query.Result = r

View File

@ -13,10 +13,11 @@ import (
gocontext "context"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/datasources"
)
func init() {
@ -115,7 +116,7 @@ func (c *QueryCondition) Eval(context *alerting.EvalContext, requestHandler lega
}, nil
}
func calculateInterval(timeRange legacydata.DataTimeRange, model *simplejson.Json, dsInfo *models.DataSource) (time.Duration, error) {
func calculateInterval(timeRange legacydata.DataTimeRange, model *simplejson.Json, dsInfo *datasources.DataSource) (time.Duration, error) {
// if there is no min-interval specified in the datasource or in the dashboard-panel,
// the value of 1ms is used (this is how it is done in the dashboard-interval-calculation too,
// see https://github.com/grafana/grafana/blob/9a0040c0aeaae8357c650cec2ee644a571dddf3d/packages/grafana-data/src/datetime/rangeutil.ts#L264)
@ -141,7 +142,7 @@ func calculateInterval(timeRange legacydata.DataTimeRange, model *simplejson.Jso
func (c *QueryCondition) executeQuery(context *alerting.EvalContext, timeRange legacydata.DataTimeRange,
requestHandler legacydata.RequestHandler) (legacydata.DataTimeSeriesSlice, error) {
getDsInfo := &models.GetDataSourceQuery{
getDsInfo := &datasources.GetDataSourceQuery{
Id: c.Query.DatasourceID,
OrgId: context.Rule.OrgID,
}
@ -253,7 +254,7 @@ func (c *QueryCondition) executeQuery(context *alerting.EvalContext, timeRange l
return result, nil
}
func (c *QueryCondition) getRequestForAlertRule(datasource *models.DataSource, timeRange legacydata.DataTimeRange,
func (c *QueryCondition) getRequestForAlertRule(datasource *datasources.DataSource, timeRange legacydata.DataTimeRange,
debug bool) (legacydata.DataQuery, error) {
queryModel := c.Query.Model

View File

@ -5,8 +5,8 @@ import (
"testing"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/tsdb/intervalv2"
@ -127,7 +127,7 @@ type fakeIntervalTestReqHandler struct {
}
//nolint: staticcheck // legacydata.DataResponse deprecated
func (rh fakeIntervalTestReqHandler) HandleRequest(ctx context.Context, dsInfo *models.DataSource, query legacydata.DataQuery) (
func (rh fakeIntervalTestReqHandler) HandleRequest(ctx context.Context, dsInfo *datasources.DataSource, query legacydata.DataQuery) (
legacydata.DataResponse, error) {
q := query.Queries[0]
rh.verifier(q)
@ -138,7 +138,7 @@ func (rh fakeIntervalTestReqHandler) HandleRequest(ctx context.Context, dsInfo *
func applyScenario(t *testing.T, timeRange string, dataSourceJsonData *simplejson.Json, queryModel string, verifier func(query legacydata.DataSubQuery)) {
t.Run("desc", func(t *testing.T) {
store := mockstore.NewSQLStoreMock()
store.ExpectedDatasource = &models.DataSource{Id: 1, Type: "graphite", JsonData: dataSourceJsonData}
store.ExpectedDatasource = &datasources.DataSource{Id: 1, Type: "graphite", JsonData: dataSourceJsonData}
ctx := &queryIntervalTestContext{}
ctx.result = &alerting.EvalContext{

View File

@ -6,6 +6,7 @@ import (
"testing"
"time"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
@ -13,9 +14,9 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/stretchr/testify/require"
@ -36,7 +37,7 @@ func TestQueryCondition(t *testing.T) {
setup := func() *queryConditionTestContext {
ctx := &queryConditionTestContext{}
store := mockstore.NewSQLStoreMock()
store.ExpectedDatasource = &models.DataSource{Id: 1, Type: "graphite"}
store.ExpectedDatasource = &datasources.DataSource{Id: 1, Type: "graphite"}
ctx.reducer = `{"type":"avg"}`
ctx.evaluator = `{"type":"gt","params":[100]}`
@ -249,7 +250,7 @@ type fakeReqHandler struct {
}
//nolint: staticcheck // legacydata.DataPlugin deprecated
func (rh fakeReqHandler) HandleRequest(context.Context, *models.DataSource, legacydata.DataQuery) (
func (rh fakeReqHandler) HandleRequest(context.Context, *datasources.DataSource, legacydata.DataQuery) (
legacydata.DataResponse, error) {
return rh.response, nil
}

View File

@ -17,6 +17,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting/metrics"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/encryption"
"github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/rendering"
@ -28,7 +29,7 @@ import (
// A subset is needed to make it easier to mock during the tests.
type AlertStore interface {
GetAllAlertQueryHandler(context.Context, *models.GetAllAlertsQuery) error
GetDataSource(context.Context, *models.GetDataSourceQuery) error
GetDataSource(context.Context, *datasources.GetDataSourceQuery) error
SetAlertNotificationStateToCompleteCommand(context.Context, *models.SetAlertNotificationStateToCompleteCommand) error
SetAlertNotificationStateToPendingCommand(context.Context, *models.SetAlertNotificationStateToPendingCommand) error
GetAlertNotificationUidWithId(context.Context, *models.GetAlertNotificationUidQuery) error

View File

@ -7,14 +7,15 @@ import (
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/require"
)
type FakeEvalHandler struct {
@ -45,12 +46,12 @@ func (handler *FakeResultHandler) handle(evalContext *EvalContext) error {
// A mock implementation of the AlertStore interface, allowing to override certain methods individually
type AlertStoreMock struct {
getAllAlerts func(context.Context, *models.GetAllAlertsQuery) error
getDataSource func(context.Context, *models.GetDataSourceQuery) error
getDataSource func(context.Context, *datasources.GetDataSourceQuery) error
getAlertNotificationsWithUidToSend func(ctx context.Context, query *models.GetAlertNotificationsWithUidToSendQuery) error
getOrCreateNotificationState func(ctx context.Context, query *models.GetOrCreateNotificationStateQuery) error
}
func (a *AlertStoreMock) GetDataSource(c context.Context, cmd *models.GetDataSourceQuery) error {
func (a *AlertStoreMock) GetDataSource(c context.Context, cmd *datasources.GetDataSourceQuery) error {
if a.getDataSource != nil {
return a.getDataSource(c, cmd)
}
@ -120,8 +121,8 @@ func TestEngineProcessJob(t *testing.T) {
return nil
}
store.getDataSource = func(ctx context.Context, q *models.GetDataSourceQuery) error {
q.Result = &models.DataSource{Id: 1, Type: models.DS_PROMETHEUS}
store.getDataSource = func(ctx context.Context, q *datasources.GetDataSourceQuery) error {
q.Result = &datasources.DataSource{Id: 1, Type: datasources.DS_PROMETHEUS}
return nil
}

View File

@ -35,7 +35,7 @@ func ProvideDashAlertExtractorService(datasourcePermissionsService permissions.D
}
}
func (e *DashAlertExtractorService) lookupQueryDataSource(ctx context.Context, panel *simplejson.Json, panelQuery *simplejson.Json, orgID int64) (*models.DataSource, error) {
func (e *DashAlertExtractorService) lookupQueryDataSource(ctx context.Context, panel *simplejson.Json, panelQuery *simplejson.Json, orgID int64) (*datasources.DataSource, error) {
dsName := ""
dsUid := ""
@ -52,14 +52,14 @@ func (e *DashAlertExtractorService) lookupQueryDataSource(ctx context.Context, p
}
if dsName == "" && dsUid == "" {
query := &models.GetDefaultDataSourceQuery{OrgId: orgID}
query := &datasources.GetDefaultDataSourceQuery{OrgId: orgID}
if err := e.datasourceService.GetDefaultDataSource(ctx, query); err != nil {
return nil, err
}
return query.Result, nil
}
query := &models.GetDataSourceQuery{Name: dsName, Uid: dsUid, OrgId: orgID}
query := &datasources.GetDataSourceQuery{Name: dsName, Uid: dsUid, OrgId: orgID}
if err := e.datasourceService.GetDataSource(ctx, query); err != nil {
return nil, err
}
@ -208,9 +208,9 @@ func (e *DashAlertExtractorService) getAlertFromPanels(ctx context.Context, json
return nil, err
}
dsFilterQuery := models.DatasourcesPermissionFilterQuery{
dsFilterQuery := datasources.DatasourcesPermissionFilterQuery{
User: dashAlertInfo.User,
Datasources: []*models.DataSource{datasource},
Datasources: []*datasources.DataSource{datasource},
}
if err := e.datasourcePermissionsService.FilterDatasourcesBasedOnQueryPermissions(ctx, &dsFilterQuery); err != nil {
@ -218,7 +218,7 @@ func (e *DashAlertExtractorService) getAlertFromPanels(ctx context.Context, json
return nil, err
}
} else if len(dsFilterQuery.Result) == 0 {
return nil, models.ErrDataSourceAccessDenied
return nil, datasources.ErrDataSourceAccessDenied
}
jsonQuery.SetPath([]string{"datasourceId"}, datasource.Id)

View File

@ -7,14 +7,15 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/datasources/permissions"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestAlertRuleExtraction(t *testing.T) {
@ -23,14 +24,14 @@ func TestAlertRuleExtraction(t *testing.T) {
})
// mock data
defaultDs := &models.DataSource{Id: 12, OrgId: 1, Name: "I am default", IsDefault: true, Uid: "def-uid"}
graphite2Ds := &models.DataSource{Id: 15, OrgId: 1, Name: "graphite2", Uid: "graphite2-uid"}
defaultDs := &datasources.DataSource{Id: 12, OrgId: 1, Name: "I am default", IsDefault: true, Uid: "def-uid"}
graphite2Ds := &datasources.DataSource{Id: 15, OrgId: 1, Name: "graphite2", Uid: "graphite2-uid"}
json, err := ioutil.ReadFile("./testdata/graphite-alert.json")
require.Nil(t, err)
dsPermissions := permissions.NewMockDatasourcePermissionService()
dsPermissions.DsResult = []*models.DataSource{
dsPermissions.DsResult = []*datasources.DataSource{
{
Id: 1,
},
@ -69,7 +70,7 @@ func TestAlertRuleExtraction(t *testing.T) {
dashJSON, err := simplejson.NewJson(json)
require.Nil(t, err)
dsService.ExpectedDatasource = &models.DataSource{Id: 12}
dsService.ExpectedDatasource = &datasources.DataSource{Id: 12}
alerts, err := extractor.GetAlerts(context.Background(), DashAlertInfo{
User: nil,
Dash: models.NewDashboardFromJson(dashJSON),
@ -168,7 +169,7 @@ func TestAlertRuleExtraction(t *testing.T) {
dashJSON, err := simplejson.NewJson(panelWithoutSpecifiedDatasource)
require.Nil(t, err)
dsService.ExpectedDatasource = &models.DataSource{Id: 12}
dsService.ExpectedDatasource = &datasources.DataSource{Id: 12}
alerts, err := extractor.GetAlerts(context.Background(), DashAlertInfo{
User: nil,
Dash: models.NewDashboardFromJson(dashJSON),
@ -305,7 +306,7 @@ func TestFilterPermissionsErrors(t *testing.T) {
})
// mock data
defaultDs := &models.DataSource{Id: 12, OrgId: 1, Name: "I am default", IsDefault: true, Uid: "def-uid"}
defaultDs := &datasources.DataSource{Id: 12, OrgId: 1, Name: "I am default", IsDefault: true, Uid: "def-uid"}
json, err := ioutil.ReadFile("./testdata/graphite-alert.json")
require.Nil(t, err)
@ -318,13 +319,13 @@ func TestFilterPermissionsErrors(t *testing.T) {
tc := []struct {
name string
result []*models.DataSource
result []*datasources.DataSource
err error
expectedErr error
}{
{
"Data sources are filtered and return results don't return an error",
[]*models.DataSource{defaultDs},
[]*datasources.DataSource{defaultDs},
nil,
nil,
},
@ -332,7 +333,7 @@ func TestFilterPermissionsErrors(t *testing.T) {
"Data sources are filtered but return empty results should return error",
nil,
nil,
models.ErrDataSourceAccessDenied,
datasources.ErrDataSourceAccessDenied,
},
{
"Using default OSS implementation doesn't return an error",
@ -363,16 +364,16 @@ func TestFilterPermissionsErrors(t *testing.T) {
}
type fakeDatasourceService struct {
ExpectedDatasource *models.DataSource
ExpectedDatasource *datasources.DataSource
datasources.DataSourceService
}
func (f *fakeDatasourceService) GetDefaultDataSource(ctx context.Context, query *models.GetDefaultDataSourceQuery) error {
func (f *fakeDatasourceService) GetDefaultDataSource(ctx context.Context, query *datasources.GetDefaultDataSourceQuery) error {
query.Result = f.ExpectedDatasource
return nil
}
func (f *fakeDatasourceService) GetDataSource(ctx context.Context, query *models.GetDataSourceQuery) error {
func (f *fakeDatasourceService) GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) error {
query.Result = f.ExpectedDatasource
return nil
}

View File

@ -92,18 +92,18 @@ func (p *DataSourceProxyService) ProxyDatasourceRequestWithID(c *models.ReqConte
}
func toAPIError(c *models.ReqContext, err error) {
if errors.Is(err, models.ErrDataSourceAccessDenied) {
if errors.Is(err, datasources.ErrDataSourceAccessDenied) {
c.JsonApiErr(http.StatusForbidden, "Access denied to datasource", err)
return
}
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
c.JsonApiErr(http.StatusNotFound, "Unable to find datasource", err)
return
}
c.JsonApiErr(http.StatusInternalServerError, "Unable to load datasource meta data", err)
}
func (p *DataSourceProxyService) proxyDatasourceRequest(c *models.ReqContext, ds *models.DataSource) {
func (p *DataSourceProxyService) proxyDatasourceRequest(c *models.ReqContext, ds *datasources.DataSource) {
err := p.PluginRequestValidator.Validate(ds.Url, c.Req)
if err != nil {
c.JsonApiErr(http.StatusForbidden, "Access denied", err)

View File

@ -5,6 +5,7 @@ import (
"net/http"
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana/pkg/infra/httpclient"
"github.com/grafana/grafana/pkg/models"
)
@ -12,51 +13,51 @@ import (
// DataSourceService interface for interacting with datasources.
type DataSourceService interface {
// GetDataSource gets a datasource.
GetDataSource(ctx context.Context, query *models.GetDataSourceQuery) error
GetDataSource(ctx context.Context, query *GetDataSourceQuery) error
// GetDataSources gets datasources.
GetDataSources(ctx context.Context, query *models.GetDataSourcesQuery) error
GetDataSources(ctx context.Context, query *GetDataSourcesQuery) error
// GetDataSourcesByType gets datasources by type.
GetDataSourcesByType(ctx context.Context, query *models.GetDataSourcesByTypeQuery) error
GetDataSourcesByType(ctx context.Context, query *GetDataSourcesByTypeQuery) error
// AddDataSource adds a new datasource.
AddDataSource(ctx context.Context, cmd *models.AddDataSourceCommand) error
AddDataSource(ctx context.Context, cmd *AddDataSourceCommand) error
// DeleteDataSource deletes an existing datasource.
DeleteDataSource(ctx context.Context, cmd *models.DeleteDataSourceCommand) error
DeleteDataSource(ctx context.Context, cmd *DeleteDataSourceCommand) error
// UpdateDataSource updates an existing datasource.
UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSourceCommand) error
UpdateDataSource(ctx context.Context, cmd *UpdateDataSourceCommand) error
// GetDefaultDataSource gets the default datasource.
GetDefaultDataSource(ctx context.Context, query *models.GetDefaultDataSourceQuery) error
GetDefaultDataSource(ctx context.Context, query *GetDefaultDataSourceQuery) error
// GetHTTPTransport gets a datasource specific HTTP transport.
GetHTTPTransport(ctx context.Context, ds *models.DataSource, provider httpclient.Provider, customMiddlewares ...sdkhttpclient.Middleware) (http.RoundTripper, error)
GetHTTPTransport(ctx context.Context, ds *DataSource, provider httpclient.Provider, customMiddlewares ...sdkhttpclient.Middleware) (http.RoundTripper, error)
// DecryptedValues decrypts the encrypted secureJSONData of the provided datasource and
// returns the decrypted values.
DecryptedValues(ctx context.Context, ds *models.DataSource) (map[string]string, error)
DecryptedValues(ctx context.Context, ds *DataSource) (map[string]string, error)
// DecryptedValue decrypts the encrypted datasource secureJSONData identified by key
// and returns the decrypted value.
DecryptedValue(ctx context.Context, ds *models.DataSource, key string) (string, bool, error)
DecryptedValue(ctx context.Context, ds *DataSource, key string) (string, bool, error)
// DecryptedBasicAuthPassword decrypts the encrypted datasource basic authentication
// password and returns the decrypted value.
DecryptedBasicAuthPassword(ctx context.Context, ds *models.DataSource) (string, error)
DecryptedBasicAuthPassword(ctx context.Context, ds *DataSource) (string, error)
// DecryptedPassword decrypts the encrypted datasource password and returns the
// decrypted value.
DecryptedPassword(ctx context.Context, ds *models.DataSource) (string, error)
DecryptedPassword(ctx context.Context, ds *DataSource) (string, error)
}
// CacheService interface for retrieving a cached datasource.
type CacheService interface {
// GetDatasource gets a datasource identified by datasource numeric identifier.
GetDatasource(ctx context.Context, datasourceID int64, user *models.SignedInUser, skipCache bool) (*models.DataSource, error)
GetDatasource(ctx context.Context, datasourceID int64, user *models.SignedInUser, skipCache bool) (*DataSource, error)
// GetDatasourceByUID gets a datasource identified by datasource unique identifier (UID).
GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*models.DataSource, error)
GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*DataSource, error)
}

View File

@ -0,0 +1,13 @@
package datasources
import "errors"
var (
ErrDataSourceNotFound = errors.New("data source not found")
ErrDataSourceNameExists = errors.New("data source with the same name already exists")
ErrDataSourceUidExists = errors.New("data source with the same uid already exists")
ErrDataSourceUpdatingOldVersion = errors.New("trying to update old version of datasource")
ErrDataSourceAccessDenied = errors.New("data source access denied")
ErrDataSourceFailedGenerateUniqueUid = errors.New("failed to generate unique datasource ID")
ErrDataSourceIdentifierNotSet = errors.New("unique identifier and org id are needed to be able to get or delete a datasource")
)

View File

@ -8,25 +8,25 @@ import (
)
type FakeCacheService struct {
DataSources []*models.DataSource
DataSources []*datasources.DataSource
}
var _ datasources.CacheService = &FakeCacheService{}
func (c *FakeCacheService) GetDatasource(ctx context.Context, datasourceID int64, user *models.SignedInUser, skipCache bool) (*models.DataSource, error) {
func (c *FakeCacheService) GetDatasource(ctx context.Context, datasourceID int64, user *models.SignedInUser, skipCache bool) (*datasources.DataSource, error) {
for _, datasource := range c.DataSources {
if datasource.Id == datasourceID {
return datasource, nil
}
}
return nil, models.ErrDataSourceNotFound
return nil, datasources.ErrDataSourceNotFound
}
func (c *FakeCacheService) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*models.DataSource, error) {
func (c *FakeCacheService) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*datasources.DataSource, error) {
for _, datasource := range c.DataSources {
if datasource.Uid == datasourceUID {
return datasource, nil
}
}
return nil, models.ErrDataSourceNotFound
return nil, datasources.ErrDataSourceNotFound
}

View File

@ -5,19 +5,19 @@ import (
"net/http"
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana/pkg/infra/httpclient"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
)
type FakeDataSourceService struct {
lastId int64
DataSources []*models.DataSource
DataSources []*datasources.DataSource
}
var _ datasources.DataSourceService = &FakeDataSourceService{}
func (s *FakeDataSourceService) GetDataSource(ctx context.Context, query *models.GetDataSourceQuery) error {
func (s *FakeDataSourceService) GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) error {
for _, datasource := range s.DataSources {
idMatch := query.Id != 0 && query.Id == datasource.Id
uidMatch := query.Uid != "" && query.Uid == datasource.Uid
@ -28,10 +28,10 @@ func (s *FakeDataSourceService) GetDataSource(ctx context.Context, query *models
return nil
}
}
return models.ErrDataSourceNotFound
return datasources.ErrDataSourceNotFound
}
func (s *FakeDataSourceService) GetDataSources(ctx context.Context, query *models.GetDataSourcesQuery) error {
func (s *FakeDataSourceService) GetDataSources(ctx context.Context, query *datasources.GetDataSourcesQuery) error {
for _, datasource := range s.DataSources {
orgMatch := query.OrgId != 0 && query.OrgId == datasource.OrgId
if orgMatch {
@ -41,7 +41,7 @@ func (s *FakeDataSourceService) GetDataSources(ctx context.Context, query *model
return nil
}
func (s *FakeDataSourceService) GetDataSourcesByType(ctx context.Context, query *models.GetDataSourcesByTypeQuery) error {
func (s *FakeDataSourceService) GetDataSourcesByType(ctx context.Context, query *datasources.GetDataSourcesByTypeQuery) error {
for _, datasource := range s.DataSources {
typeMatch := query.Type != "" && query.Type == datasource.Type
if typeMatch {
@ -51,11 +51,11 @@ func (s *FakeDataSourceService) GetDataSourcesByType(ctx context.Context, query
return nil
}
func (s *FakeDataSourceService) AddDataSource(ctx context.Context, cmd *models.AddDataSourceCommand) error {
func (s *FakeDataSourceService) AddDataSource(ctx context.Context, cmd *datasources.AddDataSourceCommand) error {
if s.lastId == 0 {
s.lastId = int64(len(s.DataSources) - 1)
}
cmd.Result = &models.DataSource{
cmd.Result = &datasources.DataSource{
Id: s.lastId + 1,
Name: cmd.Name,
Type: cmd.Type,
@ -66,7 +66,7 @@ func (s *FakeDataSourceService) AddDataSource(ctx context.Context, cmd *models.A
return nil
}
func (s *FakeDataSourceService) DeleteDataSource(ctx context.Context, cmd *models.DeleteDataSourceCommand) error {
func (s *FakeDataSourceService) DeleteDataSource(ctx context.Context, cmd *datasources.DeleteDataSourceCommand) error {
for i, datasource := range s.DataSources {
idMatch := cmd.ID != 0 && cmd.ID == datasource.Id
uidMatch := cmd.UID != "" && cmd.UID == datasource.Uid
@ -76,10 +76,10 @@ func (s *FakeDataSourceService) DeleteDataSource(ctx context.Context, cmd *model
return nil
}
}
return models.ErrDataSourceNotFound
return datasources.ErrDataSourceNotFound
}
func (s *FakeDataSourceService) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSourceCommand) error {
func (s *FakeDataSourceService) UpdateDataSource(ctx context.Context, cmd *datasources.UpdateDataSourceCommand) error {
for _, datasource := range s.DataSources {
idMatch := cmd.Id != 0 && cmd.Id == datasource.Id
uidMatch := cmd.Uid != "" && cmd.Uid == datasource.Uid
@ -91,14 +91,14 @@ func (s *FakeDataSourceService) UpdateDataSource(ctx context.Context, cmd *model
return nil
}
}
return models.ErrDataSourceNotFound
return datasources.ErrDataSourceNotFound
}
func (s *FakeDataSourceService) GetDefaultDataSource(ctx context.Context, query *models.GetDefaultDataSourceQuery) error {
func (s *FakeDataSourceService) GetDefaultDataSource(ctx context.Context, query *datasources.GetDefaultDataSourceQuery) error {
return nil
}
func (s *FakeDataSourceService) GetHTTPTransport(ctx context.Context, ds *models.DataSource, provider httpclient.Provider, customMiddlewares ...sdkhttpclient.Middleware) (http.RoundTripper, error) {
func (s *FakeDataSourceService) GetHTTPTransport(ctx context.Context, ds *datasources.DataSource, provider httpclient.Provider, customMiddlewares ...sdkhttpclient.Middleware) (http.RoundTripper, error) {
rt, err := provider.GetTransport(sdkhttpclient.Options{})
if err != nil {
return nil, err
@ -106,19 +106,19 @@ func (s *FakeDataSourceService) GetHTTPTransport(ctx context.Context, ds *models
return rt, nil
}
func (s *FakeDataSourceService) DecryptedValues(ctx context.Context, ds *models.DataSource) (map[string]string, error) {
func (s *FakeDataSourceService) DecryptedValues(ctx context.Context, ds *datasources.DataSource) (map[string]string, error) {
values := make(map[string]string)
return values, nil
}
func (s *FakeDataSourceService) DecryptedValue(ctx context.Context, ds *models.DataSource, key string) (string, bool, error) {
func (s *FakeDataSourceService) DecryptedValue(ctx context.Context, ds *datasources.DataSource, key string) (string, bool, error) {
return "", false, nil
}
func (s *FakeDataSourceService) DecryptedBasicAuthPassword(ctx context.Context, ds *models.DataSource) (string, error) {
func (s *FakeDataSourceService) DecryptedBasicAuthPassword(ctx context.Context, ds *datasources.DataSource) (string, error) {
return "", nil
}
func (s *FakeDataSourceService) DecryptedPassword(ctx context.Context, ds *models.DataSource) (string, error) {
func (s *FakeDataSourceService) DecryptedPassword(ctx context.Context, ds *datasources.DataSource) (string, error) {
return "", nil
}

View File

@ -1,10 +1,10 @@
package models
package datasources
import (
"errors"
"time"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
)
const (
@ -28,17 +28,6 @@ const (
DS_ES_OPENSEARCH = "grafana-opensearch-datasource"
)
var (
ErrDataSourceNotFound = errors.New("data source not found")
ErrDataSourceNameExists = errors.New("data source with the same name already exists")
ErrDataSourceUidExists = errors.New("data source with the same uid already exists")
ErrDataSourceUpdatingOldVersion = errors.New("trying to update old version of datasource")
ErrDatasourceIsReadOnly = errors.New("data source is readonly, can only be updated from configuration")
ErrDataSourceAccessDenied = errors.New("data source access denied")
ErrDataSourceFailedGenerateUniqueUid = errors.New("failed to generate unique datasource ID")
ErrDataSourceIdentifierNotSet = errors.New("unique identifier and org id are needed to be able to get or delete a datasource")
)
type DsAccess string
type DataSource struct {
@ -167,7 +156,7 @@ type UpdateSecretFn func() error
type GetDataSourcesQuery struct {
OrgId int64
DataSourceLimit int
User *SignedInUser
User *models.SignedInUser
Result []*DataSource
}
@ -178,7 +167,7 @@ type GetDataSourcesByTypeQuery struct {
type GetDefaultDataSourceQuery struct {
OrgId int64
User *SignedInUser
User *models.SignedInUser
Result *DataSource
}
@ -220,7 +209,7 @@ func (p DsPermissionType) String() string {
}
type DatasourcesPermissionFilterQuery struct {
User *SignedInUser
User *models.SignedInUser
Datasources []*DataSource
Result []*DataSource
}

View File

@ -4,17 +4,17 @@ import (
"context"
"errors"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
)
var ErrNotImplemented = errors.New("not implemented")
type DatasourcePermissionsService interface {
FilterDatasourcesBasedOnQueryPermissions(ctx context.Context, cmd *models.DatasourcesPermissionFilterQuery) error
FilterDatasourcesBasedOnQueryPermissions(ctx context.Context, cmd *datasources.DatasourcesPermissionFilterQuery) error
}
// dummy method
func (hs *OSSDatasourcePermissionsService) FilterDatasourcesBasedOnQueryPermissions(ctx context.Context, cmd *models.DatasourcesPermissionFilterQuery) error {
func (hs *OSSDatasourcePermissionsService) FilterDatasourcesBasedOnQueryPermissions(ctx context.Context, cmd *datasources.DatasourcesPermissionFilterQuery) error {
return ErrNotImplemented
}

View File

@ -3,15 +3,15 @@ package permissions
import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
)
type mockDatasourcePermissionService struct {
DsResult []*models.DataSource
DsResult []*datasources.DataSource
ErrResult error
}
func (m *mockDatasourcePermissionService) FilterDatasourcesBasedOnQueryPermissions(ctx context.Context, cmd *models.DatasourcesPermissionFilterQuery) error {
func (m *mockDatasourcePermissionService) FilterDatasourcesBasedOnQueryPermissions(ctx context.Context, cmd *datasources.DatasourcesPermissionFilterQuery) error {
cmd.Result = m.DsResult
return m.ErrResult
}

View File

@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/infra/localcache"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
@ -30,12 +31,12 @@ func (dc *CacheServiceImpl) GetDatasource(
datasourceID int64,
user *models.SignedInUser,
skipCache bool,
) (*models.DataSource, error) {
) (*datasources.DataSource, error) {
cacheKey := idKey(datasourceID)
if !skipCache {
if cached, found := dc.CacheService.Get(cacheKey); found {
ds := cached.(*models.DataSource)
ds := cached.(*datasources.DataSource)
if ds.OrgId == user.OrgId {
return ds, nil
}
@ -44,7 +45,7 @@ func (dc *CacheServiceImpl) GetDatasource(
dc.logger.Debug("Querying for data source via SQL store", "id", datasourceID, "orgId", user.OrgId)
query := &models.GetDataSourceQuery{Id: datasourceID, OrgId: user.OrgId}
query := &datasources.GetDataSourceQuery{Id: datasourceID, OrgId: user.OrgId}
err := dc.SQLStore.GetDataSource(ctx, query)
if err != nil {
return nil, err
@ -64,7 +65,7 @@ func (dc *CacheServiceImpl) GetDatasourceByUID(
datasourceUID string,
user *models.SignedInUser,
skipCache bool,
) (*models.DataSource, error) {
) (*datasources.DataSource, error) {
if datasourceUID == "" {
return nil, fmt.Errorf("can not get data source by uid, uid is empty")
}
@ -75,7 +76,7 @@ func (dc *CacheServiceImpl) GetDatasourceByUID(
if !skipCache {
if cached, found := dc.CacheService.Get(uidCacheKey); found {
ds := cached.(*models.DataSource)
ds := cached.(*datasources.DataSource)
if ds.OrgId == user.OrgId {
return ds, nil
}
@ -83,7 +84,7 @@ func (dc *CacheServiceImpl) GetDatasourceByUID(
}
dc.logger.Debug("Querying for data source via SQL store", "uid", datasourceUID, "orgId", user.OrgId)
query := &models.GetDataSourceQuery{Uid: datasourceUID, OrgId: user.OrgId}
query := &datasources.GetDataSourceQuery{Uid: datasourceUID, OrgId: user.OrgId}
err := dc.SQLStore.GetDataSource(ctx, query)
if err != nil {
return nil, err

View File

@ -15,7 +15,6 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/httpclient"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/featuremgmt"
@ -73,7 +72,7 @@ func ProvideService(
// DataSourceRetriever interface for retrieving a datasource.
type DataSourceRetriever interface {
// GetDataSource gets a datasource.
GetDataSource(ctx context.Context, query *models.GetDataSourceQuery) error
GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) error
}
const secretType = "datasource"
@ -92,7 +91,7 @@ func NewNameScopeResolver(db DataSourceRetriever) (string, accesscontrol.ScopeAt
return nil, accesscontrol.ErrInvalidScope
}
query := models.GetDataSourceQuery{Name: dsName, OrgId: orgID}
query := datasources.GetDataSourceQuery{Name: dsName, OrgId: orgID}
if err := db.GetDataSource(ctx, &query); err != nil {
return nil, err
}
@ -120,7 +119,7 @@ func NewIDScopeResolver(db DataSourceRetriever) (string, accesscontrol.ScopeAttr
return nil, accesscontrol.ErrInvalidScope
}
query := models.GetDataSourceQuery{Id: dsID, OrgId: orgID}
query := datasources.GetDataSourceQuery{Id: dsID, OrgId: orgID}
if err := db.GetDataSource(ctx, &query); err != nil {
return nil, err
}
@ -129,19 +128,19 @@ func NewIDScopeResolver(db DataSourceRetriever) (string, accesscontrol.ScopeAttr
})
}
func (s *Service) GetDataSource(ctx context.Context, query *models.GetDataSourceQuery) error {
func (s *Service) GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) error {
return s.SQLStore.GetDataSource(ctx, query)
}
func (s *Service) GetDataSources(ctx context.Context, query *models.GetDataSourcesQuery) error {
func (s *Service) GetDataSources(ctx context.Context, query *datasources.GetDataSourcesQuery) error {
return s.SQLStore.GetDataSources(ctx, query)
}
func (s *Service) GetDataSourcesByType(ctx context.Context, query *models.GetDataSourcesByTypeQuery) error {
func (s *Service) GetDataSourcesByType(ctx context.Context, query *datasources.GetDataSourcesByTypeQuery) error {
return s.SQLStore.GetDataSourcesByType(ctx, query)
}
func (s *Service) AddDataSource(ctx context.Context, cmd *models.AddDataSourceCommand) error {
func (s *Service) AddDataSource(ctx context.Context, cmd *datasources.AddDataSourceCommand) error {
return s.SQLStore.InTransaction(ctx, func(ctx context.Context) error {
var err error
// this is here for backwards compatibility
@ -185,7 +184,7 @@ func (s *Service) AddDataSource(ctx context.Context, cmd *models.AddDataSourceCo
})
}
func (s *Service) DeleteDataSource(ctx context.Context, cmd *models.DeleteDataSourceCommand) error {
func (s *Service) DeleteDataSource(ctx context.Context, cmd *datasources.DeleteDataSourceCommand) error {
return s.SQLStore.InTransaction(ctx, func(ctx context.Context) error {
cmd.UpdateSecretFn = func() error {
return s.SecretsStore.Del(ctx, cmd.OrgID, cmd.Name, secretType)
@ -195,11 +194,11 @@ func (s *Service) DeleteDataSource(ctx context.Context, cmd *models.DeleteDataSo
})
}
func (s *Service) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSourceCommand) error {
func (s *Service) UpdateDataSource(ctx context.Context, cmd *datasources.UpdateDataSourceCommand) error {
return s.SQLStore.InTransaction(ctx, func(ctx context.Context) error {
var err error
query := &models.GetDataSourceQuery{
query := &datasources.GetDataSourceQuery{
Id: cmd.Id,
OrgId: cmd.OrgId,
}
@ -234,11 +233,11 @@ func (s *Service) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSo
})
}
func (s *Service) GetDefaultDataSource(ctx context.Context, query *models.GetDefaultDataSourceQuery) error {
func (s *Service) GetDefaultDataSource(ctx context.Context, query *datasources.GetDefaultDataSourceQuery) error {
return s.SQLStore.GetDefaultDataSource(ctx, query)
}
func (s *Service) GetHTTPClient(ctx context.Context, ds *models.DataSource, provider httpclient.Provider) (*http.Client, error) {
func (s *Service) GetHTTPClient(ctx context.Context, ds *datasources.DataSource, provider httpclient.Provider) (*http.Client, error) {
transport, err := s.GetHTTPTransport(ctx, ds, provider)
if err != nil {
return nil, err
@ -250,7 +249,7 @@ func (s *Service) GetHTTPClient(ctx context.Context, ds *models.DataSource, prov
}, nil
}
func (s *Service) GetHTTPTransport(ctx context.Context, ds *models.DataSource, provider httpclient.Provider,
func (s *Service) GetHTTPTransport(ctx context.Context, ds *datasources.DataSource, provider httpclient.Provider,
customMiddlewares ...sdkhttpclient.Middleware) (http.RoundTripper, error) {
s.ptc.Lock()
defer s.ptc.Unlock()
@ -279,7 +278,7 @@ func (s *Service) GetHTTPTransport(ctx context.Context, ds *models.DataSource, p
return rt, nil
}
func (s *Service) GetTLSConfig(ctx context.Context, ds *models.DataSource, httpClientProvider httpclient.Provider) (*tls.Config, error) {
func (s *Service) GetTLSConfig(ctx context.Context, ds *datasources.DataSource, httpClientProvider httpclient.Provider) (*tls.Config, error) {
opts, err := s.httpClientOptions(ctx, ds)
if err != nil {
return nil, err
@ -287,7 +286,7 @@ func (s *Service) GetTLSConfig(ctx context.Context, ds *models.DataSource, httpC
return httpClientProvider.GetTLSConfig(*opts)
}
func (s *Service) DecryptedValues(ctx context.Context, ds *models.DataSource) (map[string]string, error) {
func (s *Service) DecryptedValues(ctx context.Context, ds *datasources.DataSource) (map[string]string, error) {
decryptedValues := make(map[string]string)
secret, exist, err := s.SecretsStore.Get(ctx, ds.OrgId, ds.Name, secretType)
if err != nil {
@ -308,7 +307,7 @@ func (s *Service) DecryptedValues(ctx context.Context, ds *models.DataSource) (m
return decryptedValues, nil
}
func (s *Service) MigrateSecrets(ctx context.Context, ds *models.DataSource) (map[string]string, error) {
func (s *Service) MigrateSecrets(ctx context.Context, ds *datasources.DataSource) (map[string]string, error) {
secureJsonData := make(map[string]string)
for k, v := range ds.SecureJsonData {
decrypted, err := s.SecretsService.Decrypt(ctx, v)
@ -327,7 +326,7 @@ func (s *Service) MigrateSecrets(ctx context.Context, ds *models.DataSource) (ma
return secureJsonData, err
}
func (s *Service) DecryptedValue(ctx context.Context, ds *models.DataSource, key string) (string, bool, error) {
func (s *Service) DecryptedValue(ctx context.Context, ds *datasources.DataSource, key string) (string, bool, error) {
values, err := s.DecryptedValues(ctx, ds)
if err != nil {
return "", false, err
@ -336,7 +335,7 @@ func (s *Service) DecryptedValue(ctx context.Context, ds *models.DataSource, key
return value, exists, nil
}
func (s *Service) DecryptedBasicAuthPassword(ctx context.Context, ds *models.DataSource) (string, error) {
func (s *Service) DecryptedBasicAuthPassword(ctx context.Context, ds *datasources.DataSource) (string, error) {
value, ok, err := s.DecryptedValue(ctx, ds, "basicAuthPassword")
if ok {
return value, nil
@ -345,7 +344,7 @@ func (s *Service) DecryptedBasicAuthPassword(ctx context.Context, ds *models.Dat
return "", err
}
func (s *Service) DecryptedPassword(ctx context.Context, ds *models.DataSource) (string, error) {
func (s *Service) DecryptedPassword(ctx context.Context, ds *datasources.DataSource) (string, error) {
value, ok, err := s.DecryptedValue(ctx, ds, "password")
if ok {
return value, nil
@ -354,7 +353,7 @@ func (s *Service) DecryptedPassword(ctx context.Context, ds *models.DataSource)
return "", err
}
func (s *Service) httpClientOptions(ctx context.Context, ds *models.DataSource) (*sdkhttpclient.Options, error) {
func (s *Service) httpClientOptions(ctx context.Context, ds *datasources.DataSource) (*sdkhttpclient.Options, error) {
tlsOptions, err := s.dsTLSOptions(ctx, ds)
if err != nil {
return nil, err
@ -442,7 +441,7 @@ func (s *Service) httpClientOptions(ctx context.Context, ds *models.DataSource)
return opts, nil
}
func (s *Service) dsTLSOptions(ctx context.Context, ds *models.DataSource) (sdkhttpclient.TLSOptions, error) {
func (s *Service) dsTLSOptions(ctx context.Context, ds *datasources.DataSource) (sdkhttpclient.TLSOptions, error) {
var tlsSkipVerify, tlsClientAuth, tlsAuthWithCACert bool
var serverName string
@ -491,7 +490,7 @@ func (s *Service) dsTLSOptions(ctx context.Context, ds *models.DataSource) (sdkh
return opts, nil
}
func (s *Service) getTimeout(ds *models.DataSource) time.Duration {
func (s *Service) getTimeout(ds *datasources.DataSource) time.Duration {
timeout := 0
if ds.JsonData != nil {
timeout = ds.JsonData.Get("timeout").MustInt()
@ -540,16 +539,16 @@ func (s *Service) getCustomHeaders(jsonData *simplejson.Json, decryptedValues ma
func awsServiceNamespace(dsType string) string {
switch dsType {
case models.DS_ES, models.DS_ES_OPEN_DISTRO, models.DS_ES_OPENSEARCH:
case datasources.DS_ES, datasources.DS_ES_OPEN_DISTRO, datasources.DS_ES_OPENSEARCH:
return "es"
case models.DS_PROMETHEUS, models.DS_ALERTMANAGER:
case datasources.DS_PROMETHEUS, datasources.DS_ALERTMANAGER:
return "aps"
default:
panic(fmt.Sprintf("Unsupported datasource %q", dsType))
}
}
func (s *Service) fillWithSecureJSONData(ctx context.Context, cmd *models.UpdateDataSourceCommand, ds *models.DataSource) error {
func (s *Service) fillWithSecureJSONData(ctx context.Context, cmd *datasources.UpdateDataSourceCommand, ds *datasources.DataSource) error {
decrypted, err := s.DecryptedValues(ctx, ds)
if err != nil {
return err

View File

@ -10,27 +10,27 @@ import (
"time"
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana/pkg/services/secrets"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/httpclient"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
"github.com/grafana/grafana/pkg/services/secrets/kvstore"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type dataSourceMockRetriever struct {
res []*models.DataSource
res []*datasources.DataSource
}
func (d *dataSourceMockRetriever) GetDataSource(ctx context.Context, query *models.GetDataSourceQuery) error {
func (d *dataSourceMockRetriever) GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) error {
for _, datasource := range d.res {
idMatch := query.Id != 0 && query.Id == datasource.Id
uidMatch := query.Uid != "" && query.Uid == datasource.Uid
@ -41,11 +41,11 @@ func (d *dataSourceMockRetriever) GetDataSource(ctx context.Context, query *mode
return nil
}
}
return models.ErrDataSourceNotFound
return datasources.ErrDataSourceNotFound
}
func TestService_NameScopeResolver(t *testing.T) {
retriever := &dataSourceMockRetriever{[]*models.DataSource{
retriever := &dataSourceMockRetriever{[]*datasources.DataSource{
{Name: "test-datasource", Uid: "1"},
{Name: "*", Uid: "2"},
{Name: ":/*", Uid: "3"},
@ -88,7 +88,7 @@ func TestService_NameScopeResolver(t *testing.T) {
desc: "unknown datasource",
given: "datasources:name:unknown-datasource",
want: "",
wantErr: models.ErrDataSourceNotFound,
wantErr: datasources.ErrDataSourceNotFound,
},
{
desc: "malformed scope",
@ -122,7 +122,7 @@ func TestService_NameScopeResolver(t *testing.T) {
}
func TestService_IDScopeResolver(t *testing.T) {
retriever := &dataSourceMockRetriever{[]*models.DataSource{
retriever := &dataSourceMockRetriever{[]*datasources.DataSource{
{Id: 1, Uid: "NnftN9Lnz"},
}}
@ -189,7 +189,7 @@ func TestService_GetHttpTransport(t *testing.T) {
},
})
ds := models.DataSource{
ds := datasources.DataSource{
Id: 1,
Url: "http://k8s:8001",
Type: "Kubernetes",
@ -233,7 +233,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
ds := datasources.DataSource{
Id: 1,
Url: "http://k8s:8001",
Type: "Kubernetes",
@ -281,7 +281,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
ds := datasources.DataSource{
Id: 1,
OrgId: 1,
Name: "kubernetes",
@ -326,7 +326,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
ds := datasources.DataSource{
Id: 1,
OrgId: 1,
Name: "kubernetes",
@ -368,7 +368,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
ds := datasources.DataSource{
Id: 1,
Url: "http://k8s:8001",
Type: "Kubernetes",
@ -400,7 +400,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
ds := datasources.DataSource{
Id: 1,
OrgId: 1,
Name: "kubernetes",
@ -466,7 +466,7 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
ds := datasources.DataSource{
Id: 1,
Url: "http://k8s:8001",
Type: "Kubernetes",
@ -500,8 +500,8 @@ func TestService_GetHttpTransport(t *testing.T) {
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := models.DataSource{
Type: models.DS_ES,
ds := datasources.DataSource{
Type: datasources.DS_ES,
JsonData: sjson,
}
@ -537,7 +537,7 @@ func TestService_getTimeout(t *testing.T) {
dsService := ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
for _, tc := range testCases {
ds := &models.DataSource{
ds := &datasources.DataSource{
JsonData: tc.jsonData,
}
assert.Equal(t, tc.expectedTimeout, dsService.getTimeout(ds))
@ -546,7 +546,7 @@ func TestService_getTimeout(t *testing.T) {
func TestService_GetDecryptedValues(t *testing.T) {
t.Run("should migrate and retrieve values from secure json data", func(t *testing.T) {
ds := &models.DataSource{
ds := &datasources.DataSource{
Id: 1,
Url: "https://api.example.com",
Type: "prometheus",
@ -571,7 +571,7 @@ func TestService_GetDecryptedValues(t *testing.T) {
})
t.Run("should retrieve values from secret store", func(t *testing.T) {
ds := &models.DataSource{
ds := &datasources.DataSource{
Id: 1,
Url: "https://api.example.com",
Type: "prometheus",

View File

@ -0,0 +1,16 @@
package datasources
import (
"context"
)
// Store is the interface for the datasource Service's storage.
type Store interface {
GetDataSource(context.Context, *GetDataSourceQuery) error
GetDataSources(context.Context, *GetDataSourcesQuery) error
GetDataSourcesByType(context.Context, *GetDataSourcesByTypeQuery) error
GetDefaultDataSource(context.Context, *GetDefaultDataSourceQuery) error
DeleteDataSource(context.Context, *DeleteDataSourceCommand) error
AddDataSource(context.Context, *AddDataSourceCommand) error
UpdateDataSource(context.Context, *UpdateDataSourceCommand) error
}

View File

@ -593,7 +593,7 @@ func (g *GrafanaLive) handleOnRPC(client *centrifuge.Client, e centrifuge.RPCEve
resp, err := g.queryDataService.QueryData(client.Context(), user, false, req, true)
if err != nil {
logger.Error("Error query data", "user", client.UserID(), "client", client.ID(), "method", e.Method, "error", err)
if errors.Is(err, models.ErrDataSourceAccessDenied) {
if errors.Is(err, datasources.ErrDataSourceAccessDenied) {
return centrifuge.RPCReply{}, &centrifuge.Error{Code: uint32(http.StatusForbidden), Message: http.StatusText(http.StatusForbidden)}
}
var badQuery *query.ErrBadQuery

View File

@ -62,7 +62,7 @@ func TestRouteTestGrafanaRuleConfig(t *testing.T) {
{Action: datasources.ActionQuery, Scope: datasources.ScopeProvider.GetResourceScopeUID(data2.DatasourceUID)},
})
ds := &fakes.FakeCacheService{DataSources: []*models2.DataSource{
ds := &fakes.FakeCacheService{DataSources: []*datasources.DataSource{
{Uid: data1.DatasourceUID},
{Uid: data2.DatasourceUID},
}}
@ -103,7 +103,7 @@ func TestRouteTestGrafanaRuleConfig(t *testing.T) {
t.Run("should require user to be signed in", func(t *testing.T) {
data1 := models.GenerateAlertQuery()
ds := &fakes.FakeCacheService{DataSources: []*models2.DataSource{
ds := &fakes.FakeCacheService{DataSources: []*datasources.DataSource{
{Uid: data1.DatasourceUID},
}}
@ -183,7 +183,7 @@ func TestRouteEvalQueries(t *testing.T) {
{Action: datasources.ActionQuery, Scope: datasources.ScopeProvider.GetResourceScopeUID(data2.DatasourceUID)},
})
ds := &fakes.FakeCacheService{DataSources: []*models2.DataSource{
ds := &fakes.FakeCacheService{DataSources: []*datasources.DataSource{
{Uid: data1.DatasourceUID},
{Uid: data2.DatasourceUID},
}}
@ -227,7 +227,7 @@ func TestRouteEvalQueries(t *testing.T) {
t.Run("should require user to be signed in", func(t *testing.T) {
data1 := models.GenerateAlertQuery()
ds := &fakes.FakeCacheService{DataSources: []*models2.DataSource{
ds := &fakes.FakeCacheService{DataSources: []*datasources.DataSource{
{Uid: data1.DatasourceUID},
}}

View File

@ -8,12 +8,14 @@ import (
"io"
"net/http"
"gopkg.in/yaml.v3"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/web"
"gopkg.in/yaml.v3"
)
var endpoints = map[string]map[string]string{
@ -74,10 +76,10 @@ func (am *LotexAM) withAMReq(
ds, err := am.DataProxy.DataSourceCache.GetDatasourceByUID(ctx.Req.Context(), datasourceUID, ctx.SignedInUser, ctx.SkipCache)
if err != nil {
if errors.Is(err, models.ErrDataSourceAccessDenied) {
if errors.Is(err, datasources.ErrDataSourceAccessDenied) {
return ErrResp(http.StatusForbidden, err, "Access denied to datasource")
}
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
return ErrResp(http.StatusNotFound, err, "Unable to find datasource")
}
return ErrResp(http.StatusInternalServerError, err, "Unable to load datasource meta data")

View File

@ -32,58 +32,58 @@ func TestLotexRuler_ValidateAndGetPrefix(t *testing.T) {
{
name: "with an error while trying to fetch the datasource",
namedParams: map[string]string{":DatasourceUID": "d164"},
datasourceCache: fakeCacheService{err: models.ErrDataSourceNotFound},
datasourceCache: fakeCacheService{err: datasources.ErrDataSourceNotFound},
err: errors.New("data source not found"),
},
{
name: "with an empty datasource URL",
namedParams: map[string]string{":DatasourceUID": "d164"},
datasourceCache: fakeCacheService{datasource: &models.DataSource{}},
datasourceCache: fakeCacheService{datasource: &datasources.DataSource{}},
err: errors.New("URL for this data source is empty"),
},
{
name: "with an unsupported datasource type",
namedParams: map[string]string{":DatasourceUID": "d164"},
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com"}},
datasourceCache: fakeCacheService{datasource: &datasources.DataSource{Url: "http://loki.com"}},
err: errors.New("unexpected datasource type. expecting loki or prometheus"),
},
{
name: "with a Loki datasource",
namedParams: map[string]string{":DatasourceUID": "d164"},
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com", Type: LokiDatasourceType}},
datasourceCache: fakeCacheService{datasource: &datasources.DataSource{Url: "http://loki.com", Type: LokiDatasourceType}},
expected: "/api/prom/rules",
},
{
name: "with a Prometheus datasource",
namedParams: map[string]string{":DatasourceUID": "d164"},
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
datasourceCache: fakeCacheService{datasource: &datasources.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
expected: "/rules",
},
{
name: "with a Prometheus datasource and subtype of Cortex",
namedParams: map[string]string{":DatasourceUID": "d164"},
urlParams: "?subtype=cortex",
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
datasourceCache: fakeCacheService{datasource: &datasources.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
expected: "/rules",
},
{
name: "with a Prometheus datasource and subtype of Mimir",
namedParams: map[string]string{":DatasourceUID": "d164"},
urlParams: "?subtype=mimir",
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
datasourceCache: fakeCacheService{datasource: &datasources.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
expected: "/config/v1/rules",
},
{
name: "with a Prometheus datasource and subtype of Prometheus",
namedParams: map[string]string{":DatasourceUID": "d164"},
urlParams: "?subtype=prometheus",
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
datasourceCache: fakeCacheService{datasource: &datasources.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
expected: "/rules",
},
{
name: "with a Prometheus datasource and no subtype",
namedParams: map[string]string{":DatasourceUID": "d164"},
datasourceCache: fakeCacheService{datasource: &models.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
datasourceCache: fakeCacheService{datasource: &datasources.DataSource{Url: "http://loki.com", Type: PrometheusDatasourceType}},
expected: "/rules",
},
}
@ -109,11 +109,11 @@ func TestLotexRuler_ValidateAndGetPrefix(t *testing.T) {
}
type fakeCacheService struct {
datasource *models.DataSource
datasource *datasources.DataSource
err error
}
func (f fakeCacheService) GetDatasource(_ context.Context, datasourceID int64, _ *models.SignedInUser, _ bool) (*models.DataSource, error) {
func (f fakeCacheService) GetDatasource(_ context.Context, datasourceID int64, _ *models.SignedInUser, _ bool) (*datasources.DataSource, error) {
if f.err != nil {
return nil, f.err
}
@ -121,7 +121,7 @@ func (f fakeCacheService) GetDatasource(_ context.Context, datasourceID int64, _
return f.datasource, nil
}
func (f fakeCacheService) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*models.DataSource, error) {
func (f fakeCacheService) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*datasources.DataSource, error) {
if f.err != nil {
return nil, f.err
}

View File

@ -161,7 +161,7 @@ func GetExprRequest(ctx AlertExecCtx, data []models.AlertQuery, now time.Time, d
},
}
datasources := make(map[string]*m.DataSource, len(data))
datasources := make(map[string]*datasources.DataSource, len(data))
for i := range data {
q := data[i]

View File

@ -4,11 +4,13 @@ import (
"context"
"errors"
"golang.org/x/oauth2"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/login/social"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/login"
"golang.org/x/oauth2"
)
var (
@ -22,7 +24,7 @@ type Service struct {
type OAuthTokenService interface {
GetCurrentOAuthToken(context.Context, *models.SignedInUser) *oauth2.Token
IsOAuthPassThruEnabled(*models.DataSource) bool
IsOAuthPassThruEnabled(*datasources.DataSource) bool
}
func ProvideService(socialService social.Service, authInfoService login.AuthInfoService) *Service {
@ -100,7 +102,7 @@ func (o *Service) GetCurrentOAuthToken(ctx context.Context, user *models.SignedI
}
// IsOAuthPassThruEnabled returns true if Forward OAuth Identity (oauthPassThru) is enabled for the provided data source.
func (o *Service) IsOAuthPassThruEnabled(ds *models.DataSource) bool {
func (o *Service) IsOAuthPassThruEnabled(ds *datasources.DataSource) bool {
return ds.JsonData != nil && ds.JsonData.Get("oauthPassThru").MustBool()
}

View File

@ -11,7 +11,7 @@ import (
"gopkg.in/yaml.v2"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/provisioning/utils"
)
@ -135,12 +135,12 @@ func (cr *configReader) validateAccessAndOrgID(ctx context.Context, ds *upsertDa
}
if ds.Access == "" {
ds.Access = models.DS_ACCESS_PROXY
ds.Access = datasources.DS_ACCESS_PROXY
}
if ds.Access != models.DS_ACCESS_DIRECT && ds.Access != models.DS_ACCESS_PROXY {
if ds.Access != datasources.DS_ACCESS_DIRECT && ds.Access != datasources.DS_ACCESS_PROXY {
cr.log.Warn("invalid access value, will use 'proxy' instead", "value", ds.Access)
ds.Access = models.DS_ACCESS_PROXY
ds.Access = datasources.DS_ACCESS_PROXY
}
return nil
}

View File

@ -5,11 +5,12 @@ import (
"os"
"testing"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/util"
"github.com/stretchr/testify/require"
)
var (
@ -39,14 +40,14 @@ func TestDatasourceAsConfig(t *testing.T) {
require.Equal(t, len(store.inserted), 1)
require.Equal(t, store.inserted[0].OrgId, int64(1))
require.Equal(t, store.inserted[0].Access, models.DsAccess("proxy"))
require.Equal(t, store.inserted[0].Access, datasources.DsAccess("proxy"))
require.Equal(t, store.inserted[0].Name, "My datasource name")
require.Equal(t, store.inserted[0].Uid, "P2AD1F727255C56BA")
})
t.Run("when some values missing should not change UID when updates", func(t *testing.T) {
store := &spyStore{
items: []*models.DataSource{{Name: "My datasource name", OrgId: 1, Id: 1, Uid: util.GenerateShortUID()}},
items: []*datasources.DataSource{{Name: "My datasource name", OrgId: 1, Id: 1, Uid: util.GenerateShortUID()}},
}
orgStore := &mockOrgStore{}
dc := newDatasourceProvisioner(logger, store, orgStore)
@ -76,7 +77,7 @@ func TestDatasourceAsConfig(t *testing.T) {
})
t.Run("One datasource in database with same name should update one datasource", func(t *testing.T) {
store := &spyStore{items: []*models.DataSource{{Name: "Graphite", OrgId: 1, Id: 1}}}
store := &spyStore{items: []*datasources.DataSource{{Name: "Graphite", OrgId: 1, Id: 1}}}
orgStore := &mockOrgStore{}
dc := newDatasourceProvisioner(logger, store, orgStore)
err := dc.applyChanges(context.Background(), twoDatasourcesConfig)
@ -127,7 +128,7 @@ func TestDatasourceAsConfig(t *testing.T) {
})
t.Run("Two configured datasource and purge others", func(t *testing.T) {
store := &spyStore{items: []*models.DataSource{{Name: "old-graphite", OrgId: 1, Id: 1}, {Name: "old-graphite2", OrgId: 1, Id: 2}}}
store := &spyStore{items: []*datasources.DataSource{{Name: "old-graphite", OrgId: 1, Id: 1}, {Name: "old-graphite2", OrgId: 1, Id: 2}}}
orgStore := &mockOrgStore{}
dc := newDatasourceProvisioner(logger, store, orgStore)
err := dc.applyChanges(context.Background(), twoDatasourcesConfigPurgeOthers)
@ -141,7 +142,7 @@ func TestDatasourceAsConfig(t *testing.T) {
})
t.Run("Two configured datasource and purge others = false", func(t *testing.T) {
store := &spyStore{items: []*models.DataSource{{Name: "Graphite", OrgId: 1, Id: 1}, {Name: "old-graphite2", OrgId: 1, Id: 2}}}
store := &spyStore{items: []*datasources.DataSource{{Name: "Graphite", OrgId: 1, Id: 1}, {Name: "old-graphite2", OrgId: 1, Id: 2}}}
orgStore := &mockOrgStore{}
dc := newDatasourceProvisioner(logger, store, orgStore)
err := dc.applyChanges(context.Background(), twoDatasourcesConfig)
@ -164,7 +165,7 @@ func TestDatasourceAsConfig(t *testing.T) {
reader := &configReader{log: logger, orgStore: &mockOrgStore{}}
configs, err := reader.readConfig(context.Background(), invalidAccess)
require.NoError(t, err)
require.Equal(t, configs[0].Datasources[0].Access, models.DS_ACCESS_PROXY)
require.Equal(t, configs[0].Datasources[0].Access, datasources.DS_ACCESS_PROXY)
})
t.Run("skip invalid directory", func(t *testing.T) {
@ -236,7 +237,7 @@ func validateDatasource(t *testing.T, dsCfg *configs) {
ds := dsCfg.Datasources[0]
require.Equal(t, ds.Name, "name")
require.Equal(t, ds.Type, "type")
require.Equal(t, ds.Access, models.DS_ACCESS_PROXY)
require.Equal(t, ds.Access, datasources.DS_ACCESS_PROXY)
require.Equal(t, ds.OrgID, int64(2))
require.Equal(t, ds.URL, "url")
require.Equal(t, ds.User, "user")
@ -273,33 +274,33 @@ func (m *mockOrgStore) GetOrgById(c context.Context, cmd *models.GetOrgByIdQuery
}
type spyStore struct {
inserted []*models.AddDataSourceCommand
deleted []*models.DeleteDataSourceCommand
updated []*models.UpdateDataSourceCommand
items []*models.DataSource
inserted []*datasources.AddDataSourceCommand
deleted []*datasources.DeleteDataSourceCommand
updated []*datasources.UpdateDataSourceCommand
items []*datasources.DataSource
}
func (s *spyStore) GetDataSource(ctx context.Context, query *models.GetDataSourceQuery) error {
func (s *spyStore) GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) error {
for _, v := range s.items {
if query.Name == v.Name && query.OrgId == v.OrgId {
query.Result = v
return nil
}
}
return models.ErrDataSourceNotFound
return datasources.ErrDataSourceNotFound
}
func (s *spyStore) DeleteDataSource(ctx context.Context, cmd *models.DeleteDataSourceCommand) error {
func (s *spyStore) DeleteDataSource(ctx context.Context, cmd *datasources.DeleteDataSourceCommand) error {
s.deleted = append(s.deleted, cmd)
return nil
}
func (s *spyStore) AddDataSource(ctx context.Context, cmd *models.AddDataSourceCommand) error {
func (s *spyStore) AddDataSource(ctx context.Context, cmd *datasources.AddDataSourceCommand) error {
s.inserted = append(s.inserted, cmd)
return nil
}
func (s *spyStore) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSourceCommand) error {
func (s *spyStore) UpdateDataSource(ctx context.Context, cmd *datasources.UpdateDataSourceCommand) error {
s.updated = append(s.updated, cmd)
return nil
}

View File

@ -5,16 +5,15 @@ import (
"errors"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/provisioning/utils"
"github.com/grafana/grafana/pkg/models"
)
type Store interface {
GetDataSource(ctx context.Context, query *models.GetDataSourceQuery) error
AddDataSource(ctx context.Context, cmd *models.AddDataSourceCommand) error
UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSourceCommand) error
DeleteDataSource(ctx context.Context, cmd *models.DeleteDataSourceCommand) error
GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) error
AddDataSource(ctx context.Context, cmd *datasources.AddDataSourceCommand) error
UpdateDataSource(ctx context.Context, cmd *datasources.UpdateDataSourceCommand) error
DeleteDataSource(ctx context.Context, cmd *datasources.DeleteDataSourceCommand) error
}
var (
@ -52,13 +51,13 @@ func (dc *DatasourceProvisioner) apply(ctx context.Context, cfg *configs) error
}
for _, ds := range cfg.Datasources {
cmd := &models.GetDataSourceQuery{OrgId: ds.OrgID, Name: ds.Name}
cmd := &datasources.GetDataSourceQuery{OrgId: ds.OrgID, Name: ds.Name}
err := dc.store.GetDataSource(ctx, cmd)
if err != nil && !errors.Is(err, models.ErrDataSourceNotFound) {
if err != nil && !errors.Is(err, datasources.ErrDataSourceNotFound) {
return err
}
if errors.Is(err, models.ErrDataSourceNotFound) {
if errors.Is(err, datasources.ErrDataSourceNotFound) {
insertCmd := createInsertCommand(ds)
dc.log.Info("inserting datasource from configuration ", "name", insertCmd.Name, "uid", insertCmd.Uid)
if err := dc.store.AddDataSource(ctx, insertCmd); err != nil {
@ -93,7 +92,7 @@ func (dc *DatasourceProvisioner) applyChanges(ctx context.Context, configPath st
func (dc *DatasourceProvisioner) deleteDatasources(ctx context.Context, dsToDelete []*deleteDatasourceConfig) error {
for _, ds := range dsToDelete {
cmd := &models.DeleteDataSourceCommand{OrgID: ds.OrgID, Name: ds.Name}
cmd := &datasources.DeleteDataSourceCommand{OrgID: ds.OrgID, Name: ds.Name}
if err := dc.store.DeleteDataSource(ctx, cmd); err != nil {
return err
}

View File

@ -7,7 +7,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/provisioning/values"
)
@ -189,7 +189,7 @@ func (cfg *configsV0) mapToDatasourceFromConfig(apiVersion int64) *configs {
return r
}
func createInsertCommand(ds *upsertDataSourceFromConfig) *models.AddDataSourceCommand {
func createInsertCommand(ds *upsertDataSourceFromConfig) *datasources.AddDataSourceCommand {
jsonData := simplejson.New()
if len(ds.JSONData) > 0 {
for k, v := range ds.JSONData {
@ -197,11 +197,11 @@ func createInsertCommand(ds *upsertDataSourceFromConfig) *models.AddDataSourceCo
}
}
cmd := &models.AddDataSourceCommand{
cmd := &datasources.AddDataSourceCommand{
OrgId: ds.OrgID,
Name: ds.Name,
Type: ds.Type,
Access: models.DsAccess(ds.Access),
Access: datasources.DsAccess(ds.Access),
Url: ds.URL,
User: ds.User,
Database: ds.Database,
@ -228,7 +228,7 @@ func safeUIDFromName(name string) string {
return strings.ToUpper(fmt.Sprintf("P%x", bs[:8]))
}
func createUpdateCommand(ds *upsertDataSourceFromConfig, id int64) *models.UpdateDataSourceCommand {
func createUpdateCommand(ds *upsertDataSourceFromConfig, id int64) *datasources.UpdateDataSourceCommand {
jsonData := simplejson.New()
if len(ds.JSONData) > 0 {
for k, v := range ds.JSONData {
@ -236,13 +236,13 @@ func createUpdateCommand(ds *upsertDataSourceFromConfig, id int64) *models.Updat
}
}
return &models.UpdateDataSourceCommand{
return &datasources.UpdateDataSourceCommand{
Id: id,
Uid: ds.UID,
OrgId: ds.OrgID,
Name: ds.Name,
Type: ds.Type,
Access: models.DsAccess(ds.Access),
Access: datasources.DsAccess(ds.Access),
Url: ds.URL,
User: ds.User,
Database: ds.Database,

View File

@ -146,7 +146,7 @@ func (s *Service) handleExpressions(ctx context.Context, user *models.SignedInUs
func (s *Service) handleQueryData(ctx context.Context, user *models.SignedInUser, parsedReq *parsedRequest) (*backend.QueryDataResponse, error) {
ds := parsedReq.parsedQueries[0].datasource
if err := s.pluginRequestValidator.Validate(ds.Url, nil); err != nil {
return nil, models.ErrDataSourceAccessDenied
return nil, datasources.ErrDataSourceAccessDenied
}
instanceSettings, err := adapters.ModelToInstanceSettings(ds, s.decryptSecureJsonDataFn(ctx))
@ -205,7 +205,7 @@ func (s *Service) handleQueryData(ctx context.Context, user *models.SignedInUser
}
type parsedQuery struct {
datasource *models.DataSource
datasource *datasources.DataSource
query backend.DataQuery
}
@ -247,7 +247,7 @@ func (s *Service) parseMetricRequest(ctx context.Context, user *models.SignedInU
}
// Parse the queries
datasourcesByUid := map[string]*models.DataSource{}
datasourcesByUid := map[string]*datasources.DataSource{}
for _, query := range reqDTO.Queries {
ds, err := s.getDataSourceFromQuery(ctx, user, skipCache, query, datasourcesByUid)
if err != nil {
@ -299,7 +299,7 @@ func (s *Service) parseMetricRequest(ctx context.Context, user *models.SignedInU
return req, nil
}
func (s *Service) getDataSourceFromQuery(ctx context.Context, user *models.SignedInUser, skipCache bool, query *simplejson.Json, history map[string]*models.DataSource) (*models.DataSource, error) {
func (s *Service) getDataSourceFromQuery(ctx context.Context, user *models.SignedInUser, skipCache bool, query *simplejson.Json, history map[string]*datasources.DataSource) (*datasources.DataSource, error) {
var err error
uid := query.Get("datasource").Get("uid").MustString()
@ -343,8 +343,8 @@ func (s *Service) getDataSourceFromQuery(ctx context.Context, user *models.Signe
return nil, NewErrBadQuery("missing data source ID/UID")
}
func (s *Service) decryptSecureJsonDataFn(ctx context.Context) func(ds *models.DataSource) map[string]string {
return func(ds *models.DataSource) map[string]string {
func (s *Service) decryptSecureJsonDataFn(ctx context.Context) func(ds *datasources.DataSource) map[string]string {
return func(ds *datasources.DataSource) map[string]string {
decryptedJsonData, err := s.dataSourceService.DecryptedValues(ctx, ds)
if err != nil {
s.log.Error("Failed to decrypt secure json data", "error", err)

View File

@ -6,22 +6,22 @@ import (
"net/http"
"testing"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/stretchr/testify/require"
"golang.org/x/oauth2"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
datasources "github.com/grafana/grafana/pkg/services/datasources/service"
"github.com/grafana/grafana/pkg/services/datasources"
dsSvc "github.com/grafana/grafana/pkg/services/datasources/service"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/query"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
"github.com/grafana/grafana/pkg/services/secrets/kvstore"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/stretchr/testify/require"
)
func TestQueryData(t *testing.T) {
@ -102,13 +102,13 @@ func TestQueryData(t *testing.T) {
func setup(t *testing.T) *testContext {
pc := &fakePluginClient{}
dc := &fakeDataSourceCache{ds: &models.DataSource{}}
dc := &fakeDataSourceCache{ds: &datasources.DataSource{}}
tc := &fakeOAuthTokenService{}
rv := &fakePluginRequestValidator{}
ss := kvstore.SetupTestService(t)
ssvc := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
ds := datasources.ProvideService(nil, ssvc, ss, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
ds := dsSvc.ProvideService(nil, ssvc, ss, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
return &testContext{
pluginContext: pc,
@ -156,19 +156,19 @@ func (ts *fakeOAuthTokenService) GetCurrentOAuthToken(context.Context, *models.S
return ts.token
}
func (ts *fakeOAuthTokenService) IsOAuthPassThruEnabled(*models.DataSource) bool {
func (ts *fakeOAuthTokenService) IsOAuthPassThruEnabled(*datasources.DataSource) bool {
return ts.passThruEnabled
}
type fakeDataSourceCache struct {
ds *models.DataSource
ds *datasources.DataSource
}
func (c *fakeDataSourceCache) GetDatasource(ctx context.Context, datasourceID int64, user *models.SignedInUser, skipCache bool) (*models.DataSource, error) {
func (c *fakeDataSourceCache) GetDatasource(ctx context.Context, datasourceID int64, user *models.SignedInUser, skipCache bool) (*datasources.DataSource, error) {
return c.ds, nil
}
func (c *fakeDataSourceCache) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*models.DataSource, error) {
func (c *fakeDataSourceCache) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*datasources.DataSource, error) {
return c.ds, nil
}

View File

@ -4,8 +4,8 @@ import (
"context"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
smp "github.com/grafana/grafana/pkg/plugins/backendplugin/secretsmanagerplugin"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/secrets"
)
@ -124,6 +124,6 @@ func parseKeys(keys []*smp.Key) []Key {
return newKeys
}
func wrapUserFriendlySecretError(ufe string) models.ErrDatasourceSecretsPluginUserFriendly {
return models.ErrDatasourceSecretsPluginUserFriendly{Err: ufe}
func wrapUserFriendlySecretError(ufe string) datasources.ErrDatasourceSecretsPluginUserFriendly {
return datasources.ErrDatasourceSecretsPluginUserFriendly{Err: ufe}
}

View File

@ -12,14 +12,14 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/events"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/models"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/util"
)
// GetDataSource adds a datasource to the query model by querying by org_id as well as
// either uid (preferred), id, or name and is added to the bus.
func (ss *SQLStore) GetDataSource(ctx context.Context, query *models.GetDataSourceQuery) error {
func (ss *SQLStore) GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) error {
metrics.MDBDataSourceQueryByID.Inc()
return ss.WithDbSession(ctx, func(sess *DBSession) error {
@ -27,19 +27,19 @@ func (ss *SQLStore) GetDataSource(ctx context.Context, query *models.GetDataSour
})
}
func (ss *SQLStore) getDataSource(ctx context.Context, query *models.GetDataSourceQuery, sess *DBSession) error {
func (ss *SQLStore) getDataSource(ctx context.Context, query *datasources.GetDataSourceQuery, sess *DBSession) error {
if query.OrgId == 0 || (query.Id == 0 && len(query.Name) == 0 && len(query.Uid) == 0) {
return models.ErrDataSourceIdentifierNotSet
return datasources.ErrDataSourceIdentifierNotSet
}
datasource := &models.DataSource{Name: query.Name, OrgId: query.OrgId, Id: query.Id, Uid: query.Uid}
datasource := &datasources.DataSource{Name: query.Name, OrgId: query.OrgId, Id: query.Id, Uid: query.Uid}
has, err := sess.Get(datasource)
if err != nil {
sqlog.Error("Failed getting data source", "err", err, "uid", query.Uid, "id", query.Id, "name", query.Name, "orgId", query.OrgId)
return err
} else if !has {
return models.ErrDataSourceNotFound
return datasources.ErrDataSourceNotFound
}
query.Result = datasource
@ -47,7 +47,7 @@ func (ss *SQLStore) getDataSource(ctx context.Context, query *models.GetDataSour
return nil
}
func (ss *SQLStore) GetDataSources(ctx context.Context, query *models.GetDataSourcesQuery) error {
func (ss *SQLStore) GetDataSources(ctx context.Context, query *datasources.GetDataSourcesQuery) error {
var sess *xorm.Session
return ss.WithDbSession(ctx, func(dbSess *DBSession) error {
if query.DataSourceLimit <= 0 {
@ -56,31 +56,31 @@ func (ss *SQLStore) GetDataSources(ctx context.Context, query *models.GetDataSou
sess = dbSess.Limit(query.DataSourceLimit, 0).Where("org_id=?", query.OrgId).Asc("name")
}
query.Result = make([]*models.DataSource, 0)
query.Result = make([]*datasources.DataSource, 0)
return sess.Find(&query.Result)
})
}
// GetDataSourcesByType returns all datasources for a given type or an error if the specified type is an empty string
func (ss *SQLStore) GetDataSourcesByType(ctx context.Context, query *models.GetDataSourcesByTypeQuery) error {
func (ss *SQLStore) GetDataSourcesByType(ctx context.Context, query *datasources.GetDataSourcesByTypeQuery) error {
if query.Type == "" {
return fmt.Errorf("datasource type cannot be empty")
}
query.Result = make([]*models.DataSource, 0)
query.Result = make([]*datasources.DataSource, 0)
return ss.WithDbSession(ctx, func(sess *DBSession) error {
return sess.Where("type=?", query.Type).Asc("id").Find(&query.Result)
})
}
// GetDefaultDataSource is used to get the default datasource of organization
func (ss *SQLStore) GetDefaultDataSource(ctx context.Context, query *models.GetDefaultDataSourceQuery) error {
datasource := models.DataSource{}
func (ss *SQLStore) GetDefaultDataSource(ctx context.Context, query *datasources.GetDefaultDataSourceQuery) error {
datasource := datasources.DataSource{}
return ss.WithDbSession(ctx, func(sess *DBSession) error {
exists, err := sess.Where("org_id=? AND is_default=?", query.OrgId, true).Get(&datasource)
if !exists {
return models.ErrDataSourceNotFound
return datasources.ErrDataSourceNotFound
}
query.Result = &datasource
@ -90,12 +90,12 @@ func (ss *SQLStore) GetDefaultDataSource(ctx context.Context, query *models.GetD
// DeleteDataSource removes a datasource by org_id as well as either uid (preferred), id, or name
// and is added to the bus. It also removes permissions related to the datasource.
func (ss *SQLStore) DeleteDataSource(ctx context.Context, cmd *models.DeleteDataSourceCommand) error {
func (ss *SQLStore) DeleteDataSource(ctx context.Context, cmd *datasources.DeleteDataSourceCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
dsQuery := &models.GetDataSourceQuery{Id: cmd.ID, Uid: cmd.UID, Name: cmd.Name, OrgId: cmd.OrgID}
dsQuery := &datasources.GetDataSourceQuery{Id: cmd.ID, Uid: cmd.UID, Name: cmd.Name, OrgId: cmd.OrgID}
errGettingDS := ss.getDataSource(ctx, dsQuery, sess)
if errGettingDS != nil && !errors.Is(errGettingDS, models.ErrDataSourceNotFound) {
if errGettingDS != nil && !errors.Is(errGettingDS, datasources.ErrDataSourceNotFound) {
return errGettingDS
}
@ -136,13 +136,13 @@ func (ss *SQLStore) DeleteDataSource(ctx context.Context, cmd *models.DeleteData
})
}
func (ss *SQLStore) AddDataSource(ctx context.Context, cmd *models.AddDataSourceCommand) error {
func (ss *SQLStore) AddDataSource(ctx context.Context, cmd *datasources.AddDataSourceCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
existing := models.DataSource{OrgId: cmd.OrgId, Name: cmd.Name}
existing := datasources.DataSource{OrgId: cmd.OrgId, Name: cmd.Name}
has, _ := sess.Get(&existing)
if has {
return models.ErrDataSourceNameExists
return datasources.ErrDataSourceNameExists
}
if cmd.JsonData == nil {
@ -157,7 +157,7 @@ func (ss *SQLStore) AddDataSource(ctx context.Context, cmd *models.AddDataSource
cmd.Uid = uid
}
ds := &models.DataSource{
ds := &datasources.DataSource{
OrgId: cmd.OrgId,
Name: cmd.Name,
Type: cmd.Type,
@ -180,7 +180,7 @@ func (ss *SQLStore) AddDataSource(ctx context.Context, cmd *models.AddDataSource
if _, err := sess.Insert(ds); err != nil {
if dialect.IsUniqueConstraintViolation(err) && strings.Contains(strings.ToLower(dialect.ErrorMessage(err)), "uid") {
return models.ErrDataSourceUidExists
return datasources.ErrDataSourceUidExists
}
return err
}
@ -208,7 +208,7 @@ func (ss *SQLStore) AddDataSource(ctx context.Context, cmd *models.AddDataSource
})
}
func updateIsDefaultFlag(ds *models.DataSource, sess *DBSession) error {
func updateIsDefaultFlag(ds *datasources.DataSource, sess *DBSession) error {
// Handle is default flag
if ds.IsDefault {
rawSQL := "UPDATE data_source SET is_default=? WHERE org_id=? AND id <> ?"
@ -219,13 +219,13 @@ func updateIsDefaultFlag(ds *models.DataSource, sess *DBSession) error {
return nil
}
func (ss *SQLStore) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSourceCommand) error {
func (ss *SQLStore) UpdateDataSource(ctx context.Context, cmd *datasources.UpdateDataSourceCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
if cmd.JsonData == nil {
cmd.JsonData = simplejson.New()
}
ds := &models.DataSource{
ds := &datasources.DataSource{
Id: cmd.Id,
OrgId: cmd.OrgId,
Name: cmd.Name,
@ -272,7 +272,7 @@ func (ss *SQLStore) UpdateDataSource(ctx context.Context, cmd *models.UpdateData
}
if affected == 0 {
return models.ErrDataSourceUpdatingOldVersion
return datasources.ErrDataSourceUpdatingOldVersion
}
err = updateIsDefaultFlag(ds, sess)
@ -293,7 +293,7 @@ func generateNewDatasourceUid(sess *DBSession, orgId int64) (string, error) {
for i := 0; i < 3; i++ {
uid := generateNewUid()
exists, err := sess.Where("org_id=? AND uid=?", orgId, uid).Get(&models.DataSource{})
exists, err := sess.Where("org_id=? AND uid=?", orgId, uid).Get(&datasources.DataSource{})
if err != nil {
return "", err
}
@ -303,7 +303,7 @@ func generateNewDatasourceUid(sess *DBSession, orgId int64) (string, error) {
}
}
return "", models.ErrDataSourceFailedGenerateUniqueUid
return "", datasources.ErrDataSourceFailedGenerateUniqueUid
}
var generateNewUid func() string = util.GenerateShortUID

View File

@ -8,39 +8,40 @@ import (
"testing"
"time"
"github.com/grafana/grafana/pkg/events"
"github.com/grafana/grafana/pkg/models"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/events"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
)
func TestIntegrationDataAccess(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
defaultAddDatasourceCommand := models.AddDataSourceCommand{
defaultAddDatasourceCommand := datasources.AddDataSourceCommand{
OrgId: 10,
Name: "nisse",
Type: models.DS_GRAPHITE,
Access: models.DS_ACCESS_DIRECT,
Type: datasources.DS_GRAPHITE,
Access: datasources.DS_ACCESS_DIRECT,
Url: "http://test",
}
defaultUpdateDatasourceCommand := models.UpdateDataSourceCommand{
defaultUpdateDatasourceCommand := datasources.UpdateDataSourceCommand{
OrgId: 10,
Name: "nisse_updated",
Type: models.DS_GRAPHITE,
Access: models.DS_ACCESS_DIRECT,
Type: datasources.DS_GRAPHITE,
Access: datasources.DS_ACCESS_DIRECT,
Url: "http://test",
}
initDatasource := func(sqlStore *SQLStore) *models.DataSource {
initDatasource := func(sqlStore *SQLStore) *datasources.DataSource {
cmd := defaultAddDatasourceCommand
err := sqlStore.AddDataSource(context.Background(), &cmd)
require.NoError(t, err)
query := models.GetDataSourcesQuery{OrgId: 10}
query := datasources.GetDataSourcesQuery{OrgId: 10}
err = sqlStore.GetDataSources(context.Background(), &query)
require.NoError(t, err)
require.Equal(t, 1, len(query.Result))
@ -52,18 +53,18 @@ func TestIntegrationDataAccess(t *testing.T) {
t.Run("Can add datasource", func(t *testing.T) {
sqlStore := InitTestDB(t)
err := sqlStore.AddDataSource(context.Background(), &models.AddDataSourceCommand{
err := sqlStore.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
OrgId: 10,
Name: "laban",
Type: models.DS_GRAPHITE,
Access: models.DS_ACCESS_DIRECT,
Type: datasources.DS_GRAPHITE,
Access: datasources.DS_ACCESS_DIRECT,
Url: "http://test",
Database: "site",
ReadOnly: true,
})
require.NoError(t, err)
query := models.GetDataSourcesQuery{OrgId: 10}
query := datasources.GetDataSourcesQuery{OrgId: 10}
err = sqlStore.GetDataSources(context.Background(), &query)
require.NoError(t, err)
@ -91,7 +92,7 @@ func TestIntegrationDataAccess(t *testing.T) {
require.NoError(t, err)
err = sqlStore.AddDataSource(context.Background(), &cmd2)
require.Error(t, err)
require.IsType(t, models.ErrDataSourceUidExists, err)
require.IsType(t, datasources.ErrDataSourceUidExists, err)
})
t.Run("fires an event when the datasource is added", func(t *testing.T) {
@ -110,7 +111,7 @@ func TestIntegrationDataAccess(t *testing.T) {
return assert.NotNil(t, created)
}, time.Second, time.Millisecond)
query := models.GetDataSourcesQuery{OrgId: 10}
query := datasources.GetDataSourcesQuery{OrgId: 10}
err = sqlStore.GetDataSources(context.Background(), &query)
require.NoError(t, err)
require.Equal(t, 1, len(query.Result))
@ -143,7 +144,7 @@ func TestIntegrationDataAccess(t *testing.T) {
err := sqlStore.UpdateDataSource(context.Background(), &cmd)
require.NoError(t, err)
query := models.GetDataSourceQuery{Id: ds.Id, OrgId: 10}
query := datasources.GetDataSourceQuery{Id: ds.Id, OrgId: 10}
err = sqlStore.GetDataSource(context.Background(), &query)
require.NoError(t, err)
require.Equal(t, ds.Uid, query.Result.Uid)
@ -153,12 +154,12 @@ func TestIntegrationDataAccess(t *testing.T) {
sqlStore := InitTestDB(t)
ds := initDatasource(sqlStore)
cmd := models.UpdateDataSourceCommand{
cmd := datasources.UpdateDataSourceCommand{
Id: ds.Id,
OrgId: 10,
Name: "nisse",
Type: models.DS_GRAPHITE,
Access: models.DS_ACCESS_PROXY,
Type: datasources.DS_GRAPHITE,
Access: datasources.DS_ACCESS_PROXY,
Url: "http://test",
Version: ds.Version,
}
@ -176,12 +177,12 @@ func TestIntegrationDataAccess(t *testing.T) {
sqlStore := InitTestDB(t)
ds := initDatasource(sqlStore)
cmd := &models.UpdateDataSourceCommand{
cmd := &datasources.UpdateDataSourceCommand{
Id: ds.Id,
OrgId: 10,
Name: "nisse",
Type: models.DS_GRAPHITE,
Access: models.DS_ACCESS_PROXY,
Type: datasources.DS_GRAPHITE,
Access: datasources.DS_ACCESS_PROXY,
Url: "http://test",
}
@ -193,12 +194,12 @@ func TestIntegrationDataAccess(t *testing.T) {
sqlStore := InitTestDB(t)
ds := initDatasource(sqlStore)
cmd := &models.UpdateDataSourceCommand{
cmd := &datasources.UpdateDataSourceCommand{
Id: ds.Id,
OrgId: 10,
Name: "nisse",
Type: models.DS_GRAPHITE,
Access: models.DS_ACCESS_PROXY,
Type: datasources.DS_GRAPHITE,
Access: datasources.DS_ACCESS_PROXY,
Url: "http://test",
Version: 90000,
}
@ -213,10 +214,10 @@ func TestIntegrationDataAccess(t *testing.T) {
sqlStore := InitTestDB(t)
ds := initDatasource(sqlStore)
err := sqlStore.DeleteDataSource(context.Background(), &models.DeleteDataSourceCommand{ID: ds.Id, OrgID: ds.OrgId})
err := sqlStore.DeleteDataSource(context.Background(), &datasources.DeleteDataSourceCommand{ID: ds.Id, OrgID: ds.OrgId})
require.NoError(t, err)
query := models.GetDataSourcesQuery{OrgId: 10}
query := datasources.GetDataSourcesQuery{OrgId: 10}
err = sqlStore.GetDataSources(context.Background(), &query)
require.NoError(t, err)
@ -228,10 +229,10 @@ func TestIntegrationDataAccess(t *testing.T) {
ds := initDatasource(sqlStore)
err := sqlStore.DeleteDataSource(context.Background(),
&models.DeleteDataSourceCommand{ID: ds.Id, OrgID: 123123})
&datasources.DeleteDataSourceCommand{ID: ds.Id, OrgID: 123123})
require.NoError(t, err)
query := models.GetDataSourcesQuery{OrgId: 10}
query := datasources.GetDataSourcesQuery{OrgId: 10}
err = sqlStore.GetDataSources(context.Background(), &query)
require.NoError(t, err)
@ -250,7 +251,7 @@ func TestIntegrationDataAccess(t *testing.T) {
})
err := sqlStore.DeleteDataSource(context.Background(),
&models.DeleteDataSourceCommand{ID: ds.Id, UID: "nisse-uid", Name: "nisse", OrgID: int64(123123)})
&datasources.DeleteDataSourceCommand{ID: ds.Id, UID: "nisse-uid", Name: "nisse", OrgID: int64(123123)})
require.NoError(t, err)
require.Eventually(t, func() bool {
@ -266,9 +267,9 @@ func TestIntegrationDataAccess(t *testing.T) {
t.Run("DeleteDataSourceByName", func(t *testing.T) {
sqlStore := InitTestDB(t)
ds := initDatasource(sqlStore)
query := models.GetDataSourcesQuery{OrgId: 10}
query := datasources.GetDataSourcesQuery{OrgId: 10}
err := sqlStore.DeleteDataSource(context.Background(), &models.DeleteDataSourceCommand{Name: ds.Name, OrgID: ds.OrgId})
err := sqlStore.DeleteDataSource(context.Background(), &datasources.DeleteDataSourceCommand{Name: ds.Name, OrgID: ds.OrgId})
require.NoError(t, err)
err = sqlStore.GetDataSources(context.Background(), &query)
@ -293,10 +294,10 @@ func TestIntegrationDataAccess(t *testing.T) {
return err
})
require.NoError(t, errAddPermissions)
query := models.GetDataSourcesQuery{OrgId: 10}
query := datasources.GetDataSourcesQuery{OrgId: 10}
errDeletingDS := sqlStore.DeleteDataSource(context.Background(),
&models.DeleteDataSourceCommand{Name: ds.Name, OrgID: ds.OrgId},
&datasources.DeleteDataSourceCommand{Name: ds.Name, OrgID: ds.OrgId},
)
require.NoError(t, errDeletingDS)
@ -318,18 +319,18 @@ func TestIntegrationDataAccess(t *testing.T) {
sqlStore := InitTestDB(t)
datasourceLimit := 6
for i := 0; i < datasourceLimit+1; i++ {
err := sqlStore.AddDataSource(context.Background(), &models.AddDataSourceCommand{
err := sqlStore.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
OrgId: 10,
Name: "laban" + strconv.Itoa(i),
Type: models.DS_GRAPHITE,
Access: models.DS_ACCESS_DIRECT,
Type: datasources.DS_GRAPHITE,
Access: datasources.DS_ACCESS_DIRECT,
Url: "http://test",
Database: "site",
ReadOnly: true,
})
require.NoError(t, err)
}
query := models.GetDataSourcesQuery{OrgId: 10, DataSourceLimit: datasourceLimit}
query := datasources.GetDataSourcesQuery{OrgId: 10, DataSourceLimit: datasourceLimit}
err := sqlStore.GetDataSources(context.Background(), &query)
@ -341,18 +342,18 @@ func TestIntegrationDataAccess(t *testing.T) {
sqlStore := InitTestDB(t)
numberOfDatasource := 5100
for i := 0; i < numberOfDatasource; i++ {
err := sqlStore.AddDataSource(context.Background(), &models.AddDataSourceCommand{
err := sqlStore.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
OrgId: 10,
Name: "laban" + strconv.Itoa(i),
Type: models.DS_GRAPHITE,
Access: models.DS_ACCESS_DIRECT,
Type: datasources.DS_GRAPHITE,
Access: datasources.DS_ACCESS_DIRECT,
Url: "http://test",
Database: "site",
ReadOnly: true,
})
require.NoError(t, err)
}
query := models.GetDataSourcesQuery{OrgId: 10}
query := datasources.GetDataSourcesQuery{OrgId: 10}
err := sqlStore.GetDataSources(context.Background(), &query)
@ -364,18 +365,18 @@ func TestIntegrationDataAccess(t *testing.T) {
sqlStore := InitTestDB(t)
numberOfDatasource := 5100
for i := 0; i < numberOfDatasource; i++ {
err := sqlStore.AddDataSource(context.Background(), &models.AddDataSourceCommand{
err := sqlStore.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
OrgId: 10,
Name: "laban" + strconv.Itoa(i),
Type: models.DS_GRAPHITE,
Access: models.DS_ACCESS_DIRECT,
Type: datasources.DS_GRAPHITE,
Access: datasources.DS_ACCESS_DIRECT,
Url: "http://test",
Database: "site",
ReadOnly: true,
})
require.NoError(t, err)
}
query := models.GetDataSourcesQuery{OrgId: 10, DataSourceLimit: -1}
query := datasources.GetDataSourcesQuery{OrgId: 10, DataSourceLimit: -1}
err := sqlStore.GetDataSources(context.Background(), &query)
@ -388,29 +389,29 @@ func TestIntegrationDataAccess(t *testing.T) {
t.Run("Only returns datasources of specified type", func(t *testing.T) {
sqlStore := InitTestDB(t)
err := sqlStore.AddDataSource(context.Background(), &models.AddDataSourceCommand{
err := sqlStore.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
OrgId: 10,
Name: "Elasticsearch",
Type: models.DS_ES,
Access: models.DS_ACCESS_DIRECT,
Type: datasources.DS_ES,
Access: datasources.DS_ACCESS_DIRECT,
Url: "http://test",
Database: "site",
ReadOnly: true,
})
require.NoError(t, err)
err = sqlStore.AddDataSource(context.Background(), &models.AddDataSourceCommand{
err = sqlStore.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
OrgId: 10,
Name: "Graphite",
Type: models.DS_GRAPHITE,
Access: models.DS_ACCESS_DIRECT,
Type: datasources.DS_GRAPHITE,
Access: datasources.DS_ACCESS_DIRECT,
Url: "http://test",
Database: "site",
ReadOnly: true,
})
require.NoError(t, err)
query := models.GetDataSourcesByTypeQuery{Type: models.DS_ES}
query := datasources.GetDataSourcesByTypeQuery{Type: datasources.DS_ES}
err = sqlStore.GetDataSourcesByType(context.Background(), &query)
@ -421,7 +422,7 @@ func TestIntegrationDataAccess(t *testing.T) {
t.Run("Returns an error if no type specified", func(t *testing.T) {
sqlStore := InitTestDB(t)
query := models.GetDataSourcesByTypeQuery{}
query := datasources.GetDataSourcesByTypeQuery{}
err := sqlStore.GetDataSourcesByType(context.Background(), &query)
@ -439,31 +440,31 @@ func TestIntegrationGetDefaultDataSource(t *testing.T) {
t.Run("should return error if there is no default datasource", func(t *testing.T) {
sqlStore := InitTestDB(t)
cmd := models.AddDataSourceCommand{
cmd := datasources.AddDataSourceCommand{
OrgId: 10,
Name: "nisse",
Type: models.DS_GRAPHITE,
Access: models.DS_ACCESS_DIRECT,
Type: datasources.DS_GRAPHITE,
Access: datasources.DS_ACCESS_DIRECT,
Url: "http://test",
}
err := sqlStore.AddDataSource(context.Background(), &cmd)
require.NoError(t, err)
query := models.GetDefaultDataSourceQuery{OrgId: 10}
query := datasources.GetDefaultDataSourceQuery{OrgId: 10}
err = sqlStore.GetDefaultDataSource(context.Background(), &query)
require.Error(t, err)
assert.True(t, errors.Is(err, models.ErrDataSourceNotFound))
assert.True(t, errors.Is(err, datasources.ErrDataSourceNotFound))
})
t.Run("should return default datasource if exists", func(t *testing.T) {
sqlStore := InitTestDB(t)
cmd := models.AddDataSourceCommand{
cmd := datasources.AddDataSourceCommand{
OrgId: 10,
Name: "default datasource",
Type: models.DS_GRAPHITE,
Access: models.DS_ACCESS_DIRECT,
Type: datasources.DS_GRAPHITE,
Access: datasources.DS_ACCESS_DIRECT,
Url: "http://test",
IsDefault: true,
}
@ -471,7 +472,7 @@ func TestIntegrationGetDefaultDataSource(t *testing.T) {
err := sqlStore.AddDataSource(context.Background(), &cmd)
require.NoError(t, err)
query := models.GetDefaultDataSourceQuery{OrgId: 10}
query := datasources.GetDefaultDataSourceQuery{OrgId: 10}
err = sqlStore.GetDefaultDataSource(context.Background(), &query)
require.NoError(t, err)
assert.Equal(t, "default datasource", query.Result.Name)
@ -479,9 +480,9 @@ func TestIntegrationGetDefaultDataSource(t *testing.T) {
t.Run("should not return default datasource of other organisation", func(t *testing.T) {
sqlStore := InitTestDB(t)
query := models.GetDefaultDataSourceQuery{OrgId: 1}
query := datasources.GetDefaultDataSourceQuery{OrgId: 1}
err := sqlStore.GetDefaultDataSource(context.Background(), &query)
require.Error(t, err)
assert.True(t, errors.Is(err, models.ErrDataSourceNotFound))
assert.True(t, errors.Is(err, datasources.ErrDataSourceNotFound))
})
}

View File

@ -14,6 +14,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore/migrations"
"github.com/grafana/grafana/pkg/services/sqlstore/migrations/ualert"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
@ -556,9 +557,9 @@ func createDashboard(t *testing.T, id int64, orgId int64, uid string) *models.Da
}
// createDatasource creates a ddatasource for inserting into the test database.
func createDatasource(t *testing.T, id int64, orgId int64, uid string) *models.DataSource {
func createDatasource(t *testing.T, id int64, orgId int64, uid string) *datasources.DataSource {
t.Helper()
return &models.DataSource{
return &datasources.DataSource{
Id: id,
OrgId: orgId,
Uid: uid,
@ -613,7 +614,7 @@ func setupLegacyAlertsTables(t *testing.T, x *xorm.Engine, legacyChannels []*mod
require.NoError(t, errDashboards)
// Setup data_sources.
dataSources := []models.DataSource{
dataSources := []datasources.DataSource{
*createDatasource(t, 1, 1, "ds1-1"),
*createDatasource(t, 2, 1, "ds2-1"),
*createDatasource(t, 3, 2, "ds3-2"),

View File

@ -4,6 +4,7 @@ import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
)
@ -18,7 +19,7 @@ type SQLStoreMock struct {
LatestUserId int64
ExpectedUser *models.User
ExpectedDatasource *models.DataSource
ExpectedDatasource *datasources.DataSource
ExpectedAlert *models.Alert
ExpectedPluginSetting *models.PluginSetting
ExpectedDashboards []*models.Dashboard
@ -28,11 +29,11 @@ type SQLStoreMock struct {
ExpectedTeamsByUser []*models.TeamDTO
ExpectedSearchOrgList []*models.OrgDTO
ExpectedSearchUsers models.SearchUserQueryResult
ExpectedDatasources []*models.DataSource
ExpectedDatasources []*datasources.DataSource
ExpectedOrg *models.Org
ExpectedSystemStats *models.SystemStats
ExpectedDataSourceStats []*models.DataSourceStats
ExpectedDataSources []*models.DataSource
ExpectedDataSources []*datasources.DataSource
ExpectedDataSourcesAccessStats []*models.DataSourceAccessStats
ExpectedNotifierUsageStats []*models.NotifierUsageStats
ExpectedPersistedDashboards models.HitList
@ -415,35 +416,35 @@ func (m *SQLStoreMock) GetDashboards(ctx context.Context, query *models.GetDashb
return m.ExpectedError
}
func (m SQLStoreMock) GetDataSource(ctx context.Context, query *models.GetDataSourceQuery) error {
func (m SQLStoreMock) GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) error {
query.Result = m.ExpectedDatasource
return m.ExpectedError
}
func (m *SQLStoreMock) GetDataSources(ctx context.Context, query *models.GetDataSourcesQuery) error {
func (m *SQLStoreMock) GetDataSources(ctx context.Context, query *datasources.GetDataSourcesQuery) error {
query.Result = m.ExpectedDatasources
return m.ExpectedError
}
func (m *SQLStoreMock) GetDataSourcesByType(ctx context.Context, query *models.GetDataSourcesByTypeQuery) error {
func (m *SQLStoreMock) GetDataSourcesByType(ctx context.Context, query *datasources.GetDataSourcesByTypeQuery) error {
return m.ExpectedError
}
func (m *SQLStoreMock) GetDefaultDataSource(ctx context.Context, query *models.GetDefaultDataSourceQuery) error {
func (m *SQLStoreMock) GetDefaultDataSource(ctx context.Context, query *datasources.GetDefaultDataSourceQuery) error {
query.Result = m.ExpectedDatasource
return m.ExpectedError
}
func (m *SQLStoreMock) DeleteDataSource(ctx context.Context, cmd *models.DeleteDataSourceCommand) error {
func (m *SQLStoreMock) DeleteDataSource(ctx context.Context, cmd *datasources.DeleteDataSourceCommand) error {
return m.ExpectedError
}
func (m *SQLStoreMock) AddDataSource(ctx context.Context, cmd *models.AddDataSourceCommand) error {
func (m *SQLStoreMock) AddDataSource(ctx context.Context, cmd *datasources.AddDataSourceCommand) error {
cmd.Result = m.ExpectedDatasource
return m.ExpectedError
}
func (m *SQLStoreMock) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSourceCommand) error {
func (m *SQLStoreMock) UpdateDataSource(ctx context.Context, cmd *datasources.UpdateDataSourceCommand) error {
cmd.Result = m.ExpectedDatasource
return m.ExpectedError
}

View File

@ -4,6 +4,7 @@ import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
)
@ -88,13 +89,13 @@ type Store interface {
GetOrgUsers(ctx context.Context, query *models.GetOrgUsersQuery) error
SearchOrgUsers(ctx context.Context, query *models.SearchOrgUsersQuery) error
RemoveOrgUser(ctx context.Context, cmd *models.RemoveOrgUserCommand) error
GetDataSource(ctx context.Context, query *models.GetDataSourceQuery) error
GetDataSources(ctx context.Context, query *models.GetDataSourcesQuery) error
GetDataSourcesByType(ctx context.Context, query *models.GetDataSourcesByTypeQuery) error
GetDefaultDataSource(ctx context.Context, query *models.GetDefaultDataSourceQuery) error
DeleteDataSource(ctx context.Context, cmd *models.DeleteDataSourceCommand) error
AddDataSource(ctx context.Context, cmd *models.AddDataSourceCommand) error
UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSourceCommand) error
GetDataSource(ctx context.Context, query *datasources.GetDataSourceQuery) error
GetDataSources(ctx context.Context, query *datasources.GetDataSourcesQuery) error
GetDataSourcesByType(ctx context.Context, query *datasources.GetDataSourcesByTypeQuery) error
GetDefaultDataSource(ctx context.Context, query *datasources.GetDefaultDataSourceQuery) error
DeleteDataSource(ctx context.Context, cmd *datasources.DeleteDataSourceCommand) error
AddDataSource(ctx context.Context, cmd *datasources.AddDataSourceCommand) error
UpdateDataSource(ctx context.Context, cmd *datasources.UpdateDataSourceCommand) error
Migrate(bool) error
Sync() error
Reset() error

View File

@ -7,8 +7,9 @@ import (
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/azlog"
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
"github.com/grafana/grafana/pkg/tsdb/legacydata/interval"
@ -114,7 +115,7 @@ func (m *kqlMacroEngine) evaluateMacro(name string, defaultTimeField string, arg
azlog.Warn("Unable to parse model from query", "JSON", m.query.JSON)
it = defaultInterval
} else {
it, err = interval.GetIntervalFrom(&models.DataSource{
it, err = interval.GetIntervalFrom(&datasources.DataSource{
JsonData: simplejson.NewFromAny(dsInfo.JSONData),
}, model, defaultInterval)
if err != nil {

View File

@ -9,8 +9,9 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/searchV2"
"github.com/grafana/grafana/pkg/services/store"
"github.com/grafana/grafana/pkg/setting"
@ -56,8 +57,8 @@ type Service struct {
store store.StorageService
}
func DataSourceModel(orgId int64) *models.DataSource {
return &models.DataSource{
func DataSourceModel(orgId int64) *datasources.DataSource {
return &datasources.DataSource{
Id: DatasourceID,
Uid: DatasourceUID,
Name: DatasourceName,

View File

@ -5,8 +5,9 @@ import (
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/models"
"github.com/stretchr/testify/assert"
"github.com/grafana/grafana/pkg/services/datasources"
)
func TestIntervalCalculator_Calculate(t *testing.T) {
@ -103,7 +104,7 @@ func TestFormatDuration(t *testing.T) {
func TestGetIntervalFrom(t *testing.T) {
testCases := []struct {
name string
dsInfo *models.DataSource
dsInfo *datasources.DataSource
queryInterval string
queryIntervalMs int64
defaultInterval time.Duration

View File

@ -7,26 +7,28 @@ import (
"fmt"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
)
// RequestHandler is a data request handler interface.
// Deprecated: use backend.QueryDataHandler instead.
type RequestHandler interface {
// HandleRequest handles a data request.
HandleRequest(context.Context, *models.DataSource, DataQuery) (DataResponse, error)
HandleRequest(context.Context, *datasources.DataSource, DataQuery) (DataResponse, error)
}
// DataSubQuery represents a data sub-query. New work should use the plugin SDK.
type DataSubQuery struct {
RefID string `json:"refId"`
Model *simplejson.Json `json:"model,omitempty"`
DataSource *models.DataSource `json:"datasource"`
MaxDataPoints int64 `json:"maxDataPoints"`
IntervalMS int64 `json:"intervalMs"`
QueryType string `json:"queryType"`
RefID string `json:"refId"`
Model *simplejson.Json `json:"model,omitempty"`
DataSource *datasources.DataSource `json:"datasource"`
MaxDataPoints int64 `json:"maxDataPoints"`
IntervalMS int64 `json:"intervalMs"`
QueryType string `json:"queryType"`
}
// DataQuery contains all information about a data query request. New work should use the plugin SDK.

View File

@ -7,8 +7,9 @@ import (
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend/gtime"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
)
@ -77,7 +78,7 @@ func (ic *intervalCalculator) CalculateSafeInterval(timerange legacydata.DataTim
return Interval{Text: FormatDuration(rounded), Value: rounded}
}
func GetIntervalFrom(dsInfo *models.DataSource, queryModel *simplejson.Json, defaultInterval time.Duration) (time.Duration, error) {
func GetIntervalFrom(dsInfo *datasources.DataSource, queryModel *simplejson.Json, defaultInterval time.Duration) (time.Duration, error) {
interval := queryModel.Get("interval").MustString("")
// intervalMs field appears in the v2 plugins API and should be preferred

View File

@ -4,11 +4,12 @@ import (
"testing"
"time"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
)
func TestIntervalCalculator_Calculate(t *testing.T) {
@ -98,7 +99,7 @@ func TestGetIntervalFrom(t *testing.T) {
require.NoError(t, err)
testCases := []struct {
name string
dsInfo *models.DataSource
dsInfo *datasources.DataSource
queryModel string
defaultInterval time.Duration
expected time.Duration
@ -108,7 +109,7 @@ func TestGetIntervalFrom(t *testing.T) {
{"2m", nil, `{"interval": "2m"}`, time.Second * 15, time.Minute * 2},
{"intervalMs", nil, `{"intervalMs": 45000}`, time.Second * 15, time.Second * 45},
{"intervalMs sub-seconds", nil, `{"intervalMs": 45200}`, time.Second * 15, time.Millisecond * 45200},
{"dsInfo timeInterval", &models.DataSource{
{"dsInfo timeInterval", &datasources.DataSource{
JsonData: dsJSON,
}, `{}`, time.Second * 15, time.Second * 60},
{"defaultInterval when interval empty", nil, `{"interval": ""}`, time.Second * 15, time.Second * 15},

View File

@ -7,8 +7,8 @@ import (
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/adapters"
"github.com/grafana/grafana/pkg/services/datasources"
@ -21,7 +21,7 @@ const (
headerValue = "httpHeaderValue"
)
var oAuthIsOAuthPassThruEnabledFunc = func(oAuthTokenService oauthtoken.OAuthTokenService, ds *models.DataSource) bool {
var oAuthIsOAuthPassThruEnabledFunc = func(oAuthTokenService oauthtoken.OAuthTokenService, ds *datasources.DataSource) bool {
return oAuthTokenService.IsOAuthPassThruEnabled(ds)
}
@ -41,7 +41,7 @@ func ProvideService(pluginsClient plugins.Client, oAuthTokenService oauthtoken.O
}
//nolint: staticcheck // legacydata.DataResponse deprecated
func (h *Service) HandleRequest(ctx context.Context, ds *models.DataSource, query legacydata.DataQuery) (legacydata.DataResponse, error) {
func (h *Service) HandleRequest(ctx context.Context, ds *datasources.DataSource, query legacydata.DataQuery) (legacydata.DataResponse, error) {
decryptedJsonData, err := h.dataSourcesService.DecryptedValues(ctx, ds)
if err != nil {
return legacydata.DataResponse{}, err
@ -91,7 +91,7 @@ func (h *Service) HandleRequest(ctx context.Context, ds *models.DataSource, quer
return tR, nil
}
func generateRequest(ctx context.Context, ds *models.DataSource, decryptedJsonData map[string]string, query legacydata.DataQuery) (*backend.QueryDataRequest, error) {
func generateRequest(ctx context.Context, ds *datasources.DataSource, decryptedJsonData map[string]string, query legacydata.DataQuery) (*backend.QueryDataRequest, error) {
jsonDataBytes, err := ds.JsonData.MarshalJSON()
if err != nil {
return nil, err

View File

@ -5,10 +5,12 @@ import (
"testing"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
"github.com/grafana/grafana/pkg/services/datasources"
datasourceservice "github.com/grafana/grafana/pkg/services/datasources/service"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/oauthtoken"
@ -17,7 +19,6 @@ import (
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
"github.com/stretchr/testify/require"
)
func TestHandleRequest(t *testing.T) {
@ -25,7 +26,7 @@ func TestHandleRequest(t *testing.T) {
t.Run("Should invoke plugin manager QueryData when handling request for query", func(t *testing.T) {
origOAuthIsOAuthPassThruEnabledFunc := oAuthIsOAuthPassThruEnabledFunc
oAuthIsOAuthPassThruEnabledFunc = func(oAuthTokenService oauthtoken.OAuthTokenService, ds *models.DataSource) bool {
oAuthIsOAuthPassThruEnabledFunc = func(oAuthTokenService oauthtoken.OAuthTokenService, ds *datasources.DataSource) bool {
return false
}
@ -45,12 +46,12 @@ func TestHandleRequest(t *testing.T) {
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), datasourcePermissions)
s := ProvideService(client, nil, dsService)
ds := &models.DataSource{Id: 12, Type: "unregisteredType", JsonData: simplejson.New()}
ds := &datasources.DataSource{Id: 12, Type: "unregisteredType", JsonData: simplejson.New()}
req := legacydata.DataQuery{
TimeRange: &legacydata.DataTimeRange{},
Queries: []legacydata.DataSubQuery{
{RefID: "A", DataSource: &models.DataSource{Id: 1, Type: "test"}, Model: simplejson.New()},
{RefID: "B", DataSource: &models.DataSource{Id: 1, Type: "test"}, Model: simplejson.New()},
{RefID: "A", DataSource: &datasources.DataSource{Id: 1, Type: "test"}, Model: simplejson.New()},
{RefID: "B", DataSource: &datasources.DataSource{Id: 1, Type: "test"}, Model: simplejson.New()},
},
}
res, err := s.HandleRequest(context.Background(), ds, req)
@ -73,12 +74,12 @@ func Test_generateRequest(t *testing.T) {
"something": "else",
}
ds := &models.DataSource{Id: 12, Type: "unregisteredType", JsonData: jsonData}
ds := &datasources.DataSource{Id: 12, Type: "unregisteredType", JsonData: jsonData}
query := legacydata.DataQuery{
TimeRange: &legacydata.DataTimeRange{},
Queries: []legacydata.DataSubQuery{
{RefID: "A", DataSource: &models.DataSource{Id: 1, Type: "test"}, Model: simplejson.New()},
{RefID: "B", DataSource: &models.DataSource{Id: 1, Type: "test"}, Model: simplejson.New()},
{RefID: "A", DataSource: &datasources.DataSource{Id: 1, Type: "test"}, Model: simplejson.New()},
{RefID: "B", DataSource: &datasources.DataSource{Id: 1, Type: "test"}, Model: simplejson.New()},
},
}