Skip to content

Commit 5c0c723

Browse files
xfwdukeiSecloud
authored andcommitted
feat(mysql): mysql权限申请优化 TencentBlueKing#8650
1 parent 2f6dc83 commit 5c0c723

File tree

18 files changed

+478
-598
lines changed

18 files changed

+478
-598
lines changed

dbm-services/mysql/db-priv/service/add_priv_base_func.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,14 @@ func GenerateBackendSQL(account TbAccounts, rule TbAccountRules, ips []string, m
207207
}
208208
// 备库域名只授予查询类权限
209209
if clusterType == tendbha && tendbhaMasterDomain == false {
210-
sql = fmt.Sprintf("GRANT SELECT, SHOW VIEW ON `%s`.* TO '%s'@'%s' %s;",
211-
rule.Dbname, account.User, ip, identifiedByPassword)
210+
if rule.Dbname == "%" || rule.Dbname == "*" {
211+
sql = fmt.Sprintf("GRANT SELECT, SHOW VIEW ON *.* TO '%s'@'%s' %s;",
212+
account.User, ip, identifiedByPassword)
213+
} else {
214+
sql = fmt.Sprintf("GRANT SELECT, SHOW VIEW ON `%s`.* TO '%s'@'%s' %s;",
215+
rule.Dbname, account.User, ip, identifiedByPassword)
216+
}
217+
212218
sqlTemp = append(sqlTemp, sql)
213219
if containConnLogDBFlag {
214220
sql = fmt.Sprintf("%s '%s'@'%s' %s;", insertConnLogPriv, account.User, ip, identifiedByPassword)
@@ -229,8 +235,14 @@ func GenerateBackendSQL(account TbAccounts, rule TbAccountRules, ips []string, m
229235
}
230236

231237
if rule.DmlDdlPriv != "" {
232-
sql = fmt.Sprintf("GRANT %s ON `%s`.* TO '%s'@'%s' %s;",
233-
rule.DmlDdlPriv, rule.Dbname, account.User, ip, identifiedByPassword)
238+
if rule.Dbname == "%" || rule.Dbname == "*" {
239+
sql = fmt.Sprintf("GRANT %s ON *.* TO '%s'@'%s' %s;",
240+
rule.DmlDdlPriv, account.User, ip, identifiedByPassword)
241+
} else {
242+
sql = fmt.Sprintf("GRANT %s ON `%s`.* TO '%s'@'%s' %s;",
243+
rule.DmlDdlPriv, rule.Dbname, account.User, ip, identifiedByPassword)
244+
}
245+
234246
sqlTemp = append(sqlTemp, sql)
235247
if needInsertConnLogFlag {
236248
sql = fmt.Sprintf("%s '%s'@'%s' %s;", insertConnLogPriv, account.User, ip, identifiedByPassword)

dbm-services/mysql/db-priv/service/v2/add_priv/add_on_mysql.go

+13-7
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,15 @@ func (c *PrivTaskPara) addOneDtOnMySQL(
6464
dt *service.TbAccountRules,
6565
reports map[string][]string,
6666
) error {
67-
var ipStr string
67+
var oneBatchClients []string
6868
for idx, ip := range clientIps {
69-
// 限长 1500 代码会比较好些, 不往极限的 2000 搞
70-
ipStr = ipStr + "," + ip
71-
if len(ipStr) > 1500 || idx == len(clientIps)-1 {
72-
slog.Info("add one dt on mysql", slog.String("ipstr", ipStr))
69+
// 限长 100 代码会比较好些, 不往极限的 2000 搞
70+
oneBatchClients = append(oneBatchClients, ip)
71+
if len(oneBatchClients) > 100 || idx == len(clientIps)-1 {
72+
slog.Info("add one dt on mysql", slog.Any("one batch client", oneBatchClients))
73+
// 一次跑一批 client
7374
err := c.addOneDtOnMySQLForSplitClient(
74-
strings.Trim(ipStr, ","),
75+
strings.Join(oneBatchClients, ","),
7576
workingInstances,
7677
accountAndRuleDetails,
7778
psw,
@@ -82,7 +83,7 @@ func (c *PrivTaskPara) addOneDtOnMySQL(
8283
slog.Error("add on mysql", slog.String("err", err.Error()))
8384
return err
8485
}
85-
ipStr = ""
86+
oneBatchClients = []string{}
8687
}
8788
}
8889
return nil
@@ -152,6 +153,7 @@ func readOneDtRes(bkCloudId int64, res []*drs.OneAddressResult, reports map[stri
152153
slog.String("addr", r.Address),
153154
)
154155
reports[r.Address] = []string{r.ErrorMsg}
156+
continue
155157
}
156158
readOneAddrRes(bkCloudId, r, reports)
157159
}
@@ -163,6 +165,10 @@ func readOneAddrRes(bkCloudId int64, r *drs.OneAddressResult, reports map[string
163165
return
164166
}
165167

168+
if _, ok := reports[r.Address]; !ok {
169+
reports[r.Address] = make([]string, 0)
170+
}
171+
166172
_, sqlStat, msgText, isException := internal.ParseMySQLErrStr(errMsg)
167173
if !isException {
168174
reports[r.Address] = append(reports[r.Address], msgText)

dbm-services/mysql/db-priv/service/v2/add_priv/add_priv.go

+12-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"dbm-services/mysql/priv-service/service/v2/internal"
77
"encoding/json"
88
"log/slog"
9+
"strings"
910
"time"
1011

1112
"github.com/pkg/errors"
@@ -17,7 +18,9 @@ func (c *PrivTaskPara) AddPriv(jsonPara, ticket string) (err error) {
1718
slog.String("jsonPara", jsonPara),
1819
)
1920

20-
if c.ClusterType == internal.ClusterTypeSqlServerHA || c.ClusterType == internal.ClusterTypeSqlServer || c.ClusterType == internal.ClusterTypeSqlServerSingle {
21+
if c.ClusterType == internal.ClusterTypeSqlServerHA ||
22+
c.ClusterType == internal.ClusterTypeSqlServer ||
23+
c.ClusterType == internal.ClusterTypeSqlServerSingle {
2124
return c.AddPrivForSqlserver(jsonPara)
2225
}
2326

@@ -39,6 +42,8 @@ func (c *PrivTaskPara) AddPriv(jsonPara, ticket string) (err error) {
3942
// targetInstance 传入的其实全是域名
4043
c.TargetInstances = internal.UniqueStringSlice(c.TargetInstances)
4144

45+
slog.Info("add priv", slog.String("source ips", strings.Join(c.SourceIPs, ",")))
46+
4247
// 写审计日志
4348
service.AddPrivLog(
4449
service.PrivLog{
@@ -56,6 +61,7 @@ func (c *PrivTaskPara) AddPriv(jsonPara, ticket string) (err error) {
5661
slog.Error("add priv", slog.String("err", err.Error()))
5762
return err
5863
}
64+
slog.Info("add priv", slog.Any("target meta infos", targetMetaInfos))
5965

6066
/*
6167
TenDBSingle 授权是在存储实例操作
@@ -64,6 +70,7 @@ func (c *PrivTaskPara) AddPriv(jsonPara, ticket string) (err error) {
6470
*/
6571

6672
// 开白名单
73+
// proxy 白名单是前置集中开, 所有出错了直接返回
6774
if c.ClusterType == internal.ClusterTypeTenDBHA {
6875
err = c.addWhiteList(targetMetaInfos)
6976
if err != nil {
@@ -80,7 +87,7 @@ func (c *PrivTaskPara) AddPriv(jsonPara, ticket string) (err error) {
8087
clientIps, workingMySQLInstances := c.prepareMySQLPayload(targetMetaInfos)
8188
slog.Info(
8289
"add priv",
83-
slog.Any("clientIps", clientIps),
90+
slog.String("clientIps", strings.Join(clientIps, ",")),
8491
slog.Any("workingMySQLInstances", workingMySQLInstances),
8592
)
8693

@@ -96,6 +103,8 @@ func (c *PrivTaskPara) AddPriv(jsonPara, ticket string) (err error) {
96103
slog.String("accountAndRuleDetails", accountAndRuleDetails.String()),
97104
)
98105

106+
// err 是调用函数出错, 直接报错返回
107+
// reports 是实施授权的报告
99108
reports, err := c.addOnMySQL(clientIps, workingMySQLInstances, accountAndRuleDetails)
100109
if err != nil {
101110
slog.Error("add priv", slog.String("err", err.Error()))
@@ -111,6 +120,6 @@ func (c *PrivTaskPara) AddPriv(jsonPara, ticket string) (err error) {
111120
return errors.New(string(b))
112121
}
113122

114-
slog.Info("add priv finish", slog.Any("reports", reports))
123+
slog.Info("add priv finish")
115124
return nil
116125
}

dbm-services/mysql/db-priv/service/v2/add_priv/add_proxy_white_list.go

+54-56
Original file line numberDiff line numberDiff line change
@@ -33,71 +33,54 @@ func (c *PrivTaskPara) addWhiteList(targetMetaInfos []*service.Instance) (err er
3333
slog.Any("proxies", workingProxies),
3434
)
3535

36-
// 确实有要操作的 proxy
37-
if len(workingProxies) > 0 {
38-
var cmds []string
39-
for _, clientIp := range c.SourceIPs {
40-
//clientIp 可能是 localhost, 要忽略
41-
if clientIp == "localhost" {
42-
continue
43-
}
44-
cmds = append(
45-
cmds,
46-
fmt.Sprintf(`refresh_users('%s@%s', '+')`,
47-
c.User, clientIp,
48-
))
49-
}
36+
if len(workingProxies) <= 0 {
37+
return nil
38+
}
39+
40+
cmds := generateProxyCmds(c.SourceIPs, c.User)
41+
slog.Info(
42+
"add proxy white list",
43+
slog.Any("cmds", cmds),
44+
)
45+
46+
// drs 执行多个 sql 是循环一个一个来的
47+
// 所以批量发送是可以的, 只是这么搞 drs 负载估计要炸
48+
// 这里搞并发的意义不大
49+
var errCollect error
50+
for bkCloudId, addresses := range workingProxies {
5051
slog.Info(
5152
"add proxy white list",
52-
slog.Any("cmds", cmds),
53+
slog.Int64("bk_cloud_id", bkCloudId),
54+
slog.Any("addresses", addresses),
55+
)
56+
drsRes, err := drs.RPCProxyAdmin(
57+
bkCloudId,
58+
addresses,
59+
cmds,
60+
false,
61+
0,
5362
)
63+
if err != nil {
64+
slog.Error("add proxy white list", slog.String("err", err.Error()))
65+
return err
66+
}
5467

55-
// drs 执行多个 sql 是循环一个一个来的
56-
// 所以批量发送是可以的, 只是这么搞 drs 负载估计要炸
57-
// 这里搞并发的意义不大
58-
var errCollect error
59-
for bkCloudId, addresses := range workingProxies {
68+
// 错误要收集起来
69+
ec := collectErrors(drsRes)
70+
if ec != nil {
71+
slog.Error("add proxy white list", slog.String("err collection", ec.Error()))
72+
errCollect = errors.Join(errCollect, ec)
73+
} else {
6074
slog.Info(
61-
"add proxy white list",
75+
"add proxy white list success",
6276
slog.Int64("bk_cloud_id", bkCloudId),
63-
slog.Any("addresses", addresses),
6477
)
65-
drsRes, err := drs.RPCProxyAdmin(
66-
bkCloudId,
67-
addresses,
68-
cmds,
69-
false,
70-
0,
71-
)
72-
if err != nil {
73-
slog.Error(
74-
"add proxy white list",
75-
slog.Int64("bk_cloud_id", bkCloudId),
76-
slog.String("err", err.Error()),
77-
)
78-
return err
79-
}
80-
81-
// 错误要收集起来
82-
ec := collectErrors(drsRes)
83-
if ec != nil {
84-
slog.Error(
85-
"add proxy white list",
86-
slog.Int64("bk_cloud_id", bkCloudId),
87-
slog.String("err", ec.Error()),
88-
)
89-
errCollect = errors.Join(errCollect, ec)
90-
} else {
91-
slog.Info(
92-
"add proxy white list success",
93-
slog.Int64("bk_cloud_id", bkCloudId),
94-
)
95-
}
96-
}
97-
if errCollect != nil {
98-
return errCollect
9978
}
10079
}
80+
if errCollect != nil {
81+
return errCollect
82+
}
83+
10184
return nil
10285
}
10386

@@ -120,3 +103,18 @@ func collectErrors(res []*drs.OneAddressResult) (ec error) {
120103
}
121104
return ec
122105
}
106+
107+
func generateProxyCmds(clientIps []string, username string) (cmds []string) {
108+
for _, clientIp := range clientIps {
109+
//clientIp 可能是 localhost, 要忽略
110+
if clientIp == "localhost" {
111+
continue
112+
}
113+
cmds = append(
114+
cmds,
115+
fmt.Sprintf(`refresh_users('%s@%s', '+')`,
116+
username, clientIp,
117+
))
118+
}
119+
return cmds
120+
}

dbm-services/mysql/db-priv/service/v2/add_priv/fetch_target_dbmeta_info.go

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func (c *PrivTaskPara) fetchTargetDBMetaInfo() ([]*service.Instance, error) {
3737
)
3838
return nil, err
3939
}
40+
slog.Info("fetch target db meta info", slog.Any("result", result))
4041

4142
res := make([]*service.Instance, 0)
4243
err = json.Unmarshal(result.Data, &res)

dbm-services/mysql/db-priv/service/v2/add_priv/prepare.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"dbm-services/mysql/priv-service/service/v2/internal"
66
"fmt"
77
"log/slog"
8+
"strings"
89
)
910

1011
func (c *PrivTaskPara) prepareMySQLPayload(targetMetaInfos []*service.Instance) (
@@ -27,7 +28,7 @@ func (c *PrivTaskPara) prepareMySQLPayload(targetMetaInfos []*service.Instance)
2728
func (c *PrivTaskPara) prepareTenDBSingle(targetMetaInfos []*service.Instance) (
2829
clientIps []string,
2930
workingMySQLInstances map[int64][]string) {
30-
clientIps = make([]string, 0)
31+
clientIps = c.SourceIPs
3132
workingMySQLInstances = make(map[int64][]string)
3233

3334
for _, ele := range targetMetaInfos {
@@ -58,13 +59,21 @@ func (c *PrivTaskPara) prepareTenDBHA(targetMetaInfos []*service.Instance) (
5859

5960
// 申请主域名权限要把来源替换为 proxy ip
6061
// 如果集群有 padding proxy 属性, 则是把 proxy ip 追加到 client ip 里
62+
slog.Info(
63+
"prepare tendbha",
64+
slog.String("bind to", ele.BindTo),
65+
slog.Bool("padding proxy", ele.PaddingProxy),
66+
)
6167
if ele.BindTo == internal.MachineTypeProxy {
6268
if ele.PaddingProxy {
6369
clientIps = append(clientIps, proxyIps...)
6470
} else {
6571
clientIps = proxyIps
6672
}
73+
} else {
74+
clientIps = c.SourceIPs
6775
}
76+
slog.Info("prepare tendbha", slog.String("clientIps", strings.Join(clientIps, ",")))
6877
// TenDBHA 要在所有存储实例执行授权
6978
for _, s := range ele.Storages {
7079
if _, ok := workingMySQLInstances[ele.BkCloudId]; !ok {
@@ -81,7 +90,7 @@ func (c *PrivTaskPara) prepareTenDBHA(targetMetaInfos []*service.Instance) (
8190
}
8291

8392
func (c *PrivTaskPara) prepareTenDBCluster(targetMetaInfos []*service.Instance) (clientIps []string, workingMySQLInstances map[int64][]string) {
84-
clientIps = make([]string, 0)
93+
clientIps = c.SourceIPs
8594
workingMySQLInstances = make(map[int64][]string)
8695

8796
// 对应的 spider 上执行授权

0 commit comments

Comments
 (0)