diff --git a/dbm-services/common/go-pubpkg/errno/50000_dbpriv_code.go b/dbm-services/common/go-pubpkg/errno/50000_dbpriv_code.go index e78f343d36..f8f54d3786 100644 --- a/dbm-services/common/go-pubpkg/errno/50000_dbpriv_code.go +++ b/dbm-services/common/go-pubpkg/errno/50000_dbpriv_code.go @@ -12,6 +12,11 @@ package errno var ( // dbpriv code start 50000 + + // PasswordNotConsistent TODO + PasswordNotConsistent = Errno{Code: 51008, + Message: "user is exist,but the new password is not consistent with the old password, should be consistent", + CNMessage: "账号已存在,但是新密码与旧密码不一致,需要保持一致"} // GrantPrivilegesFail TODO GrantPrivilegesFail = Errno{Code: 51009, Message: "Grant Privileges Fail", CNMessage: "授权执行失败"} // GrantPrivilegesSuccess TODO @@ -19,6 +24,11 @@ var ( // GrantPrivilegesParameterCheckFail TODO GrantPrivilegesParameterCheckFail = Errno{Code: 51010, Message: "Parameter of Grant Privileges Check Fail", CNMessage: "授权单据的参数检查失败"} + // ErrPswNotIdentical TODO + ErrPswNotIdentical = Errno{Code: 51000, + Message: "Password is not identical to the password of existed account rules, " + + "same accounts should use same password.", + CNMessage: "密码与已存在的账号规则中的密码不同,相同账号的密码需要保持一致!"} // AccountRuleExisted TODO AccountRuleExisted = Errno{Code: 51001, Message: "Account rule of user on this db is existed ", CNMessage: "用户对此DB授权的账号规则已存在"} @@ -47,8 +57,10 @@ var ( AccountRuleNotExisted = Errno{Code: 51004, Message: "Account rule not existed ", CNMessage: "账号规则不存在"} // OnlyOneDatabaseAllowed TODO OnlyOneDatabaseAllowed = Errno{Code: 51005, - Message: "Only one database allowed, database name should not contain space", - CNMessage: "只允许填写一个数据库,数据库名称不能包含空格"} + Message: "Only one database allowed, database name should not contain space", CNMessage: "只允许填写一个数据库,数据库名称不能包含空格"} + // ErrMysqlInstanceStruct TODO + ErrMysqlInstanceStruct = Errno{Code: 51006, Message: "Not either tendbha or orphan structure", + CNMessage: "不符合tendbha或者orphan的集群结构"} // GenerateEncryptedPasswordErr TODO GenerateEncryptedPasswordErr = Errno{Code: 51007, Message: "Generate Encrypted Password Err", CNMessage: "创建账号,生成加密的密码时发生错误"} @@ -58,24 +70,11 @@ var ( ClonePrivilegesCheckFail = Errno{Code: 51014, Message: "Clone privileges check fail", CNMessage: "克隆权限检查失败"} // NoPrivilegesNothingToDo TODO NoPrivilegesNothingToDo = Errno{Code: 51015, Message: "no privileges,nothing to do", CNMessage: "没有权限需要克隆"} + // IpPortFormatError TODO + IpPortFormatError = Errno{Code: 51017, Message: "format not in 'ip:port' format", + CNMessage: "格式不是ip:port的格式"} // CloudIdRequired TODO CloudIdRequired = Errno{Code: 51019, Message: "bk_cloud_id is required", CNMessage: "bk_cloud_id不能为空"} // ClusterTypeIsEmpty TODO - ClusterTypeIsEmpty = Errno{Code: 51021, Message: "Cluster type can't be empty", - CNMessage: "cluster type不能为空"} - ModifyUserPasswordFail = Errno{Code: 51022, Message: "modify user password fail", - CNMessage: "修改用户密码失败"} - IncludeCharTypesLargerThanLength = Errno{Code: 51023, Message: "include char types larger than length", - CNMessage: "要求包含的字符类型大于字符串长度"} - TryTooManyTimes = Errno{Code: 51024, Message: "try too many times", CNMessage: "尝试太多次"} - RuleIdNull = Errno{Code: 51025, Message: "Rule ID should not be empty", - CNMessage: "安全规则的id不能为空"} - RuleNameNull = Errno{Code: 51026, Message: "Rule name should not be empty", - CNMessage: "安全规则的名称不能为空"} - RuleExisted = Errno{Code: 51027, Message: "Rule already existed ", CNMessage: "规则已存在"} - RuleNotExisted = Errno{Code: 51028, Message: "Rule not existed ", CNMessage: "规则不存在"} - NotMeetComplexity = Errno{Code: 51030, Message: "Set Passwords must meet complexity requirements", - CNMessage: "设置的密码应该符合密码复杂度"} - NameNull = Errno{Code: 51031, Message: "username should not be empty ", - CNMessage: "用户名名称不能为空"} + ClusterTypeIsEmpty = Errno{Code: 51021, Message: "Cluster type can't be empty", CNMessage: "cluster type不能为空"} ) diff --git a/dbm-services/mysql/db-partition/service/check_partition_base_func.go b/dbm-services/mysql/db-partition/service/check_partition_base_func.go index 23fcb04518..564d41411a 100644 --- a/dbm-services/mysql/db-partition/service/check_partition_base_func.go +++ b/dbm-services/mysql/db-partition/service/check_partition_base_func.go @@ -619,7 +619,7 @@ func CreatePartitionTicket(check Checker, objects []PartitionObject, zoneOffset zone := fmt.Sprintf("%+03d:00", zoneOffset) ticketType := "MYSQL_PARTITION" if check.ClusterType == Tendbcluster { - ticketType = "TENDBCLUSTER_PARTITION" + ticketType = "SPIDER_PARTITION" } ticket := Ticket{BkBizId: check.BkBizId, TicketType: ticketType, Remark: "auto partition", Details: Detail{Infos: []Info{{check.ConfigId, check.ClusterId, check.ImmuteDomain, *check.BkCloudId, objects}}}} diff --git a/dbm-services/mysql/db-priv/.gitignore b/dbm-services/mysql/db-priv/.gitignore index 13c98800f7..ecc836345a 100644 --- a/dbm-services/mysql/db-priv/.gitignore +++ b/dbm-services/mysql/db-priv/.gitignore @@ -13,5 +13,4 @@ pubkey.pem privkey.pem infile outfile -.code.yml -*.log \ No newline at end of file +.code.yml \ No newline at end of file diff --git a/dbm-services/mysql/db-priv/assests/migrations/000001_init.down.sql b/dbm-services/mysql/db-priv/assests/migrations/000001_init.down.sql.sql similarity index 100% rename from dbm-services/mysql/db-priv/assests/migrations/000001_init.down.sql rename to dbm-services/mysql/db-priv/assests/migrations/000001_init.down.sql.sql diff --git a/dbm-services/mysql/db-priv/assests/migrations/000003_init.down.sql b/dbm-services/mysql/db-priv/assests/migrations/000003_init.down.sql.sql similarity index 100% rename from dbm-services/mysql/db-priv/assests/migrations/000003_init.down.sql rename to dbm-services/mysql/db-priv/assests/migrations/000003_init.down.sql.sql diff --git a/dbm-services/mysql/db-priv/assests/migrations/000004_init.down.sql b/dbm-services/mysql/db-priv/assests/migrations/000004_init.down.sql deleted file mode 100644 index 2aa3355148..0000000000 --- a/dbm-services/mysql/db-priv/assests/migrations/000004_init.down.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE IF EXISTS tb_security_rules; -DROP TABLE IF EXISTS tb_passwords; \ No newline at end of file diff --git a/dbm-services/mysql/db-priv/assests/migrations/000004_init.up.sql b/dbm-services/mysql/db-priv/assests/migrations/000004_init.up.sql deleted file mode 100644 index a67b03a49c..0000000000 --- a/dbm-services/mysql/db-priv/assests/migrations/000004_init.up.sql +++ /dev/null @@ -1,30 +0,0 @@ -SET NAMES utf8; -CREATE TABLE IF NOT EXISTS `tb_security_rules` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(200) NOT NULL COMMENT '规则名称', - `rule` json NOT NULL COMMENT '安全规则', - `creator` varchar(800) NOT NULL COMMENT '创建者', - `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `operator` varchar(800) DEFAULT NULL COMMENT '最后一次变更者', - `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后一次变更时间', - PRIMARY KEY (`id`), - UNIQUE KEY `idx_name` (`name`)) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE IF NOT EXISTS `tb_passwords` ( - `ip` varchar(100) NOT NULL COMMENT '实例ip', - `port` int unsigned NOT NULL COMMENT '实例端口', - `password` varchar(800) NOT NULL COMMENT '加密后的密码', - `username` varchar(800) NOT NULL COMMENT '用户名称', - `lock_until` timestamp COMMENT '锁定到的时间', - `operator` varchar(800) DEFAULT NULL COMMENT '最后一次变更者', - `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后一次变更时间', - UNIQUE KEY `idx_ip_port` (ip, port, username), - KEY `idx_lock` (`lock_until`)) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -CREATE TABLE IF NOT EXISTS `tb_randomize_exclude` ( - `username` varchar(800) NOT NULL COMMENT '用户名称', - `bk_biz_id` int(11) NOT NULL COMMENT '业务的 cmdb id', - `operator` varchar(800) DEFAULT NULL COMMENT '最后一次变更者', - `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后一次变更时间', - UNIQUE KEY `idx_username_bk_biz_id` (username, bk_biz_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8; - diff --git a/dbm-services/mysql/db-priv/handler/account_rule.go b/dbm-services/mysql/db-priv/handler/account_rule.go index 2d5bb2ecde..0ab11ef29c 100644 --- a/dbm-services/mysql/db-priv/handler/account_rule.go +++ b/dbm-services/mysql/db-priv/handler/account_rule.go @@ -24,7 +24,7 @@ func (m *PrivService) GetAccountRuleList(c *gin.Context) { return } - if err = json.Unmarshal(body, &input); err != nil { + if err := json.Unmarshal(body, &input); err != nil { slog.Error("msg", err) SendResponse(c, errno.ErrBind, err) return @@ -51,14 +51,18 @@ func (m *PrivService) AddAccountRule(c *gin.Context) { return } - if err = json.Unmarshal(body, &input); err != nil { + if err := json.Unmarshal(body, &input); err != nil { slog.Error("msg", err) SendResponse(c, errno.ErrBind, err) return } err = input.AddAccountRule(string(body)) - SendResponse(c, err, nil) + if err != nil { + SendResponse(c, err, nil) + return + } + SendResponse(c, nil, nil) return } @@ -98,13 +102,17 @@ func (m *PrivService) ModifyAccountRule(c *gin.Context) { return } - if err = json.Unmarshal(body, &input); err != nil { + if err := json.Unmarshal(body, &input); err != nil { slog.Error("msg", err) SendResponse(c, errno.ErrBind, err) return } err = input.ModifyAccountRule(string(body)) - SendResponse(c, err, nil) + if err != nil { + SendResponse(c, err, nil) + return + } + SendResponse(c, nil, nil) return } diff --git a/dbm-services/mysql/db-priv/handler/admin_password.go b/dbm-services/mysql/db-priv/handler/admin_password.go deleted file mode 100644 index 673161f835..0000000000 --- a/dbm-services/mysql/db-priv/handler/admin_password.go +++ /dev/null @@ -1,81 +0,0 @@ -package handler - -import ( - "dbm-services/common/go-pubpkg/errno" - "dbm-services/mysql/priv-service/service" - "encoding/json" - "io/ioutil" - - "github.com/gin-gonic/gin" - "golang.org/x/exp/slog" -) - -// GetPassword 查询用户的密码 -func (m *PrivService) GetPassword(c *gin.Context) { - slog.Info("do GetPassword!") - var input service.GetPasswordPara - body, err := ioutil.ReadAll(c.Request.Body) - if err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - if err = json.Unmarshal(body, &input); err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - batch, err := input.GetPassword() - SendResponse(c, err, batch) - return - -} - -// ModifyPassword 新增或者修改密码 -func (m *PrivService) ModifyPassword(c *gin.Context) { - slog.Info("do ModifyMysqlAdminPassword!") - var input service.ModifyPasswordPara - body, err := ioutil.ReadAll(c.Request.Body) - if err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - if err = json.Unmarshal(body, &input); err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - err = input.ModifyPassword() - SendResponse(c, err, nil) - return -} - -// ModifyMysqlAdminPassword 新增或者修改mysql实例中管理用户的密码,可用于随机化密码 -func (m *PrivService) ModifyMysqlAdminPassword(c *gin.Context) { - slog.Info("do ModifyMysqlAdminPassword!") - var input service.ModifyAdminUserPasswordPara - - body, err := ioutil.ReadAll(c.Request.Body) - if err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - - if err = json.Unmarshal(body, &input); err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - // 随机化定时任务异步返回,避免占用资源 - if input.Async == true { - SendResponse(c, nil, nil) - } - // 前端页面调用等同步返回,返回修改成功的实例以及没有修改成功的实例 - batch, err := input.ModifyMysqlAdminPassword() - if input.Async == false { - SendResponse(c, err, batch) - } - return -} diff --git a/dbm-services/mysql/db-priv/handler/generate_random_string.go b/dbm-services/mysql/db-priv/handler/generate_random_string.go deleted file mode 100644 index d989758476..0000000000 --- a/dbm-services/mysql/db-priv/handler/generate_random_string.go +++ /dev/null @@ -1,45 +0,0 @@ -package handler - -import ( - "dbm-services/common/go-pubpkg/errno" - "dbm-services/mysql/priv-service/service" - "encoding/base64" - "encoding/json" - "io/ioutil" - - "github.com/gin-gonic/gin" - "golang.org/x/exp/slog" -) - -// GenerateRandomString 生成随机化密码 -func (m *PrivService) GenerateRandomString(c *gin.Context) { - slog.Info("do GenerateRandomString!") - var input service.GenerateRandomStringPara - body, err := ioutil.ReadAll(c.Request.Body) - if err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - - if err = json.Unmarshal(body, &input); err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - if input.SecurityRuleName == "" { - SendResponse(c, errno.RuleNameNull, nil) - return - } - // 获取安全规则 - security, err := service.GetSecurityRule(input.SecurityRuleName) - if err != nil { - slog.Error("msg", err) - SendResponse(c, errno.RuleNameNull, nil) - return - } - password, err := service.GenerateRandomString(security) - // 传输base64,因为部分字符通过url传输会转义 - SendResponse(c, err, base64.StdEncoding.EncodeToString([]byte(password))) - return -} diff --git a/dbm-services/mysql/db-priv/handler/randomize_manage.go b/dbm-services/mysql/db-priv/handler/randomize_manage.go deleted file mode 100644 index a50246d826..0000000000 --- a/dbm-services/mysql/db-priv/handler/randomize_manage.go +++ /dev/null @@ -1,56 +0,0 @@ -package handler - -import ( - "dbm-services/common/go-pubpkg/errno" - "dbm-services/mysql/priv-service/service" - "encoding/json" - "io/ioutil" - - "github.com/gin-gonic/gin" - "golang.org/x/exp/slog" -) - -// GetRandomExclude 获取不参加随机化的业务 -func (m *PrivService) GetRandomExclude(c *gin.Context) { - slog.Info("do GetRandomExclude!") - var input service.RandomExcludePara - body, err := ioutil.ReadAll(c.Request.Body) - if err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - - if err = json.Unmarshal(body, &input); err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - // 获取不参加随机化的业务 - exclude, err := input.GetRandomizeExclude() - SendResponse(c, err, exclude) - return -} - -// ModifyRandomExclude 修改不参与随机化的业务 -func (m *PrivService) ModifyRandomExclude(c *gin.Context) { - slog.Info("do ModifyRandomExclude!") - var input service.RandomExcludePara - - body, err := ioutil.ReadAll(c.Request.Body) - if err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - - if err = json.Unmarshal(body, &input); err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - // 传入的业务列表替换当前业务列表 - err = input.ModifyRandomizeExclude(string(body)) - SendResponse(c, err, nil) - return -} diff --git a/dbm-services/mysql/db-priv/handler/register_routes.go b/dbm-services/mysql/db-priv/handler/register_routes.go index 03671d74e0..0d9252e239 100644 --- a/dbm-services/mysql/db-priv/handler/register_routes.go +++ b/dbm-services/mysql/db-priv/handler/register_routes.go @@ -46,26 +46,6 @@ func (m *PrivService) Routes() []*gin.RouteInfo { // 获取公钥,用于传输过程中加密密码 {Method: http.MethodPost, Path: "pub_key", HandlerFunc: m.GetPubKey}, - - // 修改实例中指定用户的密码 - {Method: http.MethodPost, Path: "modify_mysql_admin_password", HandlerFunc: m.ModifyMysqlAdminPassword}, - // 查询密码 - {Method: http.MethodPost, Path: "get_password", HandlerFunc: m.GetPassword}, - // 修改密码 - {Method: http.MethodPost, Path: "modify_password", HandlerFunc: m.ModifyPassword}, - - // 生成随机字符串 - {Method: http.MethodPost, Path: "get_random_string", HandlerFunc: m.GenerateRandomString}, - - // 安全规则 - {Method: http.MethodPost, Path: "get_security_rule", HandlerFunc: m.GetSecurityRule}, - {Method: http.MethodPost, Path: "add_security_rule", HandlerFunc: m.AddSecurityRule}, - {Method: http.MethodPost, Path: "modify_security_rule", HandlerFunc: m.ModifySecurityRule}, - {Method: http.MethodPost, Path: "delete_security_rule", HandlerFunc: m.DeleteSecurityRule}, - - // 不参与随机化的业务 - {Method: http.MethodPost, Path: "get_randomize_exclude", HandlerFunc: m.GetRandomExclude}, - {Method: http.MethodPost, Path: "modify_randomize_exclude", HandlerFunc: m.ModifyRandomExclude}, } } diff --git a/dbm-services/mysql/db-priv/handler/security_rule.go b/dbm-services/mysql/db-priv/handler/security_rule.go deleted file mode 100644 index fa7c73fbba..0000000000 --- a/dbm-services/mysql/db-priv/handler/security_rule.go +++ /dev/null @@ -1,107 +0,0 @@ -package handler - -import ( - "encoding/json" - "io/ioutil" - - "dbm-services/common/go-pubpkg/errno" - "dbm-services/mysql/priv-service/service" - - "github.com/gin-gonic/gin" - "golang.org/x/exp/slog" -) - -// GetSecurityRule 获取安全规则 -func (m *PrivService) GetSecurityRule(c *gin.Context) { - slog.Info("do GetSecurityRule!") - - var input service.SecurityRulePara - - body, err := ioutil.ReadAll(c.Request.Body) - if err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - - if err = json.Unmarshal(body, &input); err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - // 根据名称查询安全规则 - security, err := input.GetSecurityRule() - SendResponse(c, err, security) - return -} - -// AddSecurityRule 添加安全规则 -func (m *PrivService) AddSecurityRule(c *gin.Context) { - - slog.Info("do AddSecurityRule!") - var input service.SecurityRulePara - - body, err := ioutil.ReadAll(c.Request.Body) - if err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - - if err = json.Unmarshal(body, &input); err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - // 添加安全规则,安全规则主要用于生成密码和检验密码复杂度 - err = input.AddSecurityRule(string(body)) - SendResponse(c, err, nil) - return -} - -// DeleteSecurityRule 删除安全规则 -func (m *PrivService) DeleteSecurityRule(c *gin.Context) { - slog.Info("do DeleteSecurityRule!") - - var input service.SecurityRulePara - - body, err := ioutil.ReadAll(c.Request.Body) - if err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - - if err = json.Unmarshal(body, &input); err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - // 根据id删除安全规则 - err = input.DeleteSecurityRule(string(body)) - SendResponse(c, err, nil) - return -} - -// ModifySecurityRule 修改安全规则,修改安全规则的名称和内容 -func (m *PrivService) ModifySecurityRule(c *gin.Context) { - slog.Info("do ModifySecurityRule!") - var input service.SecurityRulePara - - body, err := ioutil.ReadAll(c.Request.Body) - if err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - - if err = json.Unmarshal(body, &input); err != nil { - slog.Error("msg", err) - SendResponse(c, errno.ErrBind, err) - return - } - // 根据id,修改安全规则,修改安全规则的名称和内容 - err = input.ModifySecurityRule(string(body)) - SendResponse(c, err, nil) - return -} diff --git a/dbm-services/mysql/db-priv/service/accout_rule.go b/dbm-services/mysql/db-priv/service/accout_rule.go index 591fa76280..1aa29b5e77 100644 --- a/dbm-services/mysql/db-priv/service/accout_rule.go +++ b/dbm-services/mysql/db-priv/service/accout_rule.go @@ -5,8 +5,6 @@ import ( "fmt" "strings" - "golang.org/x/exp/slog" - "dbm-services/common/go-pubpkg/errno" "dbm-services/mysql/priv-service/util" @@ -22,10 +20,6 @@ func (m *BkBizId) QueryAccountRule() ([]*AccountRuleSplitUser, int64, error) { count int64 result *gorm.DB err error - rulesWhere string - accountsWhere string - ruleIds string - accountIds string ) if m.BkBizId == 0 { return nil, count, errno.BkBizIdIsEmpty @@ -35,50 +29,15 @@ func (m *BkBizId) QueryAccountRule() ([]*AccountRuleSplitUser, int64, error) { m.ClusterType = &ct // return nil, count, errno.ClusterTypeIsEmpty } - - if len(m.RuleIds) > 0 { - var acountList []*AccountId - for _, id := range m.RuleIds { - ruleIds = fmt.Sprintf("%d,%s", id, ruleIds) - } - ruleIds = strings.TrimRight(ruleIds, ",") - rulesWhere = fmt.Sprintf("bk_biz_id=%d and cluster_type='%s' and id in (%s)", - m.BkBizId, *m.ClusterType, ruleIds) - err = DB.Self.Model(&TbAccountRules{}).Where(rulesWhere). - Select("distinct(account_id) as account_id").Scan(&acountList).Error - if err != nil { - return nil, count, err - } - for _, id := range acountList { - accountIds = fmt.Sprintf("%d,%s", id.AccountId, accountIds) - } - accountIds = strings.TrimRight(accountIds, ",") - slog.Info("msg", "accountIds", accountIds) - accountsWhere = fmt.Sprintf("bk_biz_id=%d and cluster_type='%s' and id in (%s)", - m.BkBizId, *m.ClusterType, accountIds) - slog.Info("msg", "accountsWhere", accountsWhere) - err = DB.Self.Model(&TbAccounts{}).Where(accountsWhere).Select( - "id,bk_biz_id,user,creator,create_time").Scan(&accounts).Error - if err != nil { - return nil, count, err - } - } else { - err = DB.Self.Model(&TbAccounts{}).Where(&TbAccounts{BkBizId: m.BkBizId, ClusterType: *m.ClusterType}).Select( - "id,bk_biz_id,user,creator,create_time").Scan(&accounts).Error - if err != nil { - return nil, count, err - } + err = DB.Self.Model(&TbAccounts{}).Where(&TbAccounts{BkBizId: m.BkBizId, ClusterType: *m.ClusterType}).Select( + "id,bk_biz_id,user,creator,create_time").Scan(&accounts).Error + if err != nil { + return nil, count, err } accountRuleSplitUser = make([]*AccountRuleSplitUser, len(accounts)) for k, v := range accounts { - where := fmt.Sprintf("bk_biz_id=%d and cluster_type='%s' and account_id=%d ", - m.BkBizId, *m.ClusterType, (*v).Id) - slog.Info("msg", "where", where) - if len(m.RuleIds) > 0 { - where = fmt.Sprintf("%s and id in (%s)", where, ruleIds) - slog.Info("msg", "where", where) - } - result = DB.Self.Model(&TbAccountRules{}).Where(where). + result = DB.Self.Model(&TbAccountRules{}).Where(&TbAccountRules{BkBizId: m.BkBizId, AccountId: (*v).Id, + ClusterType: *m.ClusterType}). Select("id,account_id,bk_biz_id,dbname,priv,creator,create_time").Scan(&rules) accountRuleSplitUser[k] = &AccountRuleSplitUser{Account: v, Rules: rules} if err != nil { @@ -145,10 +104,8 @@ func (m *AccountRulePara) AddAccountRule(jsonPara string) error { return err } } - err = tx.Commit().Error - if err != nil { - return err - } + tx.Commit() + log := PrivLog{BkBizId: m.BkBizId, Operator: m.Operator, Para: jsonPara, Time: insertTime} AddPrivLog(log) @@ -268,6 +225,7 @@ func (m *DeleteAccountRuleById) DeleteAccountRule(jsonPara string) error { for k, v := range m.Id { temp[k] = fmt.Sprintf("%d", v) } + sql := fmt.Sprintf("delete from tb_account_rules where id in (%s) and bk_biz_id = %d and cluster_type = '%s'", strings.Join(temp, ","), m.BkBizId, *m.ClusterType) result := DB.Self.Exec(sql) diff --git a/dbm-services/mysql/db-priv/service/accout_rule_object.go b/dbm-services/mysql/db-priv/service/accout_rule_object.go index ff909448d4..cf67268fe1 100644 --- a/dbm-services/mysql/db-priv/service/accout_rule_object.go +++ b/dbm-services/mysql/db-priv/service/accout_rule_object.go @@ -20,10 +20,6 @@ type TbAccountRules struct { UpdateTime util.TimeFormat `gorm:"column:update_time" json:"update_time"` } -type AccountId struct { - AccountId int64 `gorm:"column:account_id;not_null" json:"account_id"` -} - // Rule 账号规则表中需要在前端展示的字段 type Rule struct { Id int64 `gorm:"column:id;primary_key;auto_increment" json:"id"` diff --git a/dbm-services/mysql/db-priv/service/add_priv_object.go b/dbm-services/mysql/db-priv/service/add_priv_object.go index 9b40171936..eec7b5eb92 100644 --- a/dbm-services/mysql/db-priv/service/add_priv_object.go +++ b/dbm-services/mysql/db-priv/service/add_priv_object.go @@ -85,7 +85,6 @@ type Domain struct { // BkBizId QueryAccountRule 函数的入参 type BkBizId struct { BkBizId int64 `json:"bk_biz_id" url:"bk_biz_id"` - RuleIds []int64 `json:"ids" url:"ids"` ClusterType *string `json:"cluster_type" url:"cluster_type"` } diff --git a/dbm-services/mysql/db-priv/service/admin_password.go b/dbm-services/mysql/db-priv/service/admin_password.go deleted file mode 100644 index 3668568978..0000000000 --- a/dbm-services/mysql/db-priv/service/admin_password.go +++ /dev/null @@ -1,259 +0,0 @@ -package service - -import ( - "dbm-services/common/go-pubpkg/errno" - "encoding/base64" - "fmt" - "strings" - "sync" - - "golang.org/x/exp/slog" -) - -// GetPassword 查询密码 -func (m *GetPasswordPara) GetPassword() ([]*TbPasswords, error) { - var passwords []*TbPasswords - if m.UserName == nil { - return passwords, errno.ErrUserIsEmpty - } - where := fmt.Sprintf(" username='%s' ", *m.UserName) - var filter []string - for _, item := range m.Instances { - filter = append(filter, fmt.Sprintf("(ip='%s' and port=%d)", item.Ip, item.Port)) - } - filters := strings.Join(filter, " or ") - if filters != "" { - where = fmt.Sprintf(" %s and %s ", where, filters) - } - // mysql实例中ADMIN用户的密码,仅能查看人为修改密码且在有效期的密码,不可以查看随机化生成的密码 - if *m.UserName == "ADMIN" { - where = fmt.Sprintf(" %s and lock_until is not null", where) - } - err := DB.Self.Model(&TbPasswords{}).Where(where).Scan(&passwords).Error - if err != nil { - return passwords, err - } - err = DecodePassword(passwords) - if err != nil { - return passwords, err - } - return passwords, nil -} - -// ModifyPassword 修改tb_passwords表中密码 -func (m *ModifyPasswordPara) ModifyPassword() error { - if m.UserName == nil { - return errno.ErrUserIsEmpty - } - var psw, encrypt string - var security SecurityRule - plain, err := base64.StdEncoding.DecodeString(m.Psw) - if err != nil { - slog.Error("msg", "base64 decode error", err) - return err - } - m.Psw = string(plain) - if m.SecurityRuleName != "" { - security, err = GetSecurityRule(m.SecurityRuleName) - if err != nil { - slog.Error("msg", "GetSecurityRule", err) - return err - } - psw, err = CheckOrGetPassword(m.Psw, security) - if err != nil { - slog.Error("msg", "CheckOrGetPassword", err) - return err - } - } else { - if m.Psw == "" { - return errno.RuleNameNull - } else { - psw = m.Psw - } - } - encrypt, err = SM4Encrypt(psw) - tx := DB.Self.Begin() - for _, address := range m.Instances { - // 更新tb_passwords中实例的密码 - sql := fmt.Sprintf("replace into tb_passwords(ip,port,password,username,operator) values('%s',%d,'%s','%s','%s')", - address.Ip, address.Port, encrypt, *m.UserName, m.Operator) - err = tx.Debug().Exec(sql).Error - if err != nil { - slog.Error("msg", sql, err) - tx.Rollback() - return err - } - } - err = tx.Commit().Error - if err != nil { - return err - } - return nil -} - -// ModifyMysqlAdminPassword 修改mysql实例中用户的密码,可用于随机化密码 -func (m *ModifyAdminUserPasswordPara) ModifyMysqlAdminPassword() (BatchResult, error) { - var errMsg Err - var success Resource - var fail Resource - var batch BatchResult - var wg sync.WaitGroup - var security SecurityRule - var passwordInput string - var errCheck error - tokenBucket := make(chan int, 10) - - // 后台定时任务,1、randmize_daily比如每天执行一次,随机化没有被锁住的实例 2、randmize_expired比如每分钟执行一次随机化锁定过期的实例 - // 前台页面,单据已提示实例密码被锁定是否修改,用户确认修改,因此不检查是否锁定 - if m.Async && m.Range == "randmize_expired" { - errCheck = m.NeedToBeRandomized() - if errCheck != nil { - return batch, errCheck - } - } else if m.Async && m.Range == "randmize_daily" { - errCheck = m.RemoveLockedInstances() - if errCheck != nil { - return batch, errCheck - } - } else if m.Async { - return batch, fmt.Errorf("[ %s ] not supported randmize range", m.Range) - } - - if m.UserName == nil { - return batch, errno.ErrUserIsEmpty - } - - plain, errCheck := base64.StdEncoding.DecodeString(m.Psw) - if errCheck != nil { - slog.Error("msg", "base64 decode error", errCheck) - return batch, errCheck - } - m.Psw = string(plain) - - // 传入安全规则,1、如果传入密码,根据安全规则校验密码复杂度,2、如果没有传入密码,根据安全规则随机生成密码 - // 不允许没有不传入安全规则,并且不传入密码 - if m.SecurityRuleName != "" { - security, errCheck = GetSecurityRule(m.SecurityRuleName) - if errCheck != nil { - slog.Error("msg", "GetSecurityRule", errCheck) - return batch, errCheck - } - if m.Psw != "" { - passwordInput, errCheck = CheckOrGetPassword(m.Psw, security) - if errCheck != nil { - slog.Error("msg", "CheckOrGetPassword", errCheck) - return batch, errCheck - } - } - } else { - if m.Psw == "" { - return batch, errno.RuleNameNull - } else { - passwordInput = m.Psw - } - } - - for _, cluster := range m.Clusters { - if cluster.BkCloudId == nil { - return batch, errno.CloudIdRequired - } - if cluster.ClusterType == nil { - return batch, errno.ClusterTypeIsEmpty - } - var psw, encrypt string - var errOuter error - if passwordInput == "" { - psw, errOuter = CheckOrGetPassword("", security) - if errOuter != nil { - slog.Error("msg", "CheckOrGetPassword", errOuter) - return batch, errOuter - } - } else { - psw = passwordInput - } - // 加密 - encrypt, errOuter = SM4Encrypt(psw) - if errOuter != nil { - slog.Error("SM4Encrypt", "error", errOuter) - return batch, errOuter - } - for _, instanceList := range cluster.MultiRoleInstanceLists { - var base []string - role := instanceList.Role - if *cluster.ClusterType == tendbcluster && role == machineTypeSpider { - base = append(base, flushPriv, setBinlogOff, setDdlByCtlOFF) - } else if *cluster.ClusterType == tendbcluster && role == tdbctl { - base = append(base, flushPriv, setBinlogOff, setTcAdminOFF) - } else { - base = append(base, flushPriv, setBinlogOff) - } - for _, address := range instanceList.Addresses { - wg.Add(1) - tokenBucket <- 0 - go func(base []string, role, psw, encrypt string, address Address, cluster OneCluster) { - defer func() { - <-tokenBucket - wg.Done() - }() - // 获取修改密码的语句 - sqls := base - hostPort := fmt.Sprintf("%s:%d", address.Ip, address.Port) - mysqlVersion, err := GetMySQLVersion(hostPort, *cluster.BkCloudId) - if err != nil { - slog.Error("mysqlVersion", err) - AddError(&errMsg, hostPort, err) - return - } - userLocalhost := fmt.Sprintf("GRANT ALL PRIVILEGES ON *.* TO '%s'@'localhost' "+ - "IDENTIFIED BY '%s' WITH GRANT OPTION", *m.UserName, psw) - userIp := fmt.Sprintf("GRANT ALL PRIVILEGES ON *.* TO '%s'@'%s' "+ - "IDENTIFIED BY '%s' WITH GRANT OPTION", *m.UserName, address.Ip, psw) - if !(*cluster.ClusterType == tendbcluster && role == machineTypeSpider) && - MySQLVersionParse(mysqlVersion, "") >= - MySQLVersionParse("8.0.0", "") { - userLocalhost = fmt.Sprintf("ALTER USER '%s'@'localhost' "+ - "IDENTIFIED WITH mysql_native_password BY '%s'", *m.UserName, psw) - userIp = fmt.Sprintf("ALTER USER '%s'@'%s' "+ - "IDENTIFIED WITH mysql_native_password BY '%s'", *m.UserName, address.Ip, psw) - } - sqls = append(sqls, userLocalhost, userIp, setBinlogOn, flushPriv) - // 到实例更新密码 - var queryRequest = QueryRequest{[]string{hostPort}, sqls, true, 60, *cluster.BkCloudId} - _, err = OneAddressExecuteSql(queryRequest) - if err != nil { - AddResource(&fail, address) - slog.Error("OneAddressExecuteSql", err) - AddError(&errMsg, hostPort, err) - return - } - // 更新tb_passwords中实例的密码 - sql := fmt.Sprintf("replace into tb_passwords(ip,port,password,username,operator) "+ - "values('%s',%d,'%s','ADMIN','%s')", - address.Ip, address.Port, encrypt, m.Operator) - if m.LockUntil != "" { - sql = fmt.Sprintf("replace into tb_passwords(ip,port,password,username,"+ - "operator,lock_until) values('%s',%d,'%s','ADMIN','%s','%s')", - address.Ip, address.Port, encrypt, m.Operator, m.LockUntil) - } - result := DB.Self.Exec(sql) - if result.Error != nil { - AddResource(&fail, address) - AddError(&errMsg, hostPort, result.Error) - return - } - AddResource(&success, address) - return - }(base, role, psw, encrypt, address, cluster) - } - } - } - wg.Wait() - close(tokenBucket) - // 随机化成功的实例以及随机化失败的实例 - batch = BatchResult{Success: success.resources, Fail: fail.resources} - if len(errMsg.errs) > 0 { - errOuter := errno.ModifyUserPasswordFail.Add("\n" + strings.Join(errMsg.errs, "\n")) - return batch, errOuter - } - return batch, nil -} diff --git a/dbm-services/mysql/db-priv/service/admin_password_base_func.go b/dbm-services/mysql/db-priv/service/admin_password_base_func.go deleted file mode 100644 index ddfd1d9430..0000000000 --- a/dbm-services/mysql/db-priv/service/admin_password_base_func.go +++ /dev/null @@ -1,235 +0,0 @@ -package service - -import ( - "dbm-services/common/go-pubpkg/errno" - "dbm-services/mysql/priv-service/util" - "encoding/base64" - "encoding/hex" - "encoding/json" - "fmt" - "io/ioutil" - "math/rand" - "os" - "time" - - "github.com/spf13/viper" - "golang.org/x/exp/slog" -) - -func CheckOrGetPassword(psw string, security SecurityRule) (string, error) { - // 密码为空,根据security生成随机密码 - // 密码不为空,根据security检查密码复杂度,security为空则不检查负责度(迁移密码无法修改,且密码复杂度不足的情况) - var password string - var err error - if psw != "" { - password = psw - // 密码长度检查 - lenOk := len(psw) >= security.MinLength && len(psw) <= security.MaxLength - // 密码不可连续的字符规则、不可重复的字符规则 检查 - repeatOk := security.ExcludeContinuousRule.Repeats && CheckContinuousRepeats( - psw, security.ExcludeContinuousRule.Limit) || - security.ExcludeContinuousRule.Repeats == false - if !(CheckExcludeContinuousRule(psw, security.ExcludeContinuousRule) && repeatOk && lenOk) { - slog.Error("msg", "NotMeetComplexity", security) - return "", errno.NotMeetComplexity - } - } else { - // 没有传入密码,按照密码复杂度随机生成密码 - password, err = GenerateRandomString(security) - if err != nil { - slog.Error("GenerateRandomString", "error", err) - return "", err - } - } - return password, nil -} - -func GetSecurityRule(securityName string) (SecurityRule, error) { - var security SecurityRule - rule, err := (&SecurityRulePara{Name: securityName}).GetSecurityRule() - if err != nil { - slog.Error("msg", "GetSecurityRule", err) - return security, err - } - err = json.Unmarshal([]byte((*rule).Rule), &security) - if err != nil { - slog.Error("msg", "unmarshal error", err) - return security, err - } - return security, nil -} - -// RemoveLockedInstances 日常随机化剔除锁定的实例 -func (m *ModifyAdminUserPasswordPara) RemoveLockedInstances() error { - var locked []*Address - var clusters []OneCluster - err := DB.Self.Model(&TbPasswords{}).Where("lock_until is not null").Select("ip,port").Scan(&locked).Error - if err != nil { - slog.Error("msg", "get locked instances error", err) - return err - } - if len(locked) == 0 { - return nil - } - for _, cluster := range m.Clusters { - var roles []InstanceList - for _, role := range cluster.MultiRoleInstanceLists { - var addresses []Address - for _, address := range role.Addresses { - for k, lock := range locked { - if address.Ip == lock.Ip && address.Port == lock.Port { - break - } - if k == len(locked)-1 { - addresses = append(addresses, address) - } - } - } - if len(addresses) > 0 { - roles = append(roles, InstanceList{role.Role, addresses}) - } - } - if len(roles) > 0 { - clusters = append(clusters, OneCluster{cluster.BkCloudId, cluster.ClusterType, roles}) - } - } - m.Clusters = clusters - return nil -} - -// NeedToBeRandomized 锁定到期的实例实例随机化 -func (m *ModifyAdminUserPasswordPara) NeedToBeRandomized() error { - var needs []*Address - var clusters []OneCluster - err := DB.Self.Model(&TbPasswords{}).Where("lock_until <= now()").Select("ip,port").Scan(&needs).Error - if err != nil { - slog.Error("msg", "get locked instances error", err) - return err - } - for _, cluster := range m.Clusters { - var roles []InstanceList - for _, role := range cluster.MultiRoleInstanceLists { - var addresses []Address - for _, address := range role.Addresses { - for _, need := range needs { - if address.Ip == need.Ip && address.Port == need.Port { - addresses = append(addresses, address) - break - } - } - } - if len(addresses) > 0 { - roles = append(roles, InstanceList{role.Role, addresses}) - } - } - if len(roles) > 0 { - clusters = append(clusters, OneCluster{cluster.BkCloudId, cluster.ClusterType, roles}) - } - } - m.Clusters = clusters - return nil -} - -func DecodePassword(slice []*TbPasswords) error { - pswList := UniquePassword(slice) - pswMap := make(map[string]string, len(pswList)) - for _, item := range pswList { - // 避免在写入和读取数据库时乱码,存储hex进制 - bytes, err := hex.DecodeString(item) - if err != nil { - slog.Error("msg", "get hex decode error", err) - return err - } - pswMap[item], err = SM4Decrypt(string(bytes)) - if err != nil { - slog.Error("msg", "SM4Decrypt error", err) - return err - } - } - for k, lock := range slice { - slice[k].Password = pswMap[lock.Password] - } - return nil -} - -// SM4Encrypt 加密 -func SM4Encrypt(input string) (string, error) { - output, err := SM4(input, "encrypt") - if err != nil { - slog.Error("msg", "SM4Encrypt", err) - return "", err - } - return hex.EncodeToString(output), nil -} - -// SM4Decrypt 解密 -func SM4Decrypt(input string) (string, error) { - output, err := SM4(input, "decrypt") - if err != nil { - slog.Error("msg", "SM4Decrypt", err) - return "", err - } - return base64.StdEncoding.EncodeToString(output), nil -} - -// SM4 加密方式 -func SM4(input string, vtype string) ([]byte, error) { - rand.Seed(time.Now().UnixNano()) - r := rand.Intn(1000) - name := fmt.Sprintf("%d%03d", time.Now().UnixNano()/1e6, r) - inputName := fmt.Sprintf("%s.input", name) - outputName := fmt.Sprintf("%s.output", name) - //由于部分特殊字符可能导致命令行执行会失败,存入文件后解密或者机密 - //cmd := fmt.Sprintf(`echo -n '%s' | openssl enc -e -sm4-ctr -pbkdf2 -k %s`, plain, viper.GetString("bk_app_secret")) - //cmd := fmt.Sprintf(`echo -n '%s' | openssl enc -d -sm4-ctr -pbkdf2 -k %s`, cipher, viper.GetString("bk_app_secret")) - _, err := os.Stat(inputName) - if err == nil || !os.IsNotExist(err) { - slog.Error("msg", "check file exist", os.ErrExist) - return nil, os.ErrExist - } - inputFile, err := os.OpenFile(inputName, os.O_CREATE|os.O_RDWR, 0644) - if err != nil { - slog.Error("msg", "file", inputName, "create file error", err) - return nil, err - } - defer func() { - inputFile.Close() - _ = os.Remove(inputName) - _ = os.Remove(outputName) - }() - if _, err = inputFile.Write([]byte(input)); err != nil { - slog.Error("msg", "file", inputName, "write file error") - return nil, err - } - cmd := fmt.Sprintf(`openssl enc -in %s -out %s -sm4-ctr -pbkdf2 -k %s`, inputName, outputName, - viper.GetString("bk_app_secret")) - if vtype == "encrypt" { - cmd = fmt.Sprintf("%s -e ", cmd) - } else if vtype == "decrypt" { - cmd = fmt.Sprintf("%s -d ", cmd) - } - _, err = util.ExecShellCommand(false, cmd) - if err != nil { - slog.Error("msg", "exec command error", err) - return nil, err - } - output, err := ioutil.ReadFile(outputName) - if err != nil { - slog.Error("msg", "file", outputName, "read file error", err) - return nil, err - } - return output, nil -} - -// UniquePassword 获取distinct的数据 -func UniquePassword(slice []*TbPasswords) []string { - res := make([]string, 0) - mp := make(map[string]bool, len(slice)) - for _, e := range slice { - if mp[e.Password] == false { - mp[e.Password] = true - res = append(res, e.Password) - } - } - return res -} diff --git a/dbm-services/mysql/db-priv/service/admin_password_object.go b/dbm-services/mysql/db-priv/service/admin_password_object.go deleted file mode 100644 index 11df274b7c..0000000000 --- a/dbm-services/mysql/db-priv/service/admin_password_object.go +++ /dev/null @@ -1,73 +0,0 @@ -package service - -import "dbm-services/mysql/priv-service/util" - -// ModifyAdminUserPasswordPara 函数的入参 -type ModifyAdminUserPasswordPara struct { - UserName *string `json:"username"` - Psw string `json:"password"` - LockUntil util.TimeFormat `json:"lock_until"` - Operator string `json:"operator"` - Clusters []OneCluster `json:"clusters"` - SecurityRuleName string `json:"security_rule_name"` - Range string `json:"range"` - Async bool `json:"async"` // 是否异步的方式执行 -} - -// ModifyPasswordPara 函数的入参 -type ModifyPasswordPara struct { - UserName *string `json:"username"` - Psw string `json:"password"` - Operator string `json:"operator"` - Instances []Address `json:"instances"` - SecurityRuleName string `json:"security_rule_name"` -} - -// GetPasswordPara 函数的入参 -type GetPasswordPara struct { - Instances []Address `json:"instances"` - UserName *string `json:"username"` -} - -type TbPasswords struct { - Id int64 `gorm:"column:id;primary_key;auto_increment" json:"id"` - Ip string `gorm:"column:ip;not_null" json:"ip"` - Port int64 `gorm:"column:port;not_null" json:"port"` - Password string `gorm:"column:password;not_null" json:"password"` - UserName string `gorm:"column:username;not_null" json:"username"` - LockUntil util.TimeFormat `gorm:"column:lock_until" json:"lock_until"` - Operator string `gorm:"column:operator" json:"operator"` - UpdateTime util.TimeFormat `gorm:"column:update_time" json:"update_time"` -} - -type OneCluster struct { - BkCloudId *int64 `json:"bk_cloud_id"` - ClusterType *string `json:"cluster_type"` - MultiRoleInstanceLists []InstanceList `json:"instances"` -} - -type InstanceList struct { - // 对于修改密码的接口,仅当集群为tendbcluster类型,需要再根据role判断实施方式 - // Role用于区分spider、tdbctl、remote - Role string `json:"role"` - Addresses []Address `json:"addresses"` -} - -type Address struct { - Ip string `gorm:"column:ip" json:"ip"` - Port int64 `gorm:"column:port" json:"port"` -} - -type BatchResult struct { - Success []Address `json:"success"` - Fail []Address `json:"fail"` -} - -type AdminPasswordResp struct { - Locked []*TbPasswords `json:"locked"` - Unlocked []*TbPasswords `json:"unlocked"` -} - -type Password struct { - Password string `gorm:"column:password;not_null" json:"password"` -} diff --git a/dbm-services/mysql/db-priv/service/clone_client_priv_base_func.go b/dbm-services/mysql/db-priv/service/clone_client_priv_base_func.go index ff7347cca2..691ea657f0 100644 --- a/dbm-services/mysql/db-priv/service/clone_client_priv_base_func.go +++ b/dbm-services/mysql/db-priv/service/clone_client_priv_base_func.go @@ -166,10 +166,3 @@ func AddErrorOnly(errMsg *Err, err error) { errMsg.errs = append(errMsg.errs, err.Error()) errMsg.mu.Unlock() } - -// AddResource 并行时构建数组 -func AddResource(resources *Resource, resource Address) { - resources.mu.Lock() - resources.resources = append(resources.resources, resource) - resources.mu.Unlock() -} diff --git a/dbm-services/mysql/db-priv/service/clone_client_priv_object.go b/dbm-services/mysql/db-priv/service/clone_client_priv_object.go index 825cf94054..8ae86f2e7a 100644 --- a/dbm-services/mysql/db-priv/service/clone_client_priv_object.go +++ b/dbm-services/mysql/db-priv/service/clone_client_priv_object.go @@ -40,9 +40,3 @@ type Err struct { mu sync.RWMutex errs []string } - -// Resource 并行时共同维护数组 -type Resource struct { - mu sync.RWMutex - resources []Address -} diff --git a/dbm-services/mysql/db-priv/service/generate_random_string.go b/dbm-services/mysql/db-priv/service/generate_random_string.go deleted file mode 100644 index 40d3f4a42c..0000000000 --- a/dbm-services/mysql/db-priv/service/generate_random_string.go +++ /dev/null @@ -1,173 +0,0 @@ -package service - -import ( - "dbm-services/common/go-pubpkg/errno" - "fmt" - "math" - "math/rand" - "strings" - "time" - - "golang.org/x/exp/slog" -) - -const lowercase = "abcdefghijklmnopqrstuvwxyz" -const uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" -const number = "0123456789" -const symbol = `!#$%&()*+,-./:;<=>?@[\]^_{|}~` - -// 为密码池添加连续的字母序,数字序,特殊字符序和键盘序 -const continuousSymbols = "~!@#$%^&*()_+" - -var continuousKeyboardCol = []string{"1qaz", "2wsx", "3edc", "4rfv", "5tgb", "6yhn", "7ujm", "8ik,", "9ol.", "0p;/"} -var continuousKeyboardRow = []string{"qwertyuiop[]\\", "asdfghjkl;'", "zxcvbnm,./"} - -// GenerateRandomStringPara 生成随机字符串的函数的入参 -type GenerateRandomStringPara struct { - SecurityRuleName string `json:"security_rule_name"` -} - -func GenerateRandomString(security SecurityRule) (string, error) { - length := rand.Intn(security.MaxLength-security.MinLength) + security.MinLength - var str []byte - // 字母与数字占比90%,符号占比10% - alphabetNumberStr := fmt.Sprintf("%s%s%s", lowercase, uppercase, number) - alphabetNumberPercent := 0.9 - rand.Seed(time.Now().UnixNano()) - // 必须包含的字符,至少有一个 - if security.IncludeRule.Lowercase { - index := rand.Intn(len(lowercase)) - str = append(str, lowercase[index]) - } - if security.IncludeRule.Uppercase { - index := rand.Intn(len(uppercase)) - str = append(str, uppercase[index]) - } - if security.IncludeRule.Symbols { - index := rand.Intn(len(symbol)) - str = append(str, symbol[index]) - } - if security.IncludeRule.Numbers { - index := rand.Intn(len(number)) - str = append(str, number[index]) - } - if len(str) > security.MinLength { - return string(str), errno.IncludeCharTypesLargerThanLength - } - remain := length - len(str) - if remain <= 0 { - return string(str), nil - } - alphabetNumberCnt := int(math.Ceil(alphabetNumberPercent * float64(remain))) - symbolCnt := remain - alphabetNumberCnt - //遍历,生成一个随机index索引 - for i := 0; i < alphabetNumberCnt; i++ { - index := rand.Intn(len(alphabetNumberStr)) - str = append(str, alphabetNumberStr[index]) - } - for i := 0; i < symbolCnt; i++ { - index := rand.Intn(len(symbol)) - str = append(str, symbol[index]) - } - for i := 0; i < 10; i++ { - RandShuffle(&str) - repeatOk := security.ExcludeContinuousRule.Repeats && - CheckContinuousRepeats(string(str), security.ExcludeContinuousRule.Limit) || - security.ExcludeContinuousRule.Repeats == false - // 连续规则以及重复规则不通过,打乱顺序 - if CheckExcludeContinuousRule(string(str), security.ExcludeContinuousRule) && repeatOk { - return string(str), nil - } - } - slog.Error("error", errno.TryTooManyTimes.AddBefore("GenerateRandomString")) - return "", errno.TryTooManyTimes.AddBefore("GenerateRandomString") -} - -// RandShuffle 随机打乱字符串中的字符顺序 -func RandShuffle(slice *[]byte) { - r := rand.New(rand.NewSource(time.Now().UnixNano())) - r.Shuffle(len(*slice), func(i, j int) { - (*slice)[i], (*slice)[j] = (*slice)[j], (*slice)[i] - }) -} - -// CheckExcludeContinuousRule 检查密码不允许连续N位出现某个规则 -func CheckExcludeContinuousRule(str string, rule ExcludeContinuousRule) bool { - str = strings.ToLower(str) - // 连续的符号或者数字或者字母 - if rule.Symbols { - _, cnt := FindLongestCommonSubstr(str, continuousSymbols) - if cnt >= rule.Limit { - return false - } - } - if rule.Numbers { - _, cnt := FindLongestCommonSubstr(str, number) - if cnt >= rule.Limit { - return false - } - } - if rule.Letters { - _, cnt := FindLongestCommonSubstr(str, lowercase) - if cnt >= rule.Limit { - return false - } - } - // 连续的键盘序 - if rule.Keyboards { - for _, v := range continuousKeyboardRow { - _, cnt := FindLongestCommonSubstr(str, v) - if cnt >= rule.Limit { - return false - } - } - for _, v := range continuousKeyboardCol { - _, cnt := FindLongestCommonSubstr(str, v) - if cnt >= rule.Limit { - return false - } - } - } - return true -} - -// FindLongestCommonSubstr 找出最长的公共字符串子串以及其长度 -func FindLongestCommonSubstr(s1, s2 string) (string, int) { - var max, pos int - temp := make([][]int, len(s1)+1) - for i := range temp { - temp[i] = make([]int, len(s2)+1) - } - for i := 0; i < len(s1); i++ { - for j := 0; j < len(s2); j++ { - if s1[i] == s2[j] { - temp[i+1][j+1] = temp[i][j] + 1 - if temp[i+1][j+1] > max { - max = temp[i+1][j+1] - pos = i + 1 - } - } - } - } - return s1[pos-max : pos], max -} - -// CheckContinuousRepeats 字符连续重复出现的次数 -func CheckContinuousRepeats(str string, repeats int) bool { - str = strings.ToLower(str) - var max, j int - cnt := 1 - for i := 1; i < len(str); i++ { - if str[i] == str[j] { - cnt++ - } - if str[i] != str[j] || i == len(str)-1 { - if cnt > max { - max = cnt - } - j = i - cnt = 1 - } - } - return max < repeats -} diff --git a/dbm-services/mysql/db-priv/service/randomize_manager.go b/dbm-services/mysql/db-priv/service/randomize_manager.go deleted file mode 100644 index ffdbce002a..0000000000 --- a/dbm-services/mysql/db-priv/service/randomize_manager.go +++ /dev/null @@ -1,75 +0,0 @@ -package service - -import ( - "dbm-services/common/go-pubpkg/errno" - "dbm-services/mysql/priv-service/util" - "fmt" - - "golang.org/x/exp/slog" -) - -// RandomExcludePara 对计划相关函数的入参 -type RandomExcludePara struct { - UserName string `json:"username"` - BkBizIds []int64 `json:"bk_biz_ids"` - Operator string `json:"operator"` -} - -// TbRandomExclude 不参与随机化的业务的表 -type TbRandomExclude struct { - UserName string `gorm:"column:username;not_null" json:"username"` - BkBizId int64 `gorm:"column:bk_biz_id;not_null" json:"bk_biz_id"` - Operator string `gorm:"column:operator" json:"operator"` - UpdateTime util.TimeFormat `gorm:"column:update_time" json:"update_time"` -} - -// ModifyRandomizeExclude 修改不参与随机化的业务 -func (m *RandomExcludePara) ModifyRandomizeExclude(jsonPara string) error { - if m.UserName == "" { - return errno.NameNull - } - tx := DB.Self.Begin() - // 传入的业务列表替换当前业务列表 - sql := fmt.Sprintf("delete from tb_randomize_exclude where username='%s'", m.UserName) - err := tx.Debug().Exec(sql).Error - if err != nil { - slog.Error("msg", sql, err) - tx.Rollback() - return err - } - for _, id := range m.BkBizIds { - // 更新tb_passwords中实例的密码 - sql = fmt.Sprintf("replace into tb_randomize_exclude(username,bk_biz_id,operator) values('%s',%d,'%s')", - m.UserName, id, m.Operator) - err = tx.Debug().Exec(sql).Error - if err != nil { - slog.Error("msg", sql, err) - tx.Rollback() - return err - } - } - err = tx.Commit().Error - if err != nil { - return err - } - log := PrivLog{BkBizId: 0, Operator: m.Operator, Para: jsonPara, Time: util.NowTimeFormat()} - AddPrivLog(log) - return nil -} - -// GetRandomizeExclude 查询不参与随机化的业务 -func (m *RandomExcludePara) GetRandomizeExclude() ([]int64, error) { - var ids []*TbRandomExclude - if m.UserName == "" { - return nil, errno.NameNull - } - err := DB.Self.Table("tb_randomize_exclude").Where(fmt.Sprintf("username = '%s'", m.UserName)).Scan(&ids).Error - if err != nil { - return nil, err - } - var list []int64 - for _, id := range ids { - list = append(list, id.BkBizId) - } - return list, nil -} diff --git a/dbm-services/mysql/db-priv/service/security_rule.go b/dbm-services/mysql/db-priv/service/security_rule.go deleted file mode 100644 index 12a8a66980..0000000000 --- a/dbm-services/mysql/db-priv/service/security_rule.go +++ /dev/null @@ -1,93 +0,0 @@ -package service - -import ( - "dbm-services/common/go-pubpkg/errno" - "dbm-services/mysql/priv-service/util" - "fmt" -) - -// ModifySecurityRule 修改安全规则 -func (m *SecurityRulePara) ModifySecurityRule(jsonPara string) error { - if m.Id == 0 { - return errno.RuleIdNull - } - updateTime := util.NowTimeFormat() - rule := TbSecurityRules{Name: m.Name, Rule: m.Rule, Operator: m.Operator, UpdateTime: updateTime} - id := TbSecurityRules{Id: m.Id} - result := DB.Self.Model(&id).Update(&rule) - if result.Error != nil { - return result.Error - } - // 是否更新 - if result.RowsAffected == 0 { - return errno.RuleNotExisted - } - log := PrivLog{BkBizId: 0, Operator: m.Operator, Para: jsonPara, Time: updateTime} - AddPrivLog(log) - return nil -} - -// AddSecurityRule 添加安全规则 -func (m *SecurityRulePara) AddSecurityRule(jsonPara string) error { - var count uint64 - // 检查是否已存在 - err := DB.Self.Model(&TbSecurityRules{}).Where(&TbSecurityRules{Name: m.Name}). - Count(&count).Error - if err != nil { - return err - } - if count != 0 { - return errno.RuleExisted.AddBefore(m.Name) - } - insertTime := util.NowTimeFormat() - // 添加规则 - rule := &TbSecurityRules{Name: m.Name, Rule: m.Rule, Creator: m.Operator, CreateTime: insertTime} - err = DB.Self.Model(&TbSecurityRules{}).Create(&rule).Error - if err != nil { - return err - } - log := PrivLog{BkBizId: 0, Operator: m.Operator, Para: jsonPara, Time: insertTime} - AddPrivLog(log) - return nil -} - -// GetSecurityRule 查询安全规则 -func (m *SecurityRulePara) GetSecurityRule() (*TbSecurityRules, error) { - var rules []*TbSecurityRules - if m.Name == "" { - return nil, errno.RuleNameNull - } - err := DB.Self.Model(&TbSecurityRules{}).Where(&TbSecurityRules{Name: m.Name}).Scan(&rules).Error - if err != nil { - return nil, err - } - if len(rules) > 0 { - return rules[0], nil - } - return nil, errno.RuleNotExisted.AddBefore(m.Name) -} - -// DeleteSecurityRule 删除安全规则 -func (m *SecurityRulePara) DeleteSecurityRule(jsonPara string) error { - var rules []*TbSecurityRules - if m.Id == 0 { - return errno.RuleIdNull - } - id := TbSecurityRules{Id: m.Id} - err := DB.Self.Model(&TbSecurityRules{}).Where(&id).Scan(&rules).Error - if err != nil { - return err - } - // 不允许删除密码规则,随机化默认使用的规则 - if len(rules) > 0 && rules[0].Name == "password" { - return fmt.Errorf("system config can not be delete") - } - // 根据id删除 - err = DB.Self.Model(&TbSecurityRules{}).Delete(&id).Error - if err != nil { - return err - } - log := PrivLog{BkBizId: 0, Operator: m.Operator, Para: jsonPara, Time: util.NowTimeFormat()} - AddPrivLog(log) - return nil -} diff --git a/dbm-services/mysql/db-priv/service/security_rule_object.go b/dbm-services/mysql/db-priv/service/security_rule_object.go deleted file mode 100644 index acc52bf6b6..0000000000 --- a/dbm-services/mysql/db-priv/service/security_rule_object.go +++ /dev/null @@ -1,47 +0,0 @@ -package service - -import "dbm-services/mysql/priv-service/util" - -// SecurityRulePara 安全规则相关函数的入参 -type SecurityRulePara struct { - Id int64 `json:"id"` - Name string `json:"name"` - Rule string `json:"rule"` - Operator string `json:"operator"` -} - -// TbSecurityRules 安全规则表 -type TbSecurityRules struct { - Id int64 `gorm:"column:id;primary_key;auto_increment" json:"id"` - Name string `gorm:"column:name;not_null" json:"name"` - Rule string `gorm:"column:rule;not_null" json:"rule"` - Creator string `gorm:"column:creator;not_null;" json:"creator"` - CreateTime util.TimeFormat `gorm:"column:create_time" json:"create_time"` - Operator string `gorm:"column:operator" json:"operator"` - UpdateTime util.TimeFormat `gorm:"column:update_time" json:"update_time"` -} - -// SecurityRule 安全规则 -type SecurityRule struct { - ExcludeContinuousRule ExcludeContinuousRule `json:"exclude_continuous_rule"` // 连续字符的规则 - IncludeRule IncludeRule `json:"include_rule"` // 密码中必须包含某些字符 - MaxLength int `json:"max_length"` // 密码的最大长度 - MinLength int `json:"min_length"` // 密码的最小长度 -} - -// ExcludeContinuousRule 密码不允许连续N位出现 -type ExcludeContinuousRule struct { - Limit int `json:"limit"` //连续N位 - Letters bool `json:"letters"` //字母顺序 - Numbers bool `json:"numbers"` //数字顺序 - Symbols bool `json:"symbols"` //特殊符号顺序 - Keyboards bool `json:"keyboards"` //键盘顺序 - Repeats bool `json:"repeats"` //重复的字母、数字、特殊字符 -} - -type IncludeRule struct { - Numbers bool `json:"numbers"` //是否包含数字 - Symbols bool `json:"symbols"` //是否包含字符 - Lowercase bool `json:"lowercase"` //是否包含小写 - Uppercase bool `json:"uppercase"` //是否包含大写 -} diff --git a/dbm-services/mysql/db-priv/util/base_func.go b/dbm-services/mysql/db-priv/util/base_func.go index 2f1bd7db07..5df9f0e592 100644 --- a/dbm-services/mysql/db-priv/util/base_func.go +++ b/dbm-services/mysql/db-priv/util/base_func.go @@ -1,16 +1,12 @@ package util import ( - "bytes" "fmt" - "os/exec" "reflect" "regexp" "runtime" "strings" - "github.com/pkg/errors" - "github.com/asaskevich/govalidator" ) @@ -74,25 +70,3 @@ func HasElem(elem interface{}, slice interface{}) bool { } return false } - -func ExecShellCommand(isSudo bool, param string) ([]byte, error) { - if isSudo { - param = "sudo " + param - } - cmd := exec.Command("bash", "-c", param) - var stdout, stderr bytes.Buffer - var err error - cmd.Stdout = &stdout - cmd.Stderr = &stderr - err = cmd.Run() - if err != nil { - // return stderr.String(), err - return stderr.Bytes(), errors.WithMessage(err, stderr.String()) - } - - if len(stderr.String()) > 0 { - err = fmt.Errorf("execute shell command(%s) has stderr:%s", param, stderr.String()) - return stderr.Bytes(), err - } - return stdout.Bytes(), nil -} diff --git a/dbm-ui/backend/components/mysql_priv_manager/client.py b/dbm-ui/backend/components/mysql_priv_manager/client.py index 489c254b34..97732c357b 100644 --- a/dbm-ui/backend/components/mysql_priv_manager/client.py +++ b/dbm-ui/backend/components/mysql_priv_manager/client.py @@ -83,7 +83,7 @@ def __init__(self): base=MYSQL_PRIV_MANAGER_APIGW_DOMAIN, url="/priv/modify_account", module=self.MODULE, - description=_("修改账号的密码"), + description=_("修改密码"), ) # 授权规则相关 @@ -145,76 +145,6 @@ def __init__(self): module=self.MODULE, description=_("mysql实例创建临时账号(切换专属接口)"), ) - self.modify_mysql_admin_password = DataAPI( - method="POST", - base=MYSQL_PRIV_MANAGER_APIGW_DOMAIN, - url="/priv/modify_mysql_admin_password", - module=self.MODULE, - description=_("新增或者修改mysql实例中管理用户的密码"), - ) - self.get_password = DataAPI( - method="POST", - base=MYSQL_PRIV_MANAGER_APIGW_DOMAIN, - url="/priv/get_password", - module=self.MODULE, - description=_("获取密码"), - ) - self.modify_password = DataAPI( - method="POST", - base=MYSQL_PRIV_MANAGER_APIGW_DOMAIN, - url="/priv/modify_password", - module=self.MODULE, - description=_("新增或者修改密码"), - ) - self.get_random_string = DataAPI( - method="POST", - base=MYSQL_PRIV_MANAGER_APIGW_DOMAIN, - url="/priv/get_random_string", - module=self.MODULE, - description=_("生成随机字符串"), - ) - self.get_security_rule = DataAPI( - method="POST", - base=MYSQL_PRIV_MANAGER_APIGW_DOMAIN, - url="/priv/get_security_rule", - module=self.MODULE, - description=_("获取安全规则"), - ) - self.add_security_rule = DataAPI( - method="POST", - base=MYSQL_PRIV_MANAGER_APIGW_DOMAIN, - url="/priv/add_security_rule", - module=self.MODULE, - description=_("添加安全规则"), - ) - self.modify_security_rule = DataAPI( - method="POST", - base=MYSQL_PRIV_MANAGER_APIGW_DOMAIN, - url="/priv/modify_security_rule", - module=self.MODULE, - description=_("修改安全规则"), - ) - self.delete_security_rule = DataAPI( - method="POST", - base=MYSQL_PRIV_MANAGER_APIGW_DOMAIN, - url="/priv/delete_security_rule", - module=self.MODULE, - description=_("删除安全规则"), - ) - self.get_randomize_exclude = DataAPI( - method="POST", - base=MYSQL_PRIV_MANAGER_APIGW_DOMAIN, - url="/priv/get_randomize_exclude", - module=self.MODULE, - description=_("获取不参与随机化的业务"), - ) - self.modify_randomize_exclude = DataAPI( - method="POST", - base=MYSQL_PRIV_MANAGER_APIGW_DOMAIN, - url="/priv/modify_randomize_exclude", - module=self.MODULE, - description=_("修改不参与随机化的业务"), - ) MySQLPrivManagerApi = _MySQLPrivManagerApi() diff --git a/dbm-ui/backend/db_periodic_task/local_tasks/__init__.py b/dbm-ui/backend/db_periodic_task/local_tasks/__init__.py index 8a78121103..afa727627e 100644 --- a/dbm-ui/backend/db_periodic_task/local_tasks/__init__.py +++ b/dbm-ui/backend/db_periodic_task/local_tasks/__init__.py @@ -13,7 +13,6 @@ from backend.db_periodic_task.local_tasks.db_monitor import * from backend.db_periodic_task.local_tasks.db_proxy import * from backend.db_periodic_task.local_tasks.redis_autofix import * -from backend.db_periodic_task.local_tasks.randomize_password import * from backend.db_periodic_task.local_tasks.ticket import * from backend.db_periodic_task.models import DBPeriodicTask diff --git a/dbm-ui/backend/db_periodic_task/local_tasks/randomize_password.py b/dbm-ui/backend/db_periodic_task/local_tasks/randomize_password.py deleted file mode 100644 index 6b182f0499..0000000000 --- a/dbm-ui/backend/db_periodic_task/local_tasks/randomize_password.py +++ /dev/null @@ -1,137 +0,0 @@ -import logging - -from celery.schedules import crontab -from django.db.models import Q -from django.utils.translation import ugettext as _ -from django_celery_beat.schedulers import ModelEntry - -from backend.components import MySQLPrivManagerApi -from backend.db_meta.enums import AccessLayer, ClusterType, MachineType, TenDBClusterSpiderRole -from backend.db_meta.models import Cluster -from backend.db_periodic_task.local_tasks import register_periodic_task -from backend.db_periodic_task.models import DBPeriodicTask -from backend.exceptions import ApiResultError -from backend.flow.consts import TDBCTL_USER - -logger = logging.getLogger("celery") - - -@register_periodic_task(run_every=crontab(day_of_week="*", hour="10", minute="3")) -def auto_randomize_password_daily(): - """每日随机化密码""" - randomize_admin_password(if_async=True, range_type="randmize_daily") - - -@register_periodic_task(run_every=crontab(minute="*")) -def auto_randomize_password_expired(): - """当密码锁定到期,随机化密码""" - randomize_admin_password(if_async=True, range_type="randmize_expired") - - -def randomize_admin_password(if_async: bool, range_type: str): - """密码随机化定时任务,只随机化mysql数据库""" - cluster_types = [ClusterType.TenDBCluster.value, ClusterType.TenDBHA.value, ClusterType.TenDBSingle.value] - cluster_ids = [] - if range_type == "randmize_daily": - # 获取不参与随机化的业务 - bk_biz_id_list = MySQLPrivManagerApi.get_randomize_exclude({"username": "ADMIN"}) - if bk_biz_id_list is None: - cluster_ids = [cluster.id for cluster in Cluster.objects.filter(cluster_type__in=cluster_types)] - else: - # 排除不随机化的业务 - cluster_ids = [ - cluster.id - for cluster in Cluster.objects.filter( - ~Q(bk_biz_id__in=[bk_biz_id_list]), cluster_type__in=cluster_types - ) - ] - elif range_type == "randmize_expired": - cluster_ids = [cluster.id for cluster in Cluster.objects.filter(cluster_type__in=cluster_types)] - clusters = [] - for cluster_id in cluster_ids: - clusters.append(get_mysql_instance(cluster_id)) - try: - MySQLPrivManagerApi.modify_mysql_admin_password( - params={ - "username": "ADMIN", # 管理用户 - "operator": range_type, - "clusters": clusters, - "security_rule_name": "password", # 用于生成随机化密码的安全规则 - "async": if_async, # 异步执行,避免占用资源 - "range": range_type, # 被锁定的密码到期,需要被随机化 - }, - raw=True, - ) - except ApiResultError as e: - # 捕获接口返回结果异常 - logger.error(_("「接口modify_mysql_admin_password返回结果异常」{}").format(e.message)) - except Exception as e: - # 捕获接口其他未知异常 - logger.error(_("「接口modify_mysql_admin_password调用异常」{}").format(e)) - return - - -def get_mysql_instance(cluster_id: int): - cluster = Cluster.objects.get(id=cluster_id) - instances = [ - { - "role": AccessLayer.STORAGE.value, - "addresses": [ - { - "ip": instance.machine.ip, - "port": instance.port, - "id": instance.id, - } - for instance in cluster.storageinstance_set.all() - ], - } - ] - # spider节点和tdbctl节点修改密码指令不同,需区别 - if cluster.cluster_type == ClusterType.TenDBCluster: - spiders = cluster.proxyinstance_set.all() - dbctls = cluster.proxyinstance_set.filter( - tendbclusterspiderext__spider_role=TenDBClusterSpiderRole.SPIDER_MASTER - ) - instances.append( - { - "role": MachineType.SPIDER.value, - "addresses": [ - { - "ip": instance.machine.ip, - "port": instance.port, - "id": instance.id, - } - for instance in spiders - ], - } - ) - instances.append( - { - "role": TDBCTL_USER, - "addresses": [ - { - "ip": instance.machine.ip, - "port": instance.admin_port, - "id": instance.id, - } - for instance in dbctls - ], - }, - ) - return {"bk_cloud_id": cluster.bk_cloud_id, "cluster_type": cluster.cluster_type, "instances": instances} - - -def modify_periodic_task_run_every(run_every, func_name): - """修改定时任务的运行周期""" - model_schedule, model_field = ModelEntry.to_model_schedule(run_every) - # 不存在抛出错误 - db_task = DBPeriodicTask.objects.get(name__contains=func_name) - celery_task = db_task.task - setattr(celery_task, model_field, model_schedule) - celery_task.save(update_fields=[model_field]) - - -def get_periodic_task_run_every(func_name): - """获取定时任务的运行周期""" - db_task = DBPeriodicTask.objects.get(name__contains=func_name) - return db_task.task.crontab.schedule diff --git a/dbm-ui/backend/tests/mock_data/components/mysql_priv_manager.py b/dbm-ui/backend/tests/mock_data/components/mysql_priv_manager.py index 0a9d4f9e40..66a53370d3 100644 --- a/dbm-ui/backend/tests/mock_data/components/mysql_priv_manager.py +++ b/dbm-ui/backend/tests/mock_data/components/mysql_priv_manager.py @@ -85,8 +85,3 @@ def clone_instance(cls, *args, **kwargs): @raw_response def clone_client(cls, *args, **kwargs): return True - - @classmethod - @raw_response - def modify_user_password(cls, *args, **kwargs): - return True