Encryption: Refactor securejsondata.SecureJsonData to stop relying on global functions (#38865)

* Encryption: Add support to encrypt/decrypt sjd

* Add datasources.Service as a proxy to datasources db operations

* Encrypt ds.SecureJsonData before calling SQLStore

* Move ds cache code into ds service

* Fix tlsmanager tests

* Fix pluginproxy tests

* Remove some securejsondata.GetEncryptedJsonData usages

* Add pluginsettings.Service as a proxy for plugin settings db operations

* Add AlertNotificationService as a proxy for alert notification db operations

* Remove some securejsondata.GetEncryptedJsonData usages

* Remove more securejsondata.GetEncryptedJsonData usages

* Fix lint errors

* Minor fixes

* Remove encryption global functions usages from ngalert

* Fix lint errors

* Minor fixes

* Minor fixes

* Remove securejsondata.DecryptedValue usage

* Refactor the refactor

* Remove securejsondata.DecryptedValue usage

* Move securejsondata to migrations package

* Move securejsondata to migrations package

* Minor fix

* Fix integration test

* Fix integration tests

* Undo undesired changes

* Fix tests

* Add context.Context into encryption methods

* Fix tests

* Fix tests

* Fix tests

* Trigger CI

* Fix test

* Add names to params of encryption service interface

* Remove bus from CacheServiceImpl

* Add logging

* Add keys to logger

Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>

* Add missing key to logger

Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>

* Undo changes in markdown files

* Fix formatting

* Add context to secrets service

* Rename decryptSecureJsonData to decryptSecureJsonDataFn

* Name args in GetDecryptedValueFn

* Add template back to NewAlertmanagerNotifier

* Copy GetDecryptedValueFn to ngalert

* Add logging to pluginsettings

* Fix pluginsettings test

Co-authored-by: Tania B <yalyna.ts@gmail.com>
Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>
This commit is contained in:
Joan López de la Franca Beltran
2021-10-07 17:33:50 +03:00
committed by GitHub
co-authored by Emil Tullstedt Tania B
parent da813877fb
commit 722c414fef
141 changed files with 1968 additions and 1197 deletions
+19 -12
View File
@@ -16,7 +16,7 @@ import (
"strings"
"time"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/encryption"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/api/pluginproxy"
@@ -24,6 +24,8 @@ import (
"github.com/grafana/grafana/pkg/infra/httpclient"
"github.com/grafana/grafana/pkg/infra/log"
"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"
"golang.org/x/oauth2/google"
)
@@ -66,11 +68,13 @@ const (
perSeriesAlignerDefault string = "ALIGN_MEAN"
)
func ProvideService(cfg *setting.Cfg, pluginManager plugins.Manager, httpClientProvider httpclient.Provider) *Service {
func ProvideService(cfg *setting.Cfg, pluginManager plugins.Manager, httpClientProvider httpclient.Provider,
dsService *datasources.Service) *Service {
return &Service{
PluginManager: pluginManager,
HTTPClientProvider: httpClientProvider,
Cfg: cfg,
dsService: dsService,
}
}
@@ -78,29 +82,32 @@ type Service struct {
PluginManager plugins.Manager
HTTPClientProvider httpclient.Provider
Cfg *setting.Cfg
dsService *datasources.Service
}
// Executor executes queries for the CloudMonitoring datasource.
type Executor struct {
httpClient *http.Client
dsInfo *models.DataSource
pluginManager plugins.Manager
cfg *setting.Cfg
httpClient *http.Client
dsInfo *models.DataSource
pluginManager plugins.Manager
encryptionService encryption.Service
cfg *setting.Cfg
}
// NewExecutor returns an Executor.
//nolint: staticcheck // plugins.DataPlugin deprecated
func (s *Service) NewExecutor(dsInfo *models.DataSource) (plugins.DataPlugin, error) {
httpClient, err := dsInfo.GetHTTPClient(s.HTTPClientProvider)
httpClient, err := s.dsService.GetHTTPClient(dsInfo, s.HTTPClientProvider)
if err != nil {
return nil, err
}
return &Executor{
httpClient: httpClient,
dsInfo: dsInfo,
pluginManager: s.PluginManager,
cfg: s.Cfg,
httpClient: httpClient,
dsInfo: dsInfo,
pluginManager: s.PluginManager,
encryptionService: s.dsService.EncryptionService,
cfg: s.Cfg,
}, nil
}
@@ -548,7 +555,7 @@ func (e *Executor) createRequest(ctx context.Context, dsInfo *models.DataSource,
}
}
pluginproxy.ApplyRoute(ctx, req, proxyPass, cloudMonitoringRoute, dsInfo, e.cfg)
pluginproxy.ApplyRoute(ctx, req, proxyPass, cloudMonitoringRoute, dsInfo, e.cfg, e.encryptionService)
return req, nil
}
+19 -24
View File
@@ -9,17 +9,33 @@ import (
"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"
"github.com/grafana/grafana/pkg/services/oauthtoken"
)
// nolint:staticcheck // plugins.DataQuery deprecated
func dataPluginQueryAdapter(pluginID string, handler backend.QueryDataHandler, oAuthService oauthtoken.OAuthTokenService) plugins.DataPluginFunc {
return plugins.DataPluginFunc(func(ctx context.Context, ds *models.DataSource, query plugins.DataQuery) (plugins.DataResponse, error) {
instanceSettings, err := modelToInstanceSettings(ds)
func dataPluginQueryAdapter(pluginID string, handler backend.QueryDataHandler, oAuthService oauthtoken.OAuthTokenService,
dsService *datasources.Service) plugins.DataPluginFunc {
return func(ctx context.Context, ds *models.DataSource, query plugins.DataQuery) (plugins.DataResponse, error) {
jsonDataBytes, err := ds.JsonData.MarshalJSON()
if err != nil {
return plugins.DataResponse{}, err
}
instanceSettings := &backend.DataSourceInstanceSettings{
ID: ds.Id,
Name: ds.Name,
URL: ds.Url,
Database: ds.Database,
User: ds.User,
BasicAuthEnabled: ds.BasicAuth,
BasicAuthUser: ds.BasicAuthUser,
JSONData: jsonDataBytes,
DecryptedSecureJSONData: dsService.DecryptedValues(ds),
Updated: ds.Updated,
UID: ds.Uid,
}
if query.Headers == nil {
query.Headers = make(map[string]string)
}
@@ -90,26 +106,5 @@ func dataPluginQueryAdapter(pluginID string, handler backend.QueryDataHandler, o
}
return tR, nil
})
}
func modelToInstanceSettings(ds *models.DataSource) (*backend.DataSourceInstanceSettings, error) {
jsonDataBytes, err := ds.JsonData.MarshalJSON()
if err != nil {
return nil, err
}
return &backend.DataSourceInstanceSettings{
ID: ds.Id,
Name: ds.Name,
URL: ds.Url,
Database: ds.Database,
User: ds.User,
BasicAuthEnabled: ds.BasicAuth,
BasicAuthUser: ds.BasicAuthUser,
JSONData: jsonDataBytes,
DecryptedSecureJSONData: ds.DecryptedValues(),
Updated: ds.Updated,
UID: ds.Uid,
}, nil
}
+1 -2
View File
@@ -8,7 +8,6 @@ import (
"path/filepath"
"strings"
"github.com/grafana/grafana/pkg/components/securejsondata"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
@@ -86,7 +85,7 @@ func DataSourceModel(orgId int64) *models.DataSource {
Type: "grafana",
OrgId: orgId,
JsonData: simplejson.New(),
SecureJsonData: make(securejsondata.SecureJsonData),
SecureJsonData: make(map[string][]byte),
}
}
+3 -4
View File
@@ -10,19 +10,18 @@ import (
"strconv"
"strings"
mssql "github.com/denisenkom/go-mssqldb"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/data/sqlutil"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
mssql "github.com/denisenkom/go-mssqldb"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/tsdb/sqleng"
"github.com/grafana/grafana/pkg/util"
)
var logger = log.New("tsdb.mssql")
+2 -3
View File
@@ -12,18 +12,17 @@ import (
"time"
"github.com/VividCortex/mysqlerr"
"github.com/go-sql-driver/mysql"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/data/sqlutil"
"github.com/grafana/grafana/pkg/infra/httpclient"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
"github.com/grafana/grafana/pkg/setting"
"github.com/go-sql-driver/mysql"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/tsdb/sqleng"
)
+2 -3
View File
@@ -13,13 +13,12 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/data/sqlutil"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util/errutil"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/tsdb/sqleng"
"github.com/grafana/grafana/pkg/util/errutil"
)
var logger = log.New("tsdb.postgres")
+10 -5
View File
@@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/oauthtoken"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/cloudmonitoring"
@@ -19,9 +20,10 @@ func NewService(
pluginManager plugins.Manager,
backendPluginManager backendplugin.Manager,
oauthTokenService *oauthtoken.Service,
dataSourcesService *datasources.Service,
cloudMonitoringService *cloudmonitoring.Service,
) *Service {
s := newService(cfg, pluginManager, backendPluginManager, oauthTokenService)
s := newService(cfg, pluginManager, backendPluginManager, oauthTokenService, dataSourcesService)
// register backend data sources using legacy plugin
// contracts/non-SDK contracts
@@ -31,14 +33,15 @@ func NewService(
}
func newService(cfg *setting.Cfg, manager plugins.Manager, backendPluginManager backendplugin.Manager,
oauthTokenService oauthtoken.OAuthTokenService) *Service {
oauthTokenService oauthtoken.OAuthTokenService, dataSourcesService *datasources.Service) *Service {
return &Service{
Cfg: cfg,
PluginManager: manager,
BackendPluginManager: backendPluginManager,
// nolint:staticcheck // plugins.DataPlugin deprecated
registry: map[string]func(*models.DataSource) (plugins.DataPlugin, error){},
OAuthTokenService: oauthTokenService,
registry: map[string]func(*models.DataSource) (plugins.DataPlugin, error){},
OAuthTokenService: oauthTokenService,
DataSourcesService: dataSourcesService,
}
}
@@ -48,6 +51,7 @@ type Service struct {
PluginManager plugins.Manager
BackendPluginManager backendplugin.Manager
OAuthTokenService oauthtoken.OAuthTokenService
DataSourcesService *datasources.Service
//nolint: staticcheck // plugins.DataPlugin deprecated
registry map[string]func(*models.DataSource) (plugins.DataPlugin, error)
}
@@ -65,7 +69,8 @@ func (s *Service) HandleRequest(ctx context.Context, ds *models.DataSource, quer
return plugin.DataQuery(ctx, ds, query)
}
return dataPluginQueryAdapter(ds.Type, s.BackendPluginManager, s.OAuthTokenService).DataQuery(ctx, ds, query)
return dataPluginQueryAdapter(ds.Type, s.BackendPluginManager, s.OAuthTokenService, s.DataSourcesService).
DataQuery(ctx, ds, query)
}
// RegisterQueryHandler registers a query handler factory.
+5 -1
View File
@@ -5,11 +5,14 @@ import (
"testing"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/bus"
"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/backendplugin"
"github.com/grafana/grafana/pkg/plugins/manager"
"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"
"golang.org/x/oauth2"
@@ -142,8 +145,9 @@ func createService() (*Service, *fakeExecutor, *fakeBackendPM) {
manager := &manager.PluginManager{
BackendPluginManager: fakeBackendPM,
}
dsService := datasources.ProvideService(bus.New(), nil, ossencryption.ProvideService())
s := newService(setting.NewCfg(), manager, fakeBackendPM, &fakeOAuthTokenService{})
s := newService(setting.NewCfg(), manager, fakeBackendPM, &fakeOAuthTokenService{}, dsService)
e := &fakeExecutor{
//nolint: staticcheck // plugins.DataPlugin deprecated
results: make(map[string]plugins.DataQueryResult),