-
Notifications
You must be signed in to change notification settings - Fork 92
/
mssql.go
103 lines (88 loc) · 2.67 KB
/
mssql.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
package collect
import (
"bytes"
"context"
"database/sql"
"encoding/json"
"fmt"
"net/url"
"regexp"
_ "github.com/microsoft/go-mssqldb"
"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
)
type CollectMssql struct {
Collector *troubleshootv1beta2.Database
BundlePath string
Namespace string
ClientConfig *rest.Config
Client kubernetes.Interface
Context context.Context
RBACErrors
}
func (c *CollectMssql) Title() string {
return getCollectorName(c)
}
func (c *CollectMssql) IsExcluded() (bool, error) {
return isExcluded(c.Collector.Exclude)
}
func (c *CollectMssql) Collect(progressChan chan<- interface{}) (CollectorResult, error) {
databaseConnection := DatabaseConnection{}
connUrl, err := url.Parse(c.Collector.URI)
// Parsing the uri should not lead to the collector failing
// sql.Open will fail if the uri is invalid.
if err == nil {
klog.V(2).Infof("Connect to %q MSSQL Database", connUrl.Host)
} else {
klog.V(2).Info("Connect to MSSQL Database")
}
db, err := sql.Open("mssql", c.Collector.URI)
if err != nil {
klog.V(2).Infof("Failed to connect to %q MSSQL Database: %v", connUrl.Host, err)
databaseConnection.Error = err.Error()
} else {
defer db.Close()
query := `select @@VERSION as version`
row := db.QueryRow(query)
version := ""
if err := row.Scan(&version); err != nil {
klog.V(2).Infof("Failed to query version string from database: %s", err)
databaseConnection.Error = err.Error()
} else {
databaseConnection.IsConnected = true
mssqlVersion, err := parseMsSqlVersion(version)
if err != nil {
databaseConnection.Version = "Unknown"
databaseConnection.Error = err.Error()
} else {
databaseConnection.Version = mssqlVersion
}
klog.V(2).Infof("Successfully queried version string from database: %s", version)
}
}
b, err := json.Marshal(databaseConnection)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal database connection")
}
collectorName := c.Collector.CollectorName
if collectorName == "" {
collectorName = "mssql"
}
output := NewResult()
output.SaveResult(c.BundlePath, fmt.Sprintf("mssql/%s.json", collectorName), bytes.NewBuffer(b))
return output, nil
}
func parseMsSqlVersion(mssqlVersion string) (string, error) {
re, err := regexp.Compile(`.*SQL.*-\s+([0-9.]+)`)
if err != nil {
return "", errors.Wrap(err, "failed to compile regex")
}
matches := re.FindStringSubmatch(mssqlVersion)
if len(matches) < 2 {
return "", errors.Errorf("mssql version did not match regex: %q", mssqlVersion)
}
return matches[1], nil
}