mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Plugins: Add plugin settings DTO (#46283)
* add clearer service layer * re-order frontend settings for clarity * fix fetch fail * fix API response * fix mockstore * in -> where
This commit is contained in:
@@ -8,129 +8,20 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/licensing"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsettings"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/tsdb/grafanads"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
func (hs *HTTPServer) getFSDataSources(c *models.ReqContext, enabledPlugins EnabledPlugins) (map[string]plugins.DataSourceDTO, error) {
|
||||
orgDataSources := make([]*models.DataSource, 0)
|
||||
|
||||
if c.OrgId != 0 {
|
||||
query := models.GetDataSourcesQuery{OrgId: c.OrgId, DataSourceLimit: hs.Cfg.DataSourceLimit}
|
||||
err := hs.SQLStore.GetDataSources(c.Req.Context(), &query)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filtered, err := hs.filterDatasourcesByQueryPermission(c.Req.Context(), c.SignedInUser, query.Result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
orgDataSources = filtered
|
||||
func (hs *HTTPServer) GetFrontendSettings(c *models.ReqContext) {
|
||||
settings, err := hs.getFrontendSettingsMap(c)
|
||||
if err != nil {
|
||||
c.JsonApiErr(400, "Failed to get frontend settings", err)
|
||||
return
|
||||
}
|
||||
|
||||
dataSources := make(map[string]plugins.DataSourceDTO)
|
||||
|
||||
for _, ds := range orgDataSources {
|
||||
url := ds.Url
|
||||
|
||||
if ds.Access == models.DS_ACCESS_PROXY {
|
||||
url = "/api/datasources/proxy/" + strconv.FormatInt(ds.Id, 10)
|
||||
}
|
||||
|
||||
dsDTO := plugins.DataSourceDTO{
|
||||
ID: ds.Id,
|
||||
UID: ds.Uid,
|
||||
Type: ds.Type,
|
||||
Name: ds.Name,
|
||||
URL: url,
|
||||
IsDefault: ds.IsDefault,
|
||||
Access: string(ds.Access),
|
||||
}
|
||||
|
||||
plugin, exists := enabledPlugins.Get(plugins.DataSource, ds.Type)
|
||||
if !exists {
|
||||
c.Logger.Error("Could not find plugin definition for data source", "datasource_type", ds.Type)
|
||||
continue
|
||||
}
|
||||
dsDTO.Preload = plugin.Preload
|
||||
dsDTO.Module = plugin.Module
|
||||
dsDTO.PluginMeta = &plugins.PluginMetaDTO{
|
||||
JSONData: plugin.JSONData,
|
||||
Signature: plugin.Signature,
|
||||
Module: plugin.Module,
|
||||
BaseURL: plugin.BaseURL,
|
||||
}
|
||||
|
||||
if ds.JsonData == nil {
|
||||
dsDTO.JSONData = make(map[string]interface{})
|
||||
} else {
|
||||
dsDTO.JSONData = ds.JsonData.MustMap()
|
||||
}
|
||||
|
||||
if ds.Access == models.DS_ACCESS_DIRECT {
|
||||
if ds.BasicAuth {
|
||||
dsDTO.BasicAuth = util.GetBasicAuthHeader(
|
||||
ds.BasicAuthUser,
|
||||
hs.DataSourcesService.DecryptedBasicAuthPassword(ds),
|
||||
)
|
||||
}
|
||||
if ds.WithCredentials {
|
||||
dsDTO.WithCredentials = ds.WithCredentials
|
||||
}
|
||||
|
||||
if ds.Type == models.DS_INFLUXDB_08 {
|
||||
dsDTO.Username = ds.User
|
||||
dsDTO.Password = hs.DataSourcesService.DecryptedPassword(ds)
|
||||
dsDTO.URL = url + "/db/" + ds.Database
|
||||
}
|
||||
|
||||
if ds.Type == models.DS_INFLUXDB {
|
||||
dsDTO.Username = ds.User
|
||||
dsDTO.Password = hs.DataSourcesService.DecryptedPassword(ds)
|
||||
dsDTO.URL = url
|
||||
}
|
||||
}
|
||||
|
||||
if (ds.Type == models.DS_INFLUXDB) || (ds.Type == models.DS_ES) {
|
||||
dsDTO.Database = ds.Database
|
||||
}
|
||||
|
||||
if ds.Type == models.DS_PROMETHEUS {
|
||||
// add unproxied server URL for link to Prometheus web UI
|
||||
ds.JsonData.Set("directUrl", ds.Url)
|
||||
}
|
||||
|
||||
dataSources[ds.Name] = dsDTO
|
||||
}
|
||||
|
||||
// add data sources that are built in (meaning they are not added via data sources page, nor have any entry in
|
||||
// the datasource table)
|
||||
for _, ds := range hs.pluginStore.Plugins(c.Req.Context(), plugins.DataSource) {
|
||||
if ds.BuiltIn {
|
||||
dto := plugins.DataSourceDTO{
|
||||
Type: string(ds.Type),
|
||||
Name: ds.Name,
|
||||
JSONData: make(map[string]interface{}),
|
||||
PluginMeta: &plugins.PluginMetaDTO{
|
||||
JSONData: ds.JSONData,
|
||||
Signature: ds.Signature,
|
||||
Module: ds.Module,
|
||||
BaseURL: ds.BaseURL,
|
||||
},
|
||||
}
|
||||
if ds.Name == grafanads.DatasourceName {
|
||||
dto.ID = grafanads.DatasourceID
|
||||
dto.UID = grafanads.DatasourceUID
|
||||
}
|
||||
dataSources[ds.Name] = dto
|
||||
}
|
||||
}
|
||||
|
||||
return dataSources, nil
|
||||
c.JSON(200, settings)
|
||||
}
|
||||
|
||||
// getFrontendSettingsMap returns a json object with all the settings needed for front end initialisation.
|
||||
@@ -290,6 +181,126 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i
|
||||
return jsonObj, nil
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) getFSDataSources(c *models.ReqContext, enabledPlugins EnabledPlugins) (map[string]plugins.DataSourceDTO, error) {
|
||||
orgDataSources := make([]*models.DataSource, 0)
|
||||
|
||||
if c.OrgId != 0 {
|
||||
query := models.GetDataSourcesQuery{OrgId: c.OrgId, DataSourceLimit: hs.Cfg.DataSourceLimit}
|
||||
err := hs.SQLStore.GetDataSources(c.Req.Context(), &query)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filtered, err := hs.filterDatasourcesByQueryPermission(c.Req.Context(), c.SignedInUser, query.Result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
orgDataSources = filtered
|
||||
}
|
||||
|
||||
dataSources := make(map[string]plugins.DataSourceDTO)
|
||||
|
||||
for _, ds := range orgDataSources {
|
||||
url := ds.Url
|
||||
|
||||
if ds.Access == models.DS_ACCESS_PROXY {
|
||||
url = "/api/datasources/proxy/" + strconv.FormatInt(ds.Id, 10)
|
||||
}
|
||||
|
||||
dsDTO := plugins.DataSourceDTO{
|
||||
ID: ds.Id,
|
||||
UID: ds.Uid,
|
||||
Type: ds.Type,
|
||||
Name: ds.Name,
|
||||
URL: url,
|
||||
IsDefault: ds.IsDefault,
|
||||
Access: string(ds.Access),
|
||||
}
|
||||
|
||||
plugin, exists := enabledPlugins.Get(plugins.DataSource, ds.Type)
|
||||
if !exists {
|
||||
c.Logger.Error("Could not find plugin definition for data source", "datasource_type", ds.Type)
|
||||
continue
|
||||
}
|
||||
dsDTO.Preload = plugin.Preload
|
||||
dsDTO.Module = plugin.Module
|
||||
dsDTO.PluginMeta = &plugins.PluginMetaDTO{
|
||||
JSONData: plugin.JSONData,
|
||||
Signature: plugin.Signature,
|
||||
Module: plugin.Module,
|
||||
BaseURL: plugin.BaseURL,
|
||||
}
|
||||
|
||||
if ds.JsonData == nil {
|
||||
dsDTO.JSONData = make(map[string]interface{})
|
||||
} else {
|
||||
dsDTO.JSONData = ds.JsonData.MustMap()
|
||||
}
|
||||
|
||||
if ds.Access == models.DS_ACCESS_DIRECT {
|
||||
if ds.BasicAuth {
|
||||
dsDTO.BasicAuth = util.GetBasicAuthHeader(
|
||||
ds.BasicAuthUser,
|
||||
hs.DataSourcesService.DecryptedBasicAuthPassword(ds),
|
||||
)
|
||||
}
|
||||
if ds.WithCredentials {
|
||||
dsDTO.WithCredentials = ds.WithCredentials
|
||||
}
|
||||
|
||||
if ds.Type == models.DS_INFLUXDB_08 {
|
||||
dsDTO.Username = ds.User
|
||||
dsDTO.Password = hs.DataSourcesService.DecryptedPassword(ds)
|
||||
dsDTO.URL = url + "/db/" + ds.Database
|
||||
}
|
||||
|
||||
if ds.Type == models.DS_INFLUXDB {
|
||||
dsDTO.Username = ds.User
|
||||
dsDTO.Password = hs.DataSourcesService.DecryptedPassword(ds)
|
||||
dsDTO.URL = url
|
||||
}
|
||||
}
|
||||
|
||||
if (ds.Type == models.DS_INFLUXDB) || (ds.Type == models.DS_ES) {
|
||||
dsDTO.Database = ds.Database
|
||||
}
|
||||
|
||||
if ds.Type == models.DS_PROMETHEUS {
|
||||
// add unproxied server URL for link to Prometheus web UI
|
||||
ds.JsonData.Set("directUrl", ds.Url)
|
||||
}
|
||||
|
||||
dataSources[ds.Name] = dsDTO
|
||||
}
|
||||
|
||||
// add data sources that are built in (meaning they are not added via data sources page, nor have any entry in
|
||||
// the datasource table)
|
||||
for _, ds := range hs.pluginStore.Plugins(c.Req.Context(), plugins.DataSource) {
|
||||
if ds.BuiltIn {
|
||||
dto := plugins.DataSourceDTO{
|
||||
Type: string(ds.Type),
|
||||
Name: ds.Name,
|
||||
JSONData: make(map[string]interface{}),
|
||||
PluginMeta: &plugins.PluginMetaDTO{
|
||||
JSONData: ds.JSONData,
|
||||
Signature: ds.Signature,
|
||||
Module: ds.Module,
|
||||
BaseURL: ds.BaseURL,
|
||||
},
|
||||
}
|
||||
if ds.Name == grafanads.DatasourceName {
|
||||
dto.ID = grafanads.DatasourceID
|
||||
dto.UID = grafanads.DatasourceUID
|
||||
}
|
||||
dataSources[ds.Name] = dto
|
||||
}
|
||||
}
|
||||
|
||||
return dataSources, nil
|
||||
}
|
||||
|
||||
func getPanelSort(id string) int {
|
||||
sort := 100
|
||||
switch id {
|
||||
@@ -331,16 +342,6 @@ func getPanelSort(id string) int {
|
||||
return sort
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) GetFrontendSettings(c *models.ReqContext) {
|
||||
settings, err := hs.getFrontendSettingsMap(c)
|
||||
if err != nil {
|
||||
c.JsonApiErr(400, "Failed to get frontend settings", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, settings)
|
||||
}
|
||||
|
||||
// EnabledPlugins represents a mapping from plugin types (panel, data source, etc.) to plugin IDs to plugins
|
||||
// For example ["panel"] -> ["piechart"] -> {pie chart plugin DTO}
|
||||
type EnabledPlugins map[plugins.Type]map[string]plugins.PluginDTO
|
||||
@@ -389,15 +390,15 @@ func (hs *HTTPServer) enabledPlugins(ctx context.Context, orgID int64) (EnabledP
|
||||
return ep, nil
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) pluginSettings(ctx context.Context, orgID int64) (map[string]*models.PluginSettingInfoDTO, error) {
|
||||
pluginSettings := make(map[string]*models.PluginSettingInfoDTO)
|
||||
func (hs *HTTPServer) pluginSettings(ctx context.Context, orgID int64) (map[string]*pluginsettings.DTO, error) {
|
||||
pluginSettings := make(map[string]*pluginsettings.DTO)
|
||||
|
||||
// fill settings from database
|
||||
if pss, err := hs.PluginSettings.GetPluginSettings(ctx, orgID); err != nil {
|
||||
if pss, err := hs.PluginSettings.GetPluginSettings(ctx, &pluginsettings.GetArgs{OrgID: orgID}); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
for _, ps := range pss {
|
||||
pluginSettings[ps.PluginId] = ps
|
||||
pluginSettings[ps.PluginID] = ps
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,9 +410,9 @@ func (hs *HTTPServer) pluginSettings(ctx context.Context, orgID int64) (map[stri
|
||||
}
|
||||
|
||||
// add new setting which is enabled depending on if AutoEnabled: true
|
||||
pluginSetting := &models.PluginSettingInfoDTO{
|
||||
PluginId: plugin.ID,
|
||||
OrgId: orgID,
|
||||
pluginSetting := &pluginsettings.DTO{
|
||||
PluginID: plugin.ID,
|
||||
OrgID: orgID,
|
||||
Enabled: plugin.AutoEnabled,
|
||||
Pinned: plugin.AutoEnabled,
|
||||
}
|
||||
@@ -427,9 +428,9 @@ func (hs *HTTPServer) pluginSettings(ctx context.Context, orgID int64) (map[stri
|
||||
}
|
||||
|
||||
// add new setting which is enabled by default
|
||||
pluginSetting := &models.PluginSettingInfoDTO{
|
||||
PluginId: plugin.ID,
|
||||
OrgId: orgID,
|
||||
pluginSetting := &pluginsettings.DTO{
|
||||
PluginID: plugin.ID,
|
||||
OrgID: orgID,
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user