@@ -7,11 +7,17 @@ import (
7
7
"time"
8
8
9
9
"github.com/go-sql-driver/mysql"
10
+ "github.com/grafana/dskit/crypto/tls"
11
+
10
12
"xorm.io/xorm"
11
13
12
14
"github.com/grafana/grafana/pkg/storage/unified/sql/db"
13
15
)
14
16
17
+ // tlsConfigName is the name of the TLS config that we register with the MySQL
18
+ // driver.
19
+ const tlsConfigName = "db_engine_tls"
20
+
15
21
func getEngineMySQL (getter confGetter ) (* xorm.Engine , error ) {
16
22
config := mysql .NewConfig ()
17
23
config .User = getter .String ("user" )
@@ -25,29 +31,22 @@ func getEngineMySQL(getter confGetter) (*xorm.Engine, error) {
25
31
// See: https://dev.mysql.com/doc/refman/en/sql-mode.html
26
32
"@@SESSION.sql_mode" : "ANSI" ,
27
33
}
28
- sslMode := getter .String ("ssl_mode" )
29
- if sslMode == "true" || sslMode == "skip-verify" {
30
- config .Params ["tls" ] = "preferred"
31
- }
32
- tls := getter .String ("tls" )
33
- if tls != "" {
34
- config .Params ["tls" ] = tls
35
- }
36
34
config .Collation = "utf8mb4_unicode_ci"
37
35
config .Loc = time .UTC
38
36
config .AllowNativePasswords = true
39
37
config .ClientFoundRows = true
40
38
config .ParseTime = true
41
39
40
+ // Setup TLS for the database connection if configured.
41
+ if err := configureTLS (getter , config ); err != nil {
42
+ return nil , fmt .Errorf ("failed to configure TLS: %w" , err )
43
+ }
44
+
42
45
// allow executing multiple SQL statements in a single roundtrip, and also
43
46
// enable executing the CALL statement to run stored procedures that execute
44
47
// multiple SQL statements.
45
48
//config.MultiStatements = true
46
49
47
- // TODO: do we want to support these?
48
- // config.ServerPubKey = getter.String("server_pub_key")
49
- // config.TLSConfig = getter.String("tls_config_name")
50
-
51
50
if err := getter .Err (); err != nil {
52
51
return nil , fmt .Errorf ("config error: %w" , err )
53
52
}
@@ -56,7 +55,6 @@ func getEngineMySQL(getter confGetter) (*xorm.Engine, error) {
56
55
config .Net = "unix"
57
56
}
58
57
59
- // FIXME: get rid of xorm
60
58
engine , err := xorm .NewEngine (db .DriverMySQL , config .FormatDSN ())
61
59
if err != nil {
62
60
return nil , fmt .Errorf ("open database: %w" , err )
@@ -69,6 +67,47 @@ func getEngineMySQL(getter confGetter) (*xorm.Engine, error) {
69
67
return engine , nil
70
68
}
71
69
70
+ func configureTLS (getter confGetter , config * mysql.Config ) error {
71
+ sslMode := getter .String ("ssl_mode" )
72
+
73
+ if sslMode == "true" || sslMode == "skip-verify" {
74
+ tlsCfg := tls.ClientConfig {
75
+ CAPath : getter .String ("ca_cert_path" ),
76
+ CertPath : getter .String ("client_cert_path" ),
77
+ KeyPath : getter .String ("client_key_path" ),
78
+ ServerName : getter .String ("server_cert_name" ),
79
+ }
80
+
81
+ rawTLSCfg , err := tlsCfg .GetTLSConfig ()
82
+ if err != nil {
83
+ return fmt .Errorf ("failed to get TLS config for mysql: %w" , err )
84
+ }
85
+
86
+ if sslMode == "skip-verify" {
87
+ rawTLSCfg .InsecureSkipVerify = true
88
+ }
89
+
90
+ if err := mysql .RegisterTLSConfig (tlsConfigName , rawTLSCfg ); err != nil {
91
+ return fmt .Errorf ("failed to register TLS config for mysql: %w" , err )
92
+ }
93
+
94
+ config .TLSConfig = tlsConfigName
95
+ }
96
+
97
+ // If the TLS mode is set in the database config, we need to set it here.
98
+ if tls := getter .String ("tls" ); tls != "" {
99
+ // If the user has provided TLS certs, we don't want to use the tls=<value>, as
100
+ // they would override the TLS config that we set above. They both use the same
101
+ // parameter, so we need to check for that.
102
+ if sslMode == "true" {
103
+ return fmt .Errorf ("cannot provide tls certs and tls=<value> at the same time" )
104
+ }
105
+ config .Params ["tls" ] = tls
106
+ }
107
+
108
+ return nil
109
+ }
110
+
72
111
func getEnginePostgres (getter confGetter ) (* xorm.Engine , error ) {
73
112
dsnKV := map [string ]string {
74
113
"user" : getter .String ("user" ),
0 commit comments