-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcloudsql.go
106 lines (91 loc) · 3.33 KB
/
cloudsql.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package helper
import (
"crypto/tls"
"crypto/x509"
"database/sql"
"errors"
"fmt"
"os"
"time"
"github.com/go-sql-driver/mysql"
)
func ConnectCloudSQL(database string) *sql.DB {
databaseSocket, err := connectTCPSocket(database)
if err != nil {
Logger(fmt.Sprint(" Something went wrong when trying to create a connection to the database: ", err), "critical")
return nil
}
if databaseSocket == nil {
Logger(" Something went wrong with the values that were passed to the database connection.", "critical")
return nil
}
return databaseSocket
}
func connectTCPSocket(database string) (*sql.DB, error) {
var (
databaseUser = MustGetenv("DATABASE_USER")
databasePassword = MustGetenv("DATABASE_PASS")
databaseIP = MustGetenv("DATABASE_IP")
databaseName = MustGetenv("DATABASE_NAME")
databaseProject = MustGetenv("PROJECT_ID")
databasePort = "3306"
)
databaseURI := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?parseTime=true", databaseUser, databasePassword, databaseIP, databasePort, database)
if databaseRootCert, ok := os.LookupEnv("DATABASE_ROOT_CERT"); ok {
var (
databaseCert = MustGetenv("DATABASE_CERT")
databaseCertKey = MustGetenv("DATABASE_CERT_KEY")
)
certificatePool := x509.NewCertPool()
rootCertificate, err := os.ReadFile(databaseRootCert)
if err != nil {
Logger(fmt.Sprint(" Something went wrong when trying to read the root certificate: ", err), "critical")
return nil, err
}
if ok := certificatePool.AppendCertsFromPEM(rootCertificate); !ok {
Logger(fmt.Sprint(" Something went wrong when trying to append the root certificate to the pool: ", err), "critical")
return nil, errors.New("unable to append root cert to pool")
}
clientCertificate, err := tls.LoadX509KeyPair(databaseCert, databaseCertKey)
if err != nil {
Logger(fmt.Sprint(" Something went wrong when trying to load the client certificate: ", err), "critical")
return nil, err
}
// Issue with the connection and use the function in here:
// /~https://github.com/golang/go/issues/40748
mysql.RegisterTLSConfig("cloudsql", &tls.Config{
RootCAs: certificatePool,
Certificates: []tls.Certificate{clientCertificate},
InsecureSkipVerify: true,
ServerName: databaseProject + ":" + databaseName,
VerifyConnection: func(cs tls.ConnectionState) error {
commonName := cs.PeerCertificates[0].Subject.CommonName
if commonName != cs.ServerName {
Logger(fmt.Sprintf(" Something went wrong when trying to verify the connection: invalid certificate name %q, expected %q", commonName, cs.ServerName), "critical")
return fmt.Errorf(" Something went wrong when trying to verify the connection: invalid certificate name")
}
opts := x509.VerifyOptions{
Roots: certificatePool,
Intermediates: x509.NewCertPool(),
}
for _, cert := range cs.PeerCertificates[1:] {
opts.Intermediates.AddCert(cert)
}
_, err := cs.PeerCertificates[0].Verify(opts)
return err
},
})
databaseURI += "&tls=cloudsql"
}
databaseConnection, err := sql.Open("mysql", databaseURI)
if err != nil {
return nil, fmt.Errorf("sql.Open: %w", err)
}
configureConnectionPool(databaseConnection)
return databaseConnection, nil
}
func configureConnectionPool(db *sql.DB) {
db.SetMaxIdleConns(5)
db.SetMaxOpenConns(7)
db.SetConnMaxLifetime(1800 * time.Second)
}