Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/gitpod-db/go/conn.go
2497 views
1
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package db
6
7
import (
8
"crypto/tls"
9
"crypto/x509"
10
"fmt"
11
"net"
12
"os"
13
"time"
14
15
"github.com/gitpod-io/gitpod/common-go/log"
16
driver_mysql "github.com/go-sql-driver/mysql"
17
"github.com/sirupsen/logrus"
18
"gorm.io/driver/mysql"
19
"gorm.io/gorm"
20
"gorm.io/gorm/logger"
21
"gorm.io/plugin/opentelemetry/tracing"
22
)
23
24
type ConnectionParams struct {
25
User string
26
Password string
27
Host string
28
Database string
29
CaCert string
30
}
31
32
func ConnectionParamsFromEnv() ConnectionParams {
33
return ConnectionParams{
34
User: os.Getenv("DB_USERNAME"),
35
Password: os.Getenv("DB_PASSWORD"),
36
Host: net.JoinHostPort(os.Getenv("DB_HOST"), os.Getenv("DB_PORT")),
37
Database: "gitpod",
38
CaCert: os.Getenv("DB_CA_CERT"),
39
}
40
}
41
42
func Connect(p ConnectionParams) (*gorm.DB, error) {
43
loc, err := time.LoadLocation("UTC")
44
if err != nil {
45
return nil, fmt.Errorf("Failed to load UTC location: %w", err)
46
}
47
cfg := driver_mysql.Config{
48
User: p.User,
49
Passwd: p.Password,
50
Net: "tcp",
51
Addr: p.Host,
52
DBName: p.Database,
53
Loc: loc,
54
AllowNativePasswords: true,
55
ParseTime: true,
56
}
57
58
if p.CaCert != "" {
59
rootCertPool := x509.NewCertPool()
60
if ok := rootCertPool.AppendCertsFromPEM([]byte(p.CaCert)); !ok {
61
return nil, fmt.Errorf("failed to append custom certificate for database connection")
62
}
63
64
tlsConfigName := "custom"
65
err = driver_mysql.RegisterTLSConfig(tlsConfigName, &tls.Config{
66
RootCAs: rootCertPool,
67
MinVersion: tls.VersionTLS12, // semgrep finding: set lower boundary to exclude insecure TLS1.0
68
})
69
if err != nil {
70
return nil, fmt.Errorf("failed to register custom DB CA cert: %w", err)
71
}
72
cfg.TLSConfig = tlsConfigName
73
}
74
75
// refer to https://github.com/go-sql-driver/mysql#dsn-data-source-name for details
76
conn, err := gorm.Open(mysql.Open(cfg.FormatDSN()), &gorm.Config{
77
Logger: logger.New(log.Log, logger.Config{
78
SlowThreshold: 200 * time.Millisecond,
79
Colorful: false,
80
IgnoreRecordNotFoundError: true,
81
LogLevel: (func() logger.LogLevel {
82
switch log.Log.Level {
83
case logrus.PanicLevel, logrus.FatalLevel, logrus.ErrorLevel:
84
return logger.Error
85
case logrus.WarnLevel:
86
return logger.Warn
87
default:
88
return logger.Info
89
}
90
})(),
91
}),
92
})
93
if err != nil {
94
return nil, fmt.Errorf("failed to open db connection: %w", err)
95
}
96
97
err = conn.Use(tracing.NewPlugin())
98
if err != nil {
99
return nil, fmt.Errorf("failed to setup db tracing: %w", err)
100
}
101
102
return conn, nil
103
}
104
105