Skip to content

Commit

Permalink
feat: dbpriv不允许内部账号名_支持replication授权 TencentBlueKing#7314
Browse files Browse the repository at this point in the history
  • Loading branch information
fanfanyangyang authored and iSecloud committed Oct 14, 2024
1 parent 9e32ef0 commit 64d8154
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 106 deletions.
10 changes: 6 additions & 4 deletions dbm-services/common/go-pubpkg/errno/50000_dbpriv_code.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ var (
CNMessage: "检查没有通过"}
MigrateFail = Errno{Code: 51038, Message: "migrate fail",
CNMessage: "迁移失败"}
PortRequired = Errno{Code: 51039, Message: "port is required", CNMessage: "port不能为空"}
IpRequired = Errno{Code: 51040, Message: "ip is required", CNMessage: "ip列表不能为空"}
DomainRequired = Errno{Code: 51041, Message: "domain is required", CNMessage: "域名列表不能为空"}
QueryPrivilegesFail = Errno{Code: 51042, Message: "query privileges fail", CNMessage: "查询权限失败"}
PortRequired = Errno{Code: 51039, Message: "port is required", CNMessage: "port不能为空"}
IpRequired = Errno{Code: 51040, Message: "ip is required", CNMessage: "ip列表不能为空"}
DomainRequired = Errno{Code: 51041, Message: "domain is required", CNMessage: "域名列表不能为空"}
QueryPrivilegesFail = Errno{Code: 51042, Message: "query privileges fail", CNMessage: "查询权限失败"}
InternalAccountNameNotAllowed = Errno{Code: 51043, Message: "internal account name is not allowed",
CNMessage: "不允许使用内部账号名称"}
)
12 changes: 12 additions & 0 deletions dbm-services/mysql/db-priv/service/account.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package service

import (
"dbm-services/mysql/priv-service/util"
"encoding/hex"
"fmt"
"log/slog"
Expand Down Expand Up @@ -47,6 +48,17 @@ func (m *AccountPara) AddAccount(jsonPara string, ticket string) (TbAccounts, er
if count != 0 {
return detail, errno.AccountExisted.AddBefore(m.User)
}
innerAccount := make(map[string][]string)
innerAccount[sqlserver] = []string{"mssql_exporter", "dbm_admin", "sa", "sqlserver"}
innerAccount[mongodb] = []string{"dba", "apppdba", "monitor", "appmonitor"}
innerAccount[mysql] = []string{"gcs_admin", "gcs_dba", "monitor", "gm", "admin", "repl", "dba_bak_all_sel",
"yw", "partition_yw", "spider", "mysql.session", "mysql.sys", "gcs_spider", "sync"}
innerAccount[tendbcluster] = innerAccount[mysql]
if !m.MigrateFlag {
if util.HasElem(strings.ToLower(m.User), innerAccount[*m.ClusterType]) {
return detail, errno.InternalAccountNameNotAllowed
}
}
psw = m.Psw
// 从旧系统迁移的,不检查是否帐号和密码不同
if psw == m.User && !m.MigrateFlag {
Expand Down
35 changes: 33 additions & 2 deletions dbm-services/mysql/db-priv/service/add_priv.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"log/slog"
"regexp"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -80,12 +81,27 @@ func (m *PrivTaskPara) AddPriv(jsonPara string, ticket string) error {
limit := rate.Every(time.Millisecond * 100) // QPS:10
burst := 10 // 桶容量 10
limiter := rate.NewLimiter(limit, burst)
for _, rule := range m.AccoutRules { // 添加权限,for acccountRuleList;for instanceList; do create a routine
for _, rule := range m.AccoutRules { // 添加权限,for accountRuleList;for instanceList; do create a routine
account, accountRule, outerErr := GetAccountRuleInfo(m.BkBizId, m.ClusterType, m.User, rule.Dbname)
if outerErr != nil {
AddErrorOnly(&errMsg, outerErr)
continue
}
repl := accountRule
var replFlag bool
// replication slave、replication client 权限在tendbha集群下,单独处理,授权方式与其他权限不同
for _, priv := range []string{"replication slave", "replication client"} {
if strings.Contains(accountRule.GlobalPriv, priv) {
replFlag = true
accountRule.GlobalPriv = strings.Replace(accountRule.GlobalPriv, priv, "", -1)
repl.GlobalPriv = fmt.Sprintf("%s,%s", repl.GlobalPriv, priv)
}
}
if replFlag {
repl.GlobalPriv = strings.Trim(repl.GlobalPriv, ",")
accountRule.GlobalPriv = strings.Trim(accountRule.GlobalPriv, ",")
accountRule.GlobalPriv = regexp.MustCompile(`,+`).ReplaceAllString(accountRule.GlobalPriv, ",")
}
for _, dns := range m.TargetInstances {
errLimiter := limiter.Wait(context.Background())
if errLimiter != nil {
Expand Down Expand Up @@ -140,6 +156,15 @@ func (m *PrivTaskPara) AddPriv(jsonPara string, ticket string) error {
if err != nil {
errMsgInner = append(errMsgInner, err.Error())
}
if replFlag {
// 在mysql实例上授权
err = ImportBackendPrivilege(account, repl, address, proxyIPs, m.SourceIPs,
instance.ClusterType, tendbhaMasterDomain, instance.BkCloudId, false,
true)
if err != nil {
errMsgInner = append(errMsgInner, err.Error())
}
}
}
if len(errMsgInner) > 0 {
AddErrorOnly(&errMsg, errors.New(failInfo+sep+strings.Join(errMsgInner, sep)))
Expand Down Expand Up @@ -172,7 +197,13 @@ func (m *PrivTaskPara) AddPriv(jsonPara string, ticket string) error {
var spiders []Proxy
// spider在spider-master和spider-slave节点添加权限的行为是一致的,
// 通过部署时spider-slave实例只读控制实际能执行的操作
spiders = append(append(spiders, instance.SpiderMaster...), instance.SpiderSlave...)
if instance.EntryRole == masterEntry {
spiders = append(spiders, instance.SpiderMaster...)
} else if instance.EntryRole == slaveEntry {
spiders = append(spiders, instance.SpiderSlave...)
} else {
errMsgInner = append(errMsgInner, fmt.Sprintf("wrong entry role %s", instance.EntryRole))
}
for _, spider := range spiders {
address = fmt.Sprintf("%s:%d", spider.IP, spider.Port)
err = ImportBackendPrivilege(account, accountRule, address, proxyIPs, m.SourceIPs,
Expand Down
11 changes: 7 additions & 4 deletions dbm-services/mysql/db-priv/service/add_priv_base_func.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,13 @@ func GenerateBackendSQL(account TbAccounts, rule TbAccountRules, ips []string, m
sql = fmt.Sprintf("%s '%s'@'%s' %s;", insertConnLogPriv, account.User, ip, identifiedByPassword)
sqlTemp = append(sqlTemp, sql)
}
if strings.Contains(strings.ToLower(rule.GlobalPriv), "show databases") {
sql = fmt.Sprintf(`GRANT SHOW DATABASES ON *.* TO '%s'@'%s' %s;`,
account.User, ip, identifiedByPassword)
sqlTemp = append(sqlTemp, sql)
slaveAllowedPriv := []string{"show databases", "replication slave", "replication client"}
for _, priv := range slaveAllowedPriv {
if strings.Contains(strings.ToLower(rule.GlobalPriv), priv) {
sql = fmt.Sprintf(`GRANT %s ON *.* TO '%s'@'%s' %s;`,
priv, account.User, ip, identifiedByPassword)
sqlTemp = append(sqlTemp, sql)
}
}
result.mu.Lock()
result.backendSQL = append(result.backendSQL, sqlTemp...)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func CheckOrGetPassword(psw string, security SecurityRule) (string, error) {
password = psw
check := CheckPassword(security, []byte(psw))
if !check.IsStrength {
slog.Error("msg", "check", check)
return "", errno.NotMeetComplexity
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ func GetRemotePrivilege(address string, host string, bkCloudId int64, instanceTy
wg := sync.WaitGroup{}
finishChan := make(chan bool, 1)
errorChan := make(chan error, 1)
//tokenBucket := make(chan int, 50)
limit := rate.Every(time.Millisecond * 20) // QPS:50
burst := 50 // 桶容量 50
// 权限并行过高,引起实例Waiting for table metadata lock;并行过低,效率低
limit := rate.Every(time.Millisecond * 50) // QPS:20
burst := 20 // 桶容量 20
limiter := rate.NewLimiter(limit, burst)
version, errOuter = GetMySQLVersion(address, bkCloudId)
if errOuter != nil {
Expand Down
7 changes: 4 additions & 3 deletions dbm-services/mysql/db-priv/service/db_meta_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const machineTypeRemote string = "remote"
const machineTypeProxy string = "proxy"
const machineTypeSpider string = "spider"
const backendSlave string = "backend_slave"
const masterEntry = "master_entry"
const slaveEntry = "slave_entry"
const running string = "running"
const tdbctl string = "tdbctl"
const sqlserver string = "sqlserver"
Expand All @@ -28,11 +30,10 @@ const sqlserverSingle string = "sqlserver_single"
const backendMaster string = "backend_master"
const orphan string = "orphan"
const sqlserverSysDB string = "Monitor"
const mongodb string = "mongodb"

// GetAllClustersInfo TODO
// GetAllClustersInfo 获取业务下所有集群信息
/*
GetAllClustersInfo 获取业务下所有集群信息
[{
"db_module_id": 126,
"bk_biz_id": "3",
Expand Down
Loading

0 comments on commit 64d8154

Please sign in to comment.