From 7db848f153f083b5efafc4c3bae177eeafb99f8b Mon Sep 17 00:00:00 2001
From: bugficks
Date: Tue, 15 Jan 2019 13:29:56 +0100
Subject: [PATCH 1/5] [Feature request] MySQL SSL CA in datasource connector
https://github.com/grafana/grafana/issues/8570
---
pkg/tsdb/mysql/mysql.go | 44 ++++++++++++
.../datasource/mysql/partials/config.html | 68 ++++++++++++++++++-
2 files changed, 110 insertions(+), 2 deletions(-)
diff --git a/pkg/tsdb/mysql/mysql.go b/pkg/tsdb/mysql/mysql.go
index 35b03e489a0..e713b87e265 100644
--- a/pkg/tsdb/mysql/mysql.go
+++ b/pkg/tsdb/mysql/mysql.go
@@ -6,6 +6,10 @@ import (
"reflect"
"strconv"
"strings"
+ "errors"
+
+ "crypto/x509"
+ "crypto/tls"
"github.com/go-sql-driver/mysql"
"github.com/go-xorm/core"
@@ -32,6 +36,46 @@ func newMysqlQueryEndpoint(datasource *models.DataSource) (tsdb.TsdbQueryEndpoin
datasource.Url,
datasource.Database,
)
+
+ var tlsSkipVerify, tlsAuth, tlsAuthWithCACert bool
+ if datasource.JsonData != nil {
+ tlsAuth = datasource.JsonData.Get("tlsAuth").MustBool(false)
+ tlsAuthWithCACert = datasource.JsonData.Get("tlsAuthWithCACert").MustBool(false)
+ tlsSkipVerify = datasource.JsonData.Get("tlsSkipVerify").MustBool(false)
+ }
+
+ if tlsAuth || tlsAuthWithCACert {
+
+ secureJsonData := datasource.SecureJsonData.Decrypt()
+ tlsConfig := tls.Config {
+ InsecureSkipVerify: tlsSkipVerify,
+ }
+
+ if tlsAuthWithCACert && len(secureJsonData["tlsCACert"]) > 0 {
+
+ caPool := x509.NewCertPool()
+ if ok := caPool.AppendCertsFromPEM([]byte(secureJsonData["tlsCACert"])); !ok {
+ return nil, errors.New("Failed to parse TLS CA PEM certificate")
+ }
+
+ tlsConfig.RootCAs = caPool
+ }
+
+ if tlsAuth {
+ certs, err := tls.X509KeyPair([]byte(secureJsonData["tlsClientCert"]), []byte(secureJsonData["tlsClientKey"]))
+ if err != nil {
+ return nil, err
+ }
+ clientCert := make([]tls.Certificate, 0, 1)
+ clientCert = append(clientCert, certs)
+
+ tlsConfig.Certificates = clientCert
+ }
+
+ mysql.RegisterTLSConfig(datasource.Name, &tlsConfig)
+ cnnstr += "&tls=" + datasource.Name
+ }
+
logger.Debug("getEngine", "connection", cnnstr)
config := tsdb.SqlQueryEndpointConfiguration{
diff --git a/public/app/plugins/datasource/mysql/partials/config.html b/public/app/plugins/datasource/mysql/partials/config.html
index a35633c626a..5f3ba5c1286 100644
--- a/public/app/plugins/datasource/mysql/partials/config.html
+++ b/public/app/plugins/datasource/mysql/partials/config.html
@@ -1,4 +1,3 @@
-
MySQL Connection
@@ -22,6 +21,72 @@
+
+
+
+
Connection limits
@@ -84,4 +149,3 @@
-
From f31fe495e977cd9fe1c585e25221a423ff9a7c71 Mon Sep 17 00:00:00 2001
From: bugficks
Date: Tue, 15 Jan 2019 13:54:25 +0100
Subject: [PATCH 2/5] fix go fmt
---
pkg/tsdb/mysql/mysql.go | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/pkg/tsdb/mysql/mysql.go b/pkg/tsdb/mysql/mysql.go
index e713b87e265..82e7cac27f0 100644
--- a/pkg/tsdb/mysql/mysql.go
+++ b/pkg/tsdb/mysql/mysql.go
@@ -2,14 +2,14 @@ package mysql
import (
"database/sql"
+ "errors"
"fmt"
"reflect"
"strconv"
"strings"
- "errors"
- "crypto/x509"
"crypto/tls"
+ "crypto/x509"
"github.com/go-sql-driver/mysql"
"github.com/go-xorm/core"
@@ -47,7 +47,7 @@ func newMysqlQueryEndpoint(datasource *models.DataSource) (tsdb.TsdbQueryEndpoin
if tlsAuth || tlsAuthWithCACert {
secureJsonData := datasource.SecureJsonData.Decrypt()
- tlsConfig := tls.Config {
+ tlsConfig := tls.Config{
InsecureSkipVerify: tlsSkipVerify,
}
From 7df5e3cebf06b39c0007bca76c9e86254fc7bc5a Mon Sep 17 00:00:00 2001
From: Marcus Efraimsson
Date: Mon, 28 Jan 2019 19:37:19 +0100
Subject: [PATCH 3/5] extract tls auth settings directive from datasource http
settings directive
---
public/app/features/all.ts | 1 +
.../datasources/partials/http_settings.html | 52 +-------------
.../partials/tls_auth_settings.html | 62 +++++++++++++++++
.../settings/TlsAuthSettingsCtrl.ts | 10 +++
.../datasource/mysql/partials/config.html | 68 +++----------------
5 files changed, 84 insertions(+), 109 deletions(-)
create mode 100644 public/app/features/datasources/partials/tls_auth_settings.html
create mode 100644 public/app/features/datasources/settings/TlsAuthSettingsCtrl.ts
diff --git a/public/app/features/all.ts b/public/app/features/all.ts
index 83146596ea0..d5e684e4a4e 100644
--- a/public/app/features/all.ts
+++ b/public/app/features/all.ts
@@ -12,3 +12,4 @@ import './manage-dashboards';
import './teams/CreateTeamCtrl';
import './profile/all';
import './datasources/settings/HttpSettingsCtrl';
+import './datasources/settings/TlsAuthSettingsCtrl';
diff --git a/public/app/features/datasources/partials/http_settings.html b/public/app/features/datasources/partials/http_settings.html
index 521e2d3cdc6..b6f2c4fc0dd 100644
--- a/public/app/features/datasources/partials/http_settings.html
+++ b/public/app/features/datasources/partials/http_settings.html
@@ -101,53 +101,5 @@
-
-
+
+
\ No newline at end of file
diff --git a/public/app/features/datasources/partials/tls_auth_settings.html b/public/app/features/datasources/partials/tls_auth_settings.html
new file mode 100644
index 00000000000..c852e8ec70c
--- /dev/null
+++ b/public/app/features/datasources/partials/tls_auth_settings.html
@@ -0,0 +1,62 @@
+
diff --git a/public/app/features/datasources/settings/TlsAuthSettingsCtrl.ts b/public/app/features/datasources/settings/TlsAuthSettingsCtrl.ts
new file mode 100644
index 00000000000..7c21fab404c
--- /dev/null
+++ b/public/app/features/datasources/settings/TlsAuthSettingsCtrl.ts
@@ -0,0 +1,10 @@
+import { coreModule } from 'app/core/core';
+
+coreModule.directive('datasourceTlsAuthSettings', () => {
+ return {
+ scope: {
+ current: '=',
+ },
+ templateUrl: 'public/app/features/datasources/partials/tls_auth_settings.html',
+ };
+});
diff --git a/public/app/plugins/datasource/mysql/partials/config.html b/public/app/plugins/datasource/mysql/partials/config.html
index 5f3ba5c1286..8221a06e1ee 100644
--- a/public/app/plugins/datasource/mysql/partials/config.html
+++ b/public/app/plugins/datasource/mysql/partials/config.html
@@ -24,70 +24,20 @@
-
-
+
+
Connection limits
From f157c19e16cdc970542867ec77eb5a61fe5f11ad Mon Sep 17 00:00:00 2001
From: Marcus Efraimsson
Date: Mon, 28 Jan 2019 19:38:56 +0100
Subject: [PATCH 4/5] extract parsing of datasource tls config to method
---
pkg/models/datasource_cache.go | 48 +++++++++++++++++++++-------------
pkg/tsdb/mysql/mysql.go | 43 ++++--------------------------
2 files changed, 35 insertions(+), 56 deletions(-)
diff --git a/pkg/models/datasource_cache.go b/pkg/models/datasource_cache.go
index 66ba66e4d39..1c895514ace 100644
--- a/pkg/models/datasource_cache.go
+++ b/pkg/models/datasource_cache.go
@@ -46,19 +46,16 @@ func (ds *DataSource) GetHttpTransport() (*http.Transport, error) {
return t.Transport, nil
}
- var tlsSkipVerify, tlsClientAuth, tlsAuthWithCACert bool
- if ds.JsonData != nil {
- tlsClientAuth = ds.JsonData.Get("tlsAuth").MustBool(false)
- tlsAuthWithCACert = ds.JsonData.Get("tlsAuthWithCACert").MustBool(false)
- tlsSkipVerify = ds.JsonData.Get("tlsSkipVerify").MustBool(false)
+ tlsConfig, err := ds.GetTLSConfig()
+ if err != nil {
+ return nil, err
}
+ tlsConfig.Renegotiation = tls.RenegotiateFreelyAsClient
+
transport := &http.Transport{
- TLSClientConfig: &tls.Config{
- InsecureSkipVerify: tlsSkipVerify,
- Renegotiation: tls.RenegotiateFreelyAsClient,
- },
- Proxy: http.ProxyFromEnvironment,
+ TLSClientConfig: tlsConfig,
+ Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
@@ -70,6 +67,26 @@ func (ds *DataSource) GetHttpTransport() (*http.Transport, error) {
IdleConnTimeout: 90 * time.Second,
}
+ ptc.cache[ds.Id] = cachedTransport{
+ Transport: transport,
+ updated: ds.Updated,
+ }
+
+ return transport, nil
+}
+
+func (ds *DataSource) GetTLSConfig() (*tls.Config, error) {
+ var tlsSkipVerify, tlsClientAuth, tlsAuthWithCACert bool
+ if ds.JsonData != nil {
+ tlsClientAuth = ds.JsonData.Get("tlsAuth").MustBool(false)
+ tlsAuthWithCACert = ds.JsonData.Get("tlsAuthWithCACert").MustBool(false)
+ tlsSkipVerify = ds.JsonData.Get("tlsSkipVerify").MustBool(false)
+ }
+
+ tlsConfig := &tls.Config{
+ InsecureSkipVerify: tlsSkipVerify,
+ }
+
if tlsClientAuth || tlsAuthWithCACert {
decrypted := ds.SecureJsonData.Decrypt()
if tlsAuthWithCACert && len(decrypted["tlsCACert"]) > 0 {
@@ -78,7 +95,7 @@ func (ds *DataSource) GetHttpTransport() (*http.Transport, error) {
if !ok {
return nil, errors.New("Failed to parse TLS CA PEM certificate")
}
- transport.TLSClientConfig.RootCAs = caPool
+ tlsConfig.RootCAs = caPool
}
if tlsClientAuth {
@@ -86,14 +103,9 @@ func (ds *DataSource) GetHttpTransport() (*http.Transport, error) {
if err != nil {
return nil, err
}
- transport.TLSClientConfig.Certificates = []tls.Certificate{cert}
+ tlsConfig.Certificates = []tls.Certificate{cert}
}
}
- ptc.cache[ds.Id] = cachedTransport{
- Transport: transport,
- updated: ds.Updated,
- }
-
- return transport, nil
+ return tlsConfig, nil
}
diff --git a/pkg/tsdb/mysql/mysql.go b/pkg/tsdb/mysql/mysql.go
index 82e7cac27f0..d451150f1de 100644
--- a/pkg/tsdb/mysql/mysql.go
+++ b/pkg/tsdb/mysql/mysql.go
@@ -2,15 +2,11 @@ package mysql
import (
"database/sql"
- "errors"
"fmt"
"reflect"
"strconv"
"strings"
- "crypto/tls"
- "crypto/x509"
-
"github.com/go-sql-driver/mysql"
"github.com/go-xorm/core"
"github.com/grafana/grafana/pkg/log"
@@ -37,42 +33,13 @@ func newMysqlQueryEndpoint(datasource *models.DataSource) (tsdb.TsdbQueryEndpoin
datasource.Database,
)
- var tlsSkipVerify, tlsAuth, tlsAuthWithCACert bool
- if datasource.JsonData != nil {
- tlsAuth = datasource.JsonData.Get("tlsAuth").MustBool(false)
- tlsAuthWithCACert = datasource.JsonData.Get("tlsAuthWithCACert").MustBool(false)
- tlsSkipVerify = datasource.JsonData.Get("tlsSkipVerify").MustBool(false)
+ tlsConfig, err := datasource.GetTLSConfig()
+ if err != nil {
+ return nil, err
}
- if tlsAuth || tlsAuthWithCACert {
-
- secureJsonData := datasource.SecureJsonData.Decrypt()
- tlsConfig := tls.Config{
- InsecureSkipVerify: tlsSkipVerify,
- }
-
- if tlsAuthWithCACert && len(secureJsonData["tlsCACert"]) > 0 {
-
- caPool := x509.NewCertPool()
- if ok := caPool.AppendCertsFromPEM([]byte(secureJsonData["tlsCACert"])); !ok {
- return nil, errors.New("Failed to parse TLS CA PEM certificate")
- }
-
- tlsConfig.RootCAs = caPool
- }
-
- if tlsAuth {
- certs, err := tls.X509KeyPair([]byte(secureJsonData["tlsClientCert"]), []byte(secureJsonData["tlsClientKey"]))
- if err != nil {
- return nil, err
- }
- clientCert := make([]tls.Certificate, 0, 1)
- clientCert = append(clientCert, certs)
-
- tlsConfig.Certificates = clientCert
- }
-
- mysql.RegisterTLSConfig(datasource.Name, &tlsConfig)
+ if tlsConfig.RootCAs != nil || len(tlsConfig.Certificates) > 0 {
+ mysql.RegisterTLSConfig(datasource.Name, tlsConfig)
cnnstr += "&tls=" + datasource.Name
}
From 1bc2a0af70304bee4b4a18beb5865c604cf2a942 Mon Sep 17 00:00:00 2001
From: Marcus Efraimsson
Date: Fri, 8 Feb 2019 18:08:07 +0100
Subject: [PATCH 5/5] use unique datasource id when registering mysql tls
config
---
pkg/tsdb/mysql/mysql.go | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/pkg/tsdb/mysql/mysql.go b/pkg/tsdb/mysql/mysql.go
index d451150f1de..d307e12166c 100644
--- a/pkg/tsdb/mysql/mysql.go
+++ b/pkg/tsdb/mysql/mysql.go
@@ -39,8 +39,9 @@ func newMysqlQueryEndpoint(datasource *models.DataSource) (tsdb.TsdbQueryEndpoin
}
if tlsConfig.RootCAs != nil || len(tlsConfig.Certificates) > 0 {
- mysql.RegisterTLSConfig(datasource.Name, tlsConfig)
- cnnstr += "&tls=" + datasource.Name
+ tlsConfigString := fmt.Sprintf("ds%d", datasource.Id)
+ mysql.RegisterTLSConfig(tlsConfigString, tlsConfig)
+ cnnstr += "&tls=" + tlsConfigString
}
logger.Debug("getEngine", "connection", cnnstr)