Skip to content

Commit b30d2f2

Browse files
authored
add cdb audit log (#1629)
* add cdb audit log * add cdb audit log changelog * add cdb audit log changelog
1 parent f2c5a35 commit b30d2f2

File tree

7 files changed

+554
-0
lines changed

7 files changed

+554
-0
lines changed

.changelog/1629.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:new-resource
2+
tencentcloud_mysql_audit_log_file
3+
```

tencentcloud/provider.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ TencentDB for MySQL(cdb)
447447
tencentcloud_mysql_deploy_group
448448
tencentcloud_mysql_security_groups_attachment
449449
tencentcloud_mysql_local_binlog_config
450+
tencentcloud_mysql_audit_log_file
450451
451452
Cloud Monitor(Monitor)
452453
Data Source
@@ -1452,6 +1453,7 @@ func Provider() terraform.ResourceProvider {
14521453
"tencentcloud_mysql_security_groups_attachment": resourceTencentCloudMysqlSecurityGroupsAttachment(),
14531454
"tencentcloud_mysql_deploy_group": resourceTencentCloudMysqlDeployGroup(),
14541455
"tencentcloud_mysql_local_binlog_config": resourceTencentCloudMysqlLocalBinlogConfig(),
1456+
"tencentcloud_mysql_audit_log_file": resourceTencentCloudMysqlAuditLogFile(),
14551457
"tencentcloud_cos_bucket": resourceTencentCloudCosBucket(),
14561458
"tencentcloud_cos_bucket_object": resourceTencentCloudCosBucketObject(),
14571459
"tencentcloud_cfs_file_system": resourceTencentCloudCfsFileSystem(),
Lines changed: 373 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,373 @@
1+
/*
2+
Provides a resource to create a mysql audit_log_file
3+
4+
Example Usage
5+
6+
```hcl
7+
resource "tencentcloud_mysql_audit_log_file" "audit_log_file" {
8+
instance_id = "cdb-fitq5t9h"
9+
start_time = "2023-03-28 20:14:00"
10+
end_time = "2023-03-29 20:14:00"
11+
order = "ASC"
12+
order_by = "timestamp"
13+
filter {
14+
host = ["30.50.207.46"]
15+
user = ["keep_dbbrain"]
16+
}
17+
}
18+
```
19+
20+
*/
21+
package tencentcloud
22+
23+
import (
24+
"context"
25+
"fmt"
26+
"log"
27+
"strings"
28+
"time"
29+
30+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
31+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
32+
mysql "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdb/v20170320"
33+
"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
34+
)
35+
36+
func resourceTencentCloudMysqlAuditLogFile() *schema.Resource {
37+
return &schema.Resource{
38+
Create: resourceTencentCloudMysqlAuditLogFileCreate,
39+
Read: resourceTencentCloudMysqlAuditLogFileRead,
40+
Delete: resourceTencentCloudMysqlAuditLogFileDelete,
41+
Schema: map[string]*schema.Schema{
42+
"instance_id": {
43+
Required: true,
44+
Type: schema.TypeString,
45+
ForceNew: true,
46+
Description: "The ID of instance.",
47+
},
48+
49+
"start_time": {
50+
Required: true,
51+
Type: schema.TypeString,
52+
ForceNew: true,
53+
Description: "start time.",
54+
},
55+
56+
"end_time": {
57+
Required: true,
58+
Type: schema.TypeString,
59+
ForceNew: true,
60+
Description: "end time.",
61+
},
62+
63+
"order": {
64+
Optional: true,
65+
Type: schema.TypeString,
66+
ForceNew: true,
67+
Description: "Sort by. supported values are: `ASC`- ascending order, `DESC`- descending order.",
68+
},
69+
70+
"order_by": {
71+
Optional: true,
72+
Type: schema.TypeString,
73+
ForceNew: true,
74+
Description: "Sort field. supported values include:`timestamp` - timestamp; `affectRows` - affected rows; `execTime` - execution time.",
75+
},
76+
77+
"filter": {
78+
Optional: true,
79+
Type: schema.TypeList,
80+
ForceNew: true,
81+
MaxItems: 1,
82+
Description: "Filter condition. Logs can be filtered according to the filter conditions set.",
83+
Elem: &schema.Resource{
84+
Schema: map[string]*schema.Schema{
85+
"host": {
86+
Type: schema.TypeSet,
87+
Elem: &schema.Schema{
88+
Type: schema.TypeString,
89+
},
90+
Optional: true,
91+
Description: "Client address.",
92+
},
93+
"user": {
94+
Type: schema.TypeSet,
95+
Elem: &schema.Schema{
96+
Type: schema.TypeString,
97+
},
98+
Optional: true,
99+
Description: "User name.",
100+
},
101+
"db_name": {
102+
Type: schema.TypeSet,
103+
Elem: &schema.Schema{
104+
Type: schema.TypeString,
105+
},
106+
Optional: true,
107+
Description: "Database name.",
108+
},
109+
"table_name": {
110+
Type: schema.TypeSet,
111+
Elem: &schema.Schema{
112+
Type: schema.TypeString,
113+
},
114+
Optional: true,
115+
Description: "Table name.",
116+
},
117+
"policy_name": {
118+
Type: schema.TypeSet,
119+
Elem: &schema.Schema{
120+
Type: schema.TypeString,
121+
},
122+
Optional: true,
123+
Description: "The name of policy.",
124+
},
125+
"sql": {
126+
Type: schema.TypeString,
127+
Optional: true,
128+
Description: "SQL statement. support fuzzy matching.",
129+
},
130+
"sql_type": {
131+
Type: schema.TypeString,
132+
Optional: true,
133+
Description: "SQL type. Currently supported: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, SET, REPLACE, EXECUTE.",
134+
},
135+
"exec_time": {
136+
Type: schema.TypeInt,
137+
Optional: true,
138+
Description: "Execution time. The unit is: ms. Indicates to filter audit logs whose execution time is greater than this value.",
139+
},
140+
"affect_rows": {
141+
Type: schema.TypeInt,
142+
Optional: true,
143+
Description: "Affects the number of rows. Indicates to filter audit logs whose number of affected rows is greater than this value.",
144+
},
145+
"sql_types": {
146+
Type: schema.TypeSet,
147+
Elem: &schema.Schema{
148+
Type: schema.TypeString,
149+
},
150+
Optional: true,
151+
Description: "SQL type. Supports simultaneous query of multiple types. Currently supported: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, SET, REPLACE, EXECUTE.",
152+
},
153+
"sqls": {
154+
Type: schema.TypeSet,
155+
Elem: &schema.Schema{
156+
Type: schema.TypeString,
157+
},
158+
Optional: true,
159+
Description: "SQL statement. Support passing multiple sql statements.",
160+
},
161+
},
162+
},
163+
},
164+
165+
"file_size": {
166+
Computed: true,
167+
Type: schema.TypeInt,
168+
Description: "size of file(KB).",
169+
},
170+
171+
"download_url": {
172+
Computed: true,
173+
Type: schema.TypeString,
174+
Description: "download url.",
175+
},
176+
},
177+
}
178+
}
179+
180+
func resourceTencentCloudMysqlAuditLogFileCreate(d *schema.ResourceData, meta interface{}) error {
181+
defer logElapsed("resource.tencentcloud_mysql_audit_log_file.create")()
182+
defer inconsistentCheck(d, meta)()
183+
184+
logId := getLogId(contextNil)
185+
186+
var (
187+
request = mysql.NewCreateAuditLogFileRequest()
188+
response = mysql.NewCreateAuditLogFileResponse()
189+
instanceId string
190+
fileName string
191+
)
192+
if v, ok := d.GetOk("instance_id"); ok {
193+
instanceId = v.(string)
194+
request.InstanceId = helper.String(v.(string))
195+
}
196+
197+
if v, ok := d.GetOk("start_time"); ok {
198+
request.StartTime = helper.String(v.(string))
199+
}
200+
201+
if v, ok := d.GetOk("end_time"); ok {
202+
request.EndTime = helper.String(v.(string))
203+
}
204+
205+
if v, ok := d.GetOk("order"); ok {
206+
request.Order = helper.String(v.(string))
207+
}
208+
209+
if v, ok := d.GetOk("order_by"); ok {
210+
request.OrderBy = helper.String(v.(string))
211+
}
212+
213+
if dMap, ok := helper.InterfacesHeadMap(d, "filter"); ok {
214+
auditLogFilter := mysql.AuditLogFilter{}
215+
if v, ok := dMap["host"]; ok {
216+
hostSet := v.(*schema.Set).List()
217+
for i := range hostSet {
218+
host := hostSet[i].(string)
219+
auditLogFilter.Host = append(auditLogFilter.Host, &host)
220+
}
221+
}
222+
if v, ok := dMap["user"]; ok {
223+
userSet := v.(*schema.Set).List()
224+
for i := range userSet {
225+
user := userSet[i].(string)
226+
auditLogFilter.User = append(auditLogFilter.User, &user)
227+
}
228+
}
229+
if v, ok := dMap["db_name"]; ok {
230+
dBNameSet := v.(*schema.Set).List()
231+
for i := range dBNameSet {
232+
dBName := dBNameSet[i].(string)
233+
auditLogFilter.DBName = append(auditLogFilter.DBName, &dBName)
234+
}
235+
}
236+
if v, ok := dMap["table_name"]; ok {
237+
tableNameSet := v.(*schema.Set).List()
238+
for i := range tableNameSet {
239+
tableName := tableNameSet[i].(string)
240+
auditLogFilter.TableName = append(auditLogFilter.TableName, &tableName)
241+
}
242+
}
243+
if v, ok := dMap["policy_name"]; ok {
244+
policyNameSet := v.(*schema.Set).List()
245+
for i := range policyNameSet {
246+
policyName := policyNameSet[i].(string)
247+
auditLogFilter.PolicyName = append(auditLogFilter.PolicyName, &policyName)
248+
}
249+
}
250+
if v, ok := dMap["sql"]; ok {
251+
auditLogFilter.Sql = helper.String(v.(string))
252+
}
253+
if v, ok := dMap["sql_type"]; ok {
254+
auditLogFilter.SqlType = helper.String(v.(string))
255+
}
256+
if v, ok := dMap["exec_time"]; ok {
257+
auditLogFilter.ExecTime = helper.IntInt64(v.(int))
258+
}
259+
if v, ok := dMap["affect_rows"]; ok {
260+
auditLogFilter.AffectRows = helper.IntInt64(v.(int))
261+
}
262+
if v, ok := dMap["sql_types"]; ok {
263+
sqlTypesSet := v.(*schema.Set).List()
264+
for i := range sqlTypesSet {
265+
sqlTypes := sqlTypesSet[i].(string)
266+
auditLogFilter.SqlTypes = append(auditLogFilter.SqlTypes, &sqlTypes)
267+
}
268+
}
269+
if v, ok := dMap["sqls"]; ok {
270+
sqlsSet := v.(*schema.Set).List()
271+
for i := range sqlsSet {
272+
sqls := sqlsSet[i].(string)
273+
auditLogFilter.Sqls = append(auditLogFilter.Sqls, &sqls)
274+
}
275+
}
276+
request.Filter = &auditLogFilter
277+
}
278+
279+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
280+
result, e := meta.(*TencentCloudClient).apiV3Conn.UseMysqlClient().CreateAuditLogFile(request)
281+
if e != nil {
282+
return retryError(e)
283+
} else {
284+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString())
285+
}
286+
response = result
287+
return nil
288+
})
289+
if err != nil {
290+
log.Printf("[CRITAL]%s create mysql auditLogFile failed, reason:%+v", logId, err)
291+
return err
292+
}
293+
294+
fileName = *response.Response.FileName
295+
d.SetId(instanceId + FILED_SP + fileName)
296+
297+
service := MysqlService{client: meta.(*TencentCloudClient).apiV3Conn}
298+
299+
conf := BuildStateChangeConf(
300+
[]string{"creating"},
301+
[]string{"success", "failed"},
302+
1*readRetryTimeout,
303+
time.Second,
304+
service.MysqlAuditLogFileStateRefreshFunc(instanceId, fileName, []string{}),
305+
)
306+
307+
if _, e := conf.WaitForState(); e != nil {
308+
return e
309+
}
310+
311+
return resourceTencentCloudMysqlAuditLogFileRead(d, meta)
312+
}
313+
314+
func resourceTencentCloudMysqlAuditLogFileRead(d *schema.ResourceData, meta interface{}) error {
315+
defer logElapsed("resource.tencentcloud_mysql_audit_log_file.read")()
316+
defer inconsistentCheck(d, meta)()
317+
318+
logId := getLogId(contextNil)
319+
320+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
321+
322+
service := MysqlService{client: meta.(*TencentCloudClient).apiV3Conn}
323+
324+
idSplit := strings.Split(d.Id(), FILED_SP)
325+
if len(idSplit) != 2 {
326+
return fmt.Errorf("id is broken,%s", d.Id())
327+
}
328+
instanceId := idSplit[0]
329+
fileName := idSplit[1]
330+
331+
auditLogFile, err := service.DescribeMysqlAuditLogFileById(ctx, instanceId, fileName)
332+
if err != nil {
333+
return err
334+
}
335+
336+
if auditLogFile == nil {
337+
d.SetId("")
338+
log.Printf("[WARN]%s resource `MysqlAuditLogFile` [%s] not found, please check if it has been deleted.\n", logId, d.Id())
339+
return nil
340+
}
341+
342+
if auditLogFile.FileSize != nil {
343+
_ = d.Set("file_size", auditLogFile.FileSize)
344+
}
345+
346+
if auditLogFile.DownloadUrl != nil {
347+
_ = d.Set("download_url", auditLogFile.DownloadUrl)
348+
}
349+
350+
return nil
351+
}
352+
353+
func resourceTencentCloudMysqlAuditLogFileDelete(d *schema.ResourceData, meta interface{}) error {
354+
defer logElapsed("resource.tencentcloud_mysql_audit_log_file.delete")()
355+
defer inconsistentCheck(d, meta)()
356+
357+
logId := getLogId(contextNil)
358+
ctx := context.WithValue(context.TODO(), logIdKey, logId)
359+
360+
service := MysqlService{client: meta.(*TencentCloudClient).apiV3Conn}
361+
idSplit := strings.Split(d.Id(), FILED_SP)
362+
if len(idSplit) != 2 {
363+
return fmt.Errorf("id is broken,%s", d.Id())
364+
}
365+
instanceId := idSplit[0]
366+
fileName := idSplit[1]
367+
368+
if err := service.DeleteMysqlAuditLogFileById(ctx, instanceId, fileName); err != nil {
369+
return err
370+
}
371+
372+
return nil
373+
}

0 commit comments

Comments
 (0)