Skip to content

Commit 88c004f

Browse files
committed
mysql check implementation
1 parent 7e1afb7 commit 88c004f

File tree

1 file changed

+238
-0
lines changed

1 file changed

+238
-0
lines changed

main.go

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,246 @@ package check_template
22

33
import (
44
"context"
5+
"database/sql"
6+
"fmt"
7+
"regexp"
8+
"strings"
59
)
610

11+
type optionsStruct struct {
12+
// Database is the name of the database to connect to
13+
Database string `compscore:"database"`
14+
15+
// Table is the name of the table to check
16+
Table string `compscore:"table"`
17+
18+
// Field is the name of the field to check
19+
Field string `compscore:"field"`
20+
21+
// Check if a database connection can be made
22+
Connect bool `compscore:"connect"`
23+
24+
// Check if a table exists
25+
TableExists bool `compscore:"table_exists"`
26+
27+
// Check if any row exists in table
28+
RowExists bool `compscore:"row_exists"`
29+
30+
// Check if a field of row matches regex in
31+
RegexMatch bool `compscore:"regex_match"`
32+
33+
// Check if a field of row matches substring
34+
SubstringMatch bool `compscore:"substring_match"`
35+
36+
// Check if a field of row matches exact string
37+
Match bool `compscore:"match"`
38+
}
39+
40+
func (o *optionsStruct) Unmarshal(options map[string]interface{}) {
41+
databaseInterface, ok := options["database"]
42+
if ok {
43+
database, ok := databaseInterface.(string)
44+
if ok {
45+
o.Database = database
46+
}
47+
}
48+
49+
tableInterface, ok := options["table"]
50+
if ok {
51+
table, ok := tableInterface.(string)
52+
if ok {
53+
o.Table = table
54+
}
55+
}
56+
57+
fieldInterface, ok := options["field"]
58+
if ok {
59+
field, ok := fieldInterface.(string)
60+
if ok {
61+
o.Field = field
62+
}
63+
}
64+
65+
connectInterface, ok := options["connect"]
66+
if ok {
67+
connect, ok := connectInterface.(bool)
68+
if ok {
69+
o.Connect = connect
70+
}
71+
}
72+
73+
tableExistsInterface, ok := options["table_exists"]
74+
if ok {
75+
tableExists, ok := tableExistsInterface.(bool)
76+
if ok {
77+
o.TableExists = tableExists
78+
}
79+
}
80+
81+
rowExistsInterface, ok := options["row_exists"]
82+
if ok {
83+
rowExists, ok := rowExistsInterface.(bool)
84+
if ok {
85+
o.RowExists = rowExists
86+
}
87+
}
88+
89+
regexMatchInterface, ok := options["regex_match"]
90+
if ok {
91+
regexMatch, ok := regexMatchInterface.(bool)
92+
if ok {
93+
o.RegexMatch = regexMatch
94+
}
95+
}
96+
97+
substringMatchInterface, ok := options["substring_match"]
98+
if ok {
99+
substringMatch, ok := substringMatchInterface.(bool)
100+
if ok {
101+
o.SubstringMatch = substringMatch
102+
}
103+
}
104+
105+
matchInterface, ok := options["match"]
106+
if ok {
107+
match, ok := matchInterface.(bool)
108+
if ok {
109+
o.Match = match
110+
}
111+
}
112+
}
113+
7114
func Run(ctx context.Context, target string, command string, expectedOutput string, username string, password string, options map[string]interface{}) (bool, string) {
115+
optionsStruct := optionsStruct{}
116+
optionsStruct.Unmarshal(options)
117+
118+
conn, err := sql.Open(
119+
"mysql",
120+
fmt.Sprintf(
121+
"%s:%s@tcp(%s)/%s",
122+
username,
123+
password,
124+
target,
125+
optionsStruct.Database,
126+
),
127+
)
128+
if err != nil {
129+
return false, err.Error()
130+
}
131+
defer conn.Close()
132+
133+
conn.SetConnMaxIdleTime(-1)
134+
conn.SetMaxOpenConns(1)
135+
136+
// Check if connection can be made
137+
if optionsStruct.Connect {
138+
err = conn.Ping()
139+
if err != nil {
140+
return false, err.Error()
141+
}
142+
}
143+
144+
// Check if table exists
145+
if optionsStruct.TableExists {
146+
query, err := conn.Prepare("SHOW TABLES LIKE ?")
147+
if err != nil {
148+
return false, err.Error()
149+
}
150+
defer query.Close()
151+
152+
rows, err := query.Query(optionsStruct.Table)
153+
if err != nil {
154+
return false, err.Error()
155+
}
156+
157+
if !rows.Next() {
158+
return false, fmt.Sprintf("table does not exist: \"%s\"", optionsStruct.Table)
159+
}
160+
}
161+
162+
// Check if row exists
163+
if optionsStruct.RowExists {
164+
query, err := conn.Prepare("SELECT * FROM ? LIMIT 1")
165+
if err != nil {
166+
return false, err.Error()
167+
}
168+
defer query.Close()
169+
170+
rows, err := query.Query(optionsStruct.Table)
171+
if err != nil {
172+
return false, err.Error()
173+
}
174+
175+
if !rows.Next() {
176+
return false, fmt.Sprintf("table is empty: \"%s\"", optionsStruct.Table)
177+
}
178+
}
179+
180+
// Check if field matches regex
181+
if optionsStruct.RegexMatch {
182+
regexp, err := regexp.Compile(expectedOutput)
183+
if err != nil {
184+
return false, err.Error()
185+
}
186+
187+
query, err := conn.Prepare("SELECT ? FROM ? LIMIT 1")
188+
if err != nil {
189+
return false, err.Error()
190+
}
191+
defer query.Close()
192+
193+
rows, err := query.Query(optionsStruct.Field, optionsStruct.Table)
194+
if err != nil {
195+
return false, err.Error()
196+
}
197+
198+
if !rows.Next() {
199+
return false, fmt.Sprintf("table is empty: \"%s\"", optionsStruct.Table)
200+
}
201+
202+
var field string
203+
err = rows.Scan(&field)
204+
if err != nil {
205+
return false, err.Error()
206+
}
207+
208+
if !regexp.MatchString(field) {
209+
return false, fmt.Sprintf("field does not match regex: \"%s\"", expectedOutput)
210+
}
211+
}
212+
213+
// Check if field matches substring or contains substring
214+
if optionsStruct.SubstringMatch || optionsStruct.Match {
215+
query, err := conn.Prepare("SELECT ? FROM ? LIMIT 1")
216+
if err != nil {
217+
return false, err.Error()
218+
}
219+
defer query.Close()
220+
221+
rows, err := query.Query(optionsStruct.Field, optionsStruct.Table)
222+
if err != nil {
223+
return false, err.Error()
224+
}
225+
226+
if !rows.Next() {
227+
return false, fmt.Sprintf("table is empty: \"%s\"", optionsStruct.Table)
228+
}
229+
230+
var field string
231+
err = rows.Scan(&field)
232+
if err != nil {
233+
return false, err.Error()
234+
}
235+
236+
if optionsStruct.Match && field != expectedOutput {
237+
return false, fmt.Sprintf("field does not match string: \"%s\"", expectedOutput)
238+
}
239+
240+
if optionsStruct.SubstringMatch && !strings.Contains(field, expectedOutput) {
241+
return false, fmt.Sprintf("field does not contain substring: \"%s\"", expectedOutput)
242+
}
243+
244+
}
245+
8246
return true, ""
9247
}

0 commit comments

Comments
 (0)