Skip to content

Commit

Permalink
fix(redis): redis单据联调 TencentBlueKing#7872
Browse files Browse the repository at this point in the history
# Reviewed, transaction id: 24324
  • Loading branch information
WytheLi committed Nov 20, 2024
1 parent 07d7a91 commit bee5003
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def get_redis_install_sub_pipelines(self, act_kwargs, master_ip, slave_ip, spec_
self.data,
act_kwargs,
install_master_redis_params,
dbmon_install=True,
to_install_dbmon=True,
to_trans_files=False,
to_install_puglins=False,
)
Expand All @@ -192,7 +192,7 @@ def get_redis_install_sub_pipelines(self, act_kwargs, master_ip, slave_ip, spec_
self.data,
act_kwargs,
install_slave_redis_params,
dbmon_install=True,
to_install_dbmon=True,
to_trans_files=False,
to_install_puglins=False,
)
Expand Down
2 changes: 2 additions & 0 deletions dbm-ui/backend/ticket/builders/redis/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class BaseRedisInstanceTicketFlowBuilder(RedisTicketFlowBuilderPatchMixin, Ticke
ClusterType.TendisTwemproxyRedisInstance.value,
ClusterType.TwemproxyTendisSSDInstance.value,
ClusterType.TendisRedisInstance.value,
ClusterType.RedisCluster.value,
ClusterType.RedisInstance.value,
]


Expand Down
98 changes: 98 additions & 0 deletions dbm-ui/backend/ticket/builders/redis/redis_cluster_ins_migrate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# -*- 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.
"""
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers

from backend.db_meta.enums import ClusterType
from backend.db_meta.models import Cluster
from backend.db_services.dbbase.constants import IpSource
from backend.flow.engine.controller.redis import RedisController
from backend.ticket import builders
from backend.ticket.builders.common.base import SkipToRepresentationMixin, fetch_cluster_ids
from backend.ticket.builders.redis.base import BaseRedisInstanceTicketFlowBuilder
from backend.ticket.constants import TicketType


class RedisClusterInsMigrateDetailSerializer(SkipToRepresentationMixin, serializers.Serializer):
class RedisClusterInsMigrateItemSerializer(serializers.Serializer):
cluster_id = serializers.IntegerField(help_text=_("集群ID"))
resource_spec = serializers.JSONField(help_text=_("资源规格"))
old_nodes = serializers.JSONField(help_text=_("旧节点信息集合"))

ip_source = serializers.ChoiceField(
help_text=_("主机来源"), choices=IpSource.get_choices(), default=IpSource.RESOURCE_POOL
)
infos = serializers.ListSerializer(help_text=_("实例迁移单据详情"), child=RedisClusterInsMigrateItemSerializer())

def validate(self, attrs):
self.validate_cluster_can_access(attrs)
return attrs

def validate_cluster_can_access(self, attrs):
"""校验集群状态是否可以提单"""
clusters = Cluster.objects.filter(id__in=fetch_cluster_ids(details=attrs))

for cluster in clusters:
if cluster.cluster_type != ClusterType.RedisCluster:
raise serializers.ValidationError(
_(f"Redis cluster[{cluster.id}] type is not {ClusterType.RedisCluster}")
)

def to_internal_value(self, data):
pass


class RedisClusterInsMigrateBuilder(builders.FlowParamBuilder):
controller = RedisController.redis_cluster_ins_migrate

def format_ticket_data(self):
cluster_id = self.ticket_data["infos"][0]["cluster_id"]
cluster = Cluster.objects.get(id=cluster_id)
self.ticket_data.update(
cluster_id=cluster.id,
bk_cloud_id=cluster.bk_cloud_id,
resource_spec=self.ticket_data["infos"][0]["resource_spec"],
)


class RedisClusterInstanceApplyResourceParamBuilder(builders.ResourceApplyParamBuilder):
def format(self):
# 资源申请的一些参数补充
cluster_id = self.ticket_data["infos"][0]["cluster_id"]
cluster = Cluster.objects.get(id=cluster_id)
self.ticket_data.update(
cluster_id=cluster.id,
bk_cloud_id=cluster.bk_cloud_id,
resource_spec=self.ticket_data["infos"][0]["resource_spec"],
)
self.patch_info_affinity_location(roles=["backend_group"])

def post_callback(self):
next_flow = self.ticket.next_flow()
ticket_data = next_flow.details["ticket_data"]
for info in ticket_data["infos"]:
migrate_list = {
"src_master": f'{info["old_nodes"]["master"][0]["ip"]}:{info["old_nodes"]["master"][0]["port"]}',
"src_slave": f'{info["old_nodes"]["slave"][0]["ip"]}:{info["old_nodes"]["slave"][0]["port"]}',
"dest_master": f'{ticket_data["nodes"]["backend_group"][0]["master"]["ip"]}',
"dest_slave": f'{ticket_data["nodes"]["backend_group"][0]["slave"]["ip"]}',
"resource_spec": ticket_data["resource_spec"],
}
info["migrate_list"] = migrate_list
next_flow.save(update_fields=["details"])


@builders.BuilderFactory.register(TicketType.REDIS_CLUSTER_INS_MIGRATE)
class RedisClusterInsMigrateBuilder(BaseRedisInstanceTicketFlowBuilder):
serializer = RedisClusterInsMigrateDetailSerializer
inner_flow_builder = RedisClusterInsMigrateBuilder
resource_apply_builder = RedisClusterInstanceApplyResourceParamBuilder
inner_flow_name = _("Redis 集群指定实例迁移")
109 changes: 109 additions & 0 deletions dbm-ui/backend/ticket/builders/redis/redis_single_ins_migrate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# -*- 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.
"""
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers

from backend.db_meta.enums import ClusterType
from backend.db_meta.models import Cluster
from backend.db_services.dbbase.constants import IpSource
from backend.flow.engine.controller.redis import RedisController
from backend.ticket import builders
from backend.ticket.builders.common.base import SkipToRepresentationMixin, fetch_cluster_ids
from backend.ticket.builders.redis.base import BaseRedisInstanceTicketFlowBuilder
from backend.ticket.constants import TicketType


class RedisSingleInsMigrateDetailSerializer(SkipToRepresentationMixin, serializers.Serializer):
class RedisSingleInsMigrateItemSerializer(serializers.Serializer):
cluster_id = serializers.IntegerField(help_text=_("集群ID"))
resource_spec = serializers.JSONField(help_text=_("资源规格"))
old_nodes = serializers.JSONField(help_text=_("旧节点信息集合"))

ip_source = serializers.ChoiceField(
help_text=_("主机来源"), choices=IpSource.get_choices(), default=IpSource.RESOURCE_POOL
)
infos = serializers.ListSerializer(help_text=_("实例迁移单据详情"), child=RedisSingleInsMigrateItemSerializer())

def validate(self, attrs):
self.validate_cluster_can_access(attrs)
return attrs

def validate_cluster_can_access(self, attrs):
"""校验集群状态是否可以提单"""
clusters = Cluster.objects.filter(id__in=fetch_cluster_ids(details=attrs))

for cluster in clusters:
if cluster.cluster_type != ClusterType.RedisInstance:
raise serializers.ValidationError(
_(f"Redis cluster[{cluster.id}] type is not {ClusterType.RedisInstance}")
)


class RedisSingleInsMigrateBuilder(builders.FlowParamBuilder):
controller = RedisController.redis_single_ins_migrate

def format_ticket_data(self):
cluster_id = self.ticket_data["infos"][0]["cluster_id"]
cluster = Cluster.objects.get(id=cluster_id)
self.ticket_data.update(
cluster_id=cluster.id,
bk_cloud_id=cluster.bk_cloud_id,
db_version=cluster.major_version,
resource_spec=self.ticket_data["infos"][0]["resource_spec"],
)


class RedisSingleInstanceApplyResourceParamBuilder(builders.ResourceApplyParamBuilder):
def format(self):
# 资源申请的一些参数补充
cluster_id = self.ticket_data["infos"][0]["cluster_id"]
cluster = Cluster.objects.get(id=cluster_id)
self.ticket_data.update(
cluster_id=cluster.id,
bk_cloud_id=cluster.bk_cloud_id,
db_version=cluster.major_version,
resource_spec=self.ticket_data["infos"][0]["resource_spec"],
)
self.patch_info_affinity_location(roles=["backend_group"])

def fetch_cluster_map(self, ticket_data):
cluster_ids = fetch_cluster_ids(ticket_data)
clusters = Cluster.objects.filter(id__in=cluster_ids)
cluster_id__cluster = {cluster.id: cluster for cluster in clusters}
return cluster_id__cluster

def patch_instance_migrate_info(self, ticket_data):
"""补充实例迁移的信息"""
cluster_id__cluster = self.fetch_cluster_map(ticket_data)
for index, info in enumerate(ticket_data["infos"]):
cluster = cluster_id__cluster[info["cluster_id"]]
info.update(
cluster_id=cluster.id,
db_version=cluster.major_version,
src_master=f'{info["old_nodes"]["master"][0]["ip"]}:{info["old_nodes"]["master"][0]["port"]}',
src_slave=f'{info["old_nodes"]["slave"][0]["ip"]}:{info["old_nodes"]["slave"][0]["port"]}',
dest_master=f'{ticket_data["nodes"]["backend_group"][0]["master"]["ip"]}',
dest_slave=f'{ticket_data["nodes"]["backend_group"][0]["slave"]["ip"]}',
resource_spec=ticket_data["resource_spec"],
)

def post_callback(self):
next_flow = self.ticket.next_flow()
self.patch_instance_migrate_info(next_flow.details["ticket_data"])
next_flow.save(update_fields=["details"])


@builders.BuilderFactory.register(TicketType.REDIS_SINGLE_INS_MIGRATE)
class RedisSingleInsMigrateBuilder(BaseRedisInstanceTicketFlowBuilder):
serializer = RedisSingleInsMigrateDetailSerializer
inner_flow_builder = RedisSingleInsMigrateBuilder
resource_apply_builder = RedisSingleInstanceApplyResourceParamBuilder
inner_flow_name = _("Redis 主从指定实例迁移")
4 changes: 3 additions & 1 deletion dbm-ui/backend/ticket/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,9 @@ def get_cluster_type_by_ticket(cls, ticket_type):
REDIS_CLUSTER_RENAME_DOMAIN = TicketEnumField("REDIS_CLUSTER_RENAME_DOMAIN", _("Redis集群域名重命名"), _("集群维护"))
REDIS_CLUSTER_MAXMEMORY_SET = TicketEnumField("REDIS_CLUSTER_MAXMEMORY_SET", _("Redis 集群设置maxmemory")) # noqa
REDIS_CLUSTER_LOAD_MODULES = TicketEnumField("REDIS_CLUSTER_LOAD_MODULES", _("Redis 集群加载modules")) # noqa
REDIS_TENDISPLUS_LIGHTNING_DATA= TicketEnumField("REDIS_TENDISPLUS_LIGHTNING_DATA", _("Tendisplus闪电导入数据"), _("集群维护")) # noqa
REDIS_TENDISPLUS_LIGHTNING_DATA = TicketEnumField("REDIS_TENDISPLUS_LIGHTNING_DATA", _("Tendisplus闪电导入数据"), _("集群维护")) # noqa
REDIS_CLUSTER_INS_MIGRATE = TicketEnumField("REDIS_CLUSTER_INS_MIGRATE", _("Redis 集群指定实例迁移"), _("集群管理"))
REDIS_SINGLE_INS_MIGRATE = TicketEnumField("REDIS_SINGLE_INS_MIGRATE", _("Redis 主从指定实例迁移"), _("集群管理"))

# 大数据
KAFKA_APPLY = TicketEnumField("KAFKA_APPLY", _("Kafka 集群部署"), register_iam=False)
Expand Down

0 comments on commit bee5003

Please sign in to comment.