Skip to content

Commit

Permalink
feat(mongodb): mongos自愈 TencentBlueKing#7010
Browse files Browse the repository at this point in the history
  • Loading branch information
yyhenryyy committed Oct 23, 2024
1 parent 7eaf1f6 commit 5bd4478
Show file tree
Hide file tree
Showing 34 changed files with 1,544 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
type DeInstallConfParams struct {
IP string `json:"ip" validate:"required"`
Port int `json:"port" validate:"required"`
SetId string `json:"setId" validate:"required"`
SetId string `json:"setId"`
NodeInfo []string `json:"nodeInfo" validate:"required"` // []string ip,ip 如果为复制集节点,则为复制集所有节点的ip;如果为mongos,则为mongos的ip
InstanceType string `json:"instanceType" validate:"required"` // mongod mongos
Force bool `json:"force"` // 不检查连接,强制卸载
Expand Down Expand Up @@ -111,12 +111,19 @@ func (d *DeInstall) Init(runtime *jobruntime.JobGenericRuntime) error {
strPort := strconv.Itoa(d.ConfParams.Port)
d.PortDir = filepath.Join(d.DataDir, "mongodata", strPort)
d.DbpathDir = filepath.Join(d.DataDir, "mongodata", strPort, "db")
d.DbPathRenameDir = filepath.Join(d.DataDir, "mongodata", fmt.Sprintf("%s_%s_%d",
d.ConfParams.InstanceType, d.ConfParams.SetId, d.ConfParams.Port))
if d.ConfParams.SetId == "" {
d.DbPathRenameDir = filepath.Join(d.DataDir, "mongodata", fmt.Sprintf("%s_%d",
d.ConfParams.InstanceType, d.ConfParams.Port))
d.LogPathRenameDir = filepath.Join(d.BackupDir, "mongolog", fmt.Sprintf("%s_%d",
d.ConfParams.InstanceType, d.ConfParams.Port))
} else {
d.DbPathRenameDir = filepath.Join(d.DataDir, "mongodata", fmt.Sprintf("%s_%s_%d",
d.ConfParams.InstanceType, d.ConfParams.SetId, d.ConfParams.Port))
d.LogPathRenameDir = filepath.Join(d.BackupDir, "mongolog", fmt.Sprintf("%s_%s_%d",
d.ConfParams.InstanceType, d.ConfParams.SetId, d.ConfParams.Port))
}
d.IPInfo = strings.Join(d.ConfParams.NodeInfo, "|")
d.LogPortDir = filepath.Join(d.BackupDir, "mongolog", strPort)
d.LogPathRenameDir = filepath.Join(d.BackupDir, "mongolog", fmt.Sprintf("%s_%s_%d",
d.ConfParams.InstanceType, d.ConfParams.SetId, d.ConfParams.Port))

// 进行校验
if err := d.checkParams(); err != nil {
Expand Down
Empty file.
108 changes: 108 additions & 0 deletions dbm-ui/backend/db_services/mongodb/autofix/mongodb_autofix_ticket.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# -*- coding: utf-8 -*-
"""
TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available.
Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at https://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""
import datetime
import logging

from django.utils import timezone
from django.utils.crypto import get_random_string
from django.utils.translation import ugettext_lazy as _

from backend.configuration.constants import DBType
from backend.configuration.models.dba import DBAdministrator
from backend.db_services.dbbase.constants import IpSource
from backend.db_services.redis.autofix.enums import AutofixStatus
from backend.db_services.redis.autofix.models import RedisAutofixCore
from backend.ticket.constants import TicketType
from backend.ticket.models import Ticket
from backend.utils.time import datetime2str

logger = logging.getLogger("root")


def get_resource_spec(mongos_list: list, mongod_list: list) -> dict:
"""获取申请机器规格信息,采用故障机与新机器园区相对应"""

resource_spec = {}
for mongos in mongos_list:
resource_spec.update(
{
mongos["ip"]: {
"spec_id": mongos["spec_id"],
"count": 1,
"spec_config": mongos["spec_config"],
"Location_spec": {"city": mongos["city"], "sub_zone_ids": [mongos["bk_sub_zone_id"]]},
}
}
)
# mongod自愈
for mongod in mongod_list:
resource_spec.update(
{
mongod["ip"]: {
"spec_id": mongod["spec_id"],
"count": 1,
"spec_config": mongod["spec_config"],
"Location_spec": {"city": mongod["city"], "sub_zone_ids": [mongod["bk_sub_zone_id"]]},
}
}
)
return resource_spec


def mongo_create_ticket(cluster: RedisAutofixCore, cluster_ids: list, mongos_list: list, mongod_list: list):
"""mongodb自愈创建单据"""

# 获取dba
try:
mongodb_dba = DBAdministrator.objects.get(bk_biz_id=cluster.bk_biz_id, db_type=DBType.MongoDB.value).users
except DBAdministrator.DoesNotExist:
# 如果不存在,则取默认值
mongodb_dba = DBAdministrator.objects.get(bk_biz_id=0, db_type=DBType.MongoDB.value).users

# 申请机器规格信息
resource_spec = get_resource_spec(mongos_list, mongod_list)
if not resource_spec:
return
# 集群类型
if mongos_list:
cluster_type = mongos_list[0]["cluster_type"]
if mongod_list:
cluster_type = mongod_list[0]["cluster_type"]
# 单据信息
details = {
"ip_source": IpSource.RESOURCE_POOL.value,
"infos": [
{
"cluster_ids": cluster_ids,
"immute_domain": cluster.immute_domain,
"bk_cloud_id": cluster.bk_cloud_id,
"bk_biz_id": cluster.bk_biz_id,
"resource_spec": resource_spec,
"cluster_type": cluster_type,
"mongos_list": mongos_list,
"mongod_list": mongod_list,
}
],
}

# 创建单据
ticket = Ticket.create_ticket(
ticket_type=TicketType.MONGODB_AUTOFIX.value,
creator=mongodb_dba[0],
bk_biz_id=cluster.bk_biz_id,
remark=_("自动发起-自愈任务-{}".format(cluster.immute_domain)),
details=details,
)
cluster.ticket_id = ticket.id
cluster.status_version = get_random_string(12)
cluster.deal_status = AutofixStatus.AF_WFLOW.value
cluster.update_at = datetime2str(datetime.datetime.now(timezone.utc))
cluster.save(update_fields=["ticket_id", "status_version", "deal_status", "update_at"])
34 changes: 34 additions & 0 deletions dbm-ui/backend/db_services/plugin/nameservice/clb.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,3 +384,37 @@ def immute_domain_clb_ip(cluster_id: int, creator: str, bind: bool) -> Dict[str,
return response_fail(code=3, message=message)
return response_ok()
return response_ok()


def operate_part_target(cluster_id: int, ips: list, bind: bool) -> dict:
"""绑定或解绑部分后端主机"""

# 获取信息
cluster = get_cluster_info(cluster_id=cluster_id)
clb = cluster["clusterentry_set"]["clb"]
clb_id = clb["clb_id"]
listener_id = clb["listener_id"]
clb_region = clb["clb_region"]

# 进行请求,得到返回结果
if bind:
output = NameServiceApi.clb_register_part_target(
{
"region": clb_region,
"loadbalancerid": clb_id,
"listenerid": listener_id,
"ips": ips,
},
raw=True,
)
else:
output = NameServiceApi.clb_deregister_part_target(
{
"region": clb_region,
"loadbalancerid": clb_id,
"listenerid": listener_id,
"ips": ips,
},
raw=True,
)
return output
39 changes: 37 additions & 2 deletions dbm-ui/backend/db_services/redis/autofix/bill.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
from backend.configuration.models.dba import DBAdministrator
from backend.db_meta.api.cluster.apis import query_cluster_by_hosts
from backend.db_meta.enums import ClusterType, MachineType
from backend.db_meta.enums.instance_role import InstanceRole
from backend.db_meta.models import Machine
from backend.db_services.dbbase.constants import IpSource
from backend.db_services.mongodb.autofix.mongodb_autofix_ticket import mongo_create_ticket
from backend.db_services.redis.util import is_support_redis_auotfix
from backend.ticket.builders import BuilderFactory
from backend.ticket.constants import TicketStatus, TicketType
Expand All @@ -38,6 +40,7 @@


def generate_autofix_ticket(fault_clusters: QuerySet):
"""自愈创建单据"""
for cluster in fault_clusters:
# 目前仅支持这三种架构
if not is_support_redis_auotfix(cluster.cluster_type):
Expand All @@ -53,13 +56,41 @@ def generate_autofix_ticket(fault_clusters: QuerySet):
continue

fault_machines = json.loads(cluster.fault_machines)
redis_proxies, redis_slaves, cluster_ids = [], [], [cluster.cluster_id]
mongos_list, mongod_list, redis_proxies, redis_slaves, cluster_ids = [], [], [], [], [cluster.cluster_id]
for fault_machine in fault_machines:
fault_ip = fault_machine["ip"]
fault_obj = Machine.objects.filter(ip=fault_ip, bk_biz_id=cluster.bk_biz_id).get()
fault_info = {"ip": fault_ip, "spec_id": fault_obj.spec_id, "bk_sub_zone": fault_obj.bk_sub_zone}
fault_info = {
"ip": fault_ip,
"spec_id": fault_obj.spec_id,
"bk_sub_zone": fault_obj.bk_sub_zone,
"bk_sub_zone_id": fault_obj.bk_sub_zone_id,
"city": fault_obj.bk_city.logical_city.name,
"instance_type": fault_machine["instance_type"],
"spec_config": fault_obj.spec_config,
"cluster_type": cluster.cluster_type,
}
if fault_machine["instance_type"] in [MachineType.TWEMPROXY.value, MachineType.PREDIXY.value]:
redis_proxies.append(fault_info)
elif fault_machine["instance_type"] == MachineType.MONGOS.value:
mongos_list.append(fault_info)
elif fault_machine["instance_type"] in [
InstanceRole.MONGO_M1.value,
InstanceRole.MONGO_M2.value,
InstanceRole.MONGO_M3.value,
InstanceRole.MONGO_M4.value,
InstanceRole.MONGO_M5.value,
InstanceRole.MONGO_M6.value,
InstanceRole.MONGO_M7.value,
InstanceRole.MONGO_M8.value,
InstanceRole.MONGO_M9.value,
InstanceRole.MONGO_M10.value,
InstanceRole.MONGO_BACKUP.value,
]:
mongod_list.append(fault_info)
if cluster.cluster_type == ClusterType.MongoReplicaSet.value:
clusters = query_cluster_by_hosts(hosts=[fault_ip])
cluster_ids = [cls_obj["cluster_id"] for cls_obj in clusters]
else:
if fault_obj.cluster_type == ClusterType.TendisRedisInstance.value:
clusters = query_cluster_by_hosts(hosts=[fault_ip])
Expand All @@ -72,10 +103,14 @@ def generate_autofix_ticket(fault_clusters: QuerySet):
cluster.immute_domain, redis_proxies, redis_slaves
)
)
if mongos_list or mongod_list:
mongo_create_ticket(cluster, cluster_ids, mongos_list, mongod_list)
return
create_ticket(cluster, cluster_ids, redis_proxies, redis_slaves)


def create_ticket(cluster: RedisAutofixCore, cluster_ids: list, redis_proxies: list, redis_slaves: list):
"""redis自愈创建单据"""
details = {
"ip_source": IpSource.RESOURCE_POOL.value,
"infos": [
Expand Down
2 changes: 2 additions & 0 deletions dbm-ui/backend/db_services/redis/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,6 @@ def is_support_redis_auotfix(cluster_type: str) -> bool:
ClusterType.TendisPredixyTendisplusCluster.value,
ClusterType.TendisPredixyRedisCluster.value,
ClusterType.TendisRedisInstance.value,
ClusterType.MongoShardedCluster.value,
ClusterType.MongoReplicaSet.value,
]
2 changes: 1 addition & 1 deletion dbm-ui/backend/flow/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -1441,7 +1441,7 @@ class MongoDBInstanceType(str, StructuredEnum):
MongoS = EnumField("mongos", _("mongos"))


class MongoDBDfaultAuthDB(str, StructuredEnum):
class MongoDBDefaultAuthDB(str, StructuredEnum):
"""mongodb 默认验证db"""

AuthDB = EnumField("admin", _("admin"))
Expand Down
Loading

0 comments on commit 5bd4478

Please sign in to comment.