Datasource: Shared HTTP client provider for core backend data sources and any data source using the data source proxy (#33439)

Uses new httpclient package from grafana-plugin-sdk-go introduced 
via grafana/grafana-plugin-sdk-go#328. 
Replaces the GetHTTPClient, GetTransport, GetTLSConfig methods defined 
on DataSource model.
Longer-term the goal is to migrate core HTTP backend data sources to use the 
SDK contracts and using httpclient.Provider for creating HTTP clients and such.

Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
Marcus Efraimsson
2021-05-19 23:53:41 +02:00
committed by GitHub
parent 7a83d1f9ff
commit 348e76fc8e
46 changed files with 1082 additions and 467 deletions

View File

@ -12,6 +12,7 @@ import (
"github.com/VividCortex/mysqlerr"
"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/setting"
"github.com/go-sql-driver/mysql"
@ -32,52 +33,55 @@ func characterEscape(s string, escapeChar string) string {
}
//nolint: staticcheck // plugins.DataPlugin deprecated
func NewExecutor(datasource *models.DataSource) (plugins.DataPlugin, error) {
logger := log.New("tsdb.mysql")
func New(httpClientProvider httpclient.Provider) func(datasource *models.DataSource) (plugins.DataPlugin, error) {
//nolint: staticcheck // plugins.DataPlugin deprecated
return func(datasource *models.DataSource) (plugins.DataPlugin, error) {
logger := log.New("tsdb.mysql")
protocol := "tcp"
if strings.HasPrefix(datasource.Url, "/") {
protocol = "unix"
}
protocol := "tcp"
if strings.HasPrefix(datasource.Url, "/") {
protocol = "unix"
}
cnnstr := fmt.Sprintf("%s:%s@%s(%s)/%s?collation=utf8mb4_unicode_ci&parseTime=true&loc=UTC&allowNativePasswords=true",
characterEscape(datasource.User, ":"),
datasource.DecryptedPassword(),
protocol,
characterEscape(datasource.Url, ")"),
characterEscape(datasource.Database, "?"),
)
cnnstr := fmt.Sprintf("%s:%s@%s(%s)/%s?collation=utf8mb4_unicode_ci&parseTime=true&loc=UTC&allowNativePasswords=true",
characterEscape(datasource.User, ":"),
datasource.DecryptedPassword(),
protocol,
characterEscape(datasource.Url, ")"),
characterEscape(datasource.Database, "?"),
)
tlsConfig, err := datasource.GetTLSConfig()
if err != nil {
return nil, err
}
if tlsConfig.RootCAs != nil || len(tlsConfig.Certificates) > 0 {
tlsConfigString := fmt.Sprintf("ds%d", datasource.Id)
if err := mysql.RegisterTLSConfig(tlsConfigString, tlsConfig); err != nil {
tlsConfig, err := datasource.GetTLSConfig(httpClientProvider)
if err != nil {
return nil, err
}
cnnstr += "&tls=" + tlsConfigString
}
if setting.Env == setting.Dev {
logger.Debug("getEngine", "connection", cnnstr)
}
if tlsConfig.RootCAs != nil || len(tlsConfig.Certificates) > 0 {
tlsConfigString := fmt.Sprintf("ds%d", datasource.Id)
if err := mysql.RegisterTLSConfig(tlsConfigString, tlsConfig); err != nil {
return nil, err
}
cnnstr += "&tls=" + tlsConfigString
}
config := sqleng.DataPluginConfiguration{
DriverName: "mysql",
ConnectionString: cnnstr,
Datasource: datasource,
TimeColumnNames: []string{"time", "time_sec"},
MetricColumnTypes: []string{"CHAR", "VARCHAR", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT"},
}
if setting.Env == setting.Dev {
logger.Debug("getEngine", "connection", cnnstr)
}
rowTransformer := mysqlQueryResultTransformer{
log: logger,
}
config := sqleng.DataPluginConfiguration{
DriverName: "mysql",
ConnectionString: cnnstr,
Datasource: datasource,
TimeColumnNames: []string{"time", "time_sec"},
MetricColumnTypes: []string{"CHAR", "VARCHAR", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT"},
}
return sqleng.NewDataPlugin(config, &rowTransformer, newMysqlMacroEngine(logger), logger)
rowTransformer := mysqlQueryResultTransformer{
log: logger,
}
return sqleng.NewDataPlugin(config, &rowTransformer, newMysqlMacroEngine(logger), logger)
}
}
type mysqlQueryResultTransformer struct {