Skip to content

Commit

Permalink
feat(backend): 标签功能 #6235
Browse files Browse the repository at this point in the history
# Reviewed, transaction id: 16342
  • Loading branch information
zhangzhw8 committed Aug 23, 2024
1 parent 4556c69 commit 45ddbd7
Show file tree
Hide file tree
Showing 17 changed files with 254 additions and 31 deletions.
15 changes: 13 additions & 2 deletions dbm-ui/backend/db_meta/enums/comm.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ class DBCCModule(str, StructuredEnum):


class TagType(str, StructuredEnum):
CUSTOM = EnumField("custom", _("custom"))
SYSTEM = EnumField("system", _("system"))
CUSTOM = EnumField("custom", _("自定义标签"))
SYSTEM = EnumField("system", _("系统标签"))
BUILTIN = EnumField("builtin", _("内置标签"))


class SystemTagEnum(str, StructuredEnum):
Expand All @@ -36,6 +37,16 @@ class SystemTagEnum(str, StructuredEnum):
TEMPORARY = EnumField("temporary", _("temporary"))


class TagResourceEnum(int, StructuredEnum):
"""资源类型"""

CLUSTER = EnumField(0, _("集群"))
STORAGE_INSTANCE = EnumField(1, _("存储实例"))
PROXY_INSTANCE = EnumField(2, _("代理实例"))
MACHINE = EnumField(3, _("实例机器"))
RESOURCE_MACHINE = EnumField(4, _("资源池机器"))


class RedisVerUpdateNodeType(str, StructuredEnum):
"""redis版本升级节点类型"""

Expand Down
79 changes: 79 additions & 0 deletions dbm-ui/backend/db_meta/migrations/0042_auto_20240823_1533.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Generated by Django 3.2.25 on 2024-08-23 07:33

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("db_meta", "0041_auto_20240819_1031"),
]

operations = [
migrations.AddField(
model_name="cluster",
name="tags",
field=models.ManyToManyField(blank=True, help_text="标签(外键)", to="db_meta.Tag"),
),
migrations.AddField(
model_name="tag",
name="key",
field=models.CharField(default="", help_text="标签键", max_length=64),
),
migrations.AddField(
model_name="tag",
name="value",
field=models.CharField(default="", help_text="标签值", max_length=64),
),
migrations.AlterField(
model_name="spec",
name="cpu",
field=models.JSONField(help_text='cpu规格描述:{"min":1,"max":10}', null=True),
),
migrations.AlterField(
model_name="spec",
name="device_class",
field=models.JSONField(help_text='实际机器机型: ["class1","class2"]', null=True),
),
migrations.AlterField(
model_name="spec",
name="mem",
field=models.JSONField(help_text='mem规格描述:{"min":100,"max":1000}', null=True),
),
migrations.AlterField(
model_name="spec",
name="qps",
field=models.JSONField(default=dict, help_text='qps规格描述:{"min": 1, "max": 100}'),
),
migrations.AlterField(
model_name="spec",
name="storage_spec",
field=models.JSONField(help_text='存储磁盘需求配置:[{"mount_point":"/data","size":500,"type":"ssd"}]', null=True),
),
migrations.AlterField(
model_name="tag",
name="bk_biz_id",
field=models.IntegerField(default=0, help_text="业务 ID"),
),
migrations.AlterField(
model_name="tag",
name="type",
field=models.CharField(
choices=[("custom", "自定义标签"), ("system", "系统标签"), ("builtin", "内置标签")],
help_text="tag类型",
max_length=64,
),
),
migrations.AlterUniqueTogether(
name="tag",
unique_together={("bk_biz_id", "key", "value")},
),
migrations.RemoveField(
model_name="tag",
name="cluster",
),
migrations.RemoveField(
model_name="tag",
name="name",
),
]
2 changes: 2 additions & 0 deletions dbm-ui/backend/db_meta/models/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
ClusterSqlserverStatusFlags,
)
from backend.db_meta.exceptions import ClusterExclusiveOperateException, DBMetaException
from backend.db_meta.models.tag import Tag
from backend.db_services.version.constants import LATEST, PredixyVersion, TwemproxyVersion
from backend.flow.consts import DEFAULT_RIAK_PORT
from backend.ticket.constants import TicketType
Expand All @@ -68,6 +69,7 @@ class Cluster(AuditedModel):
max_length=128, help_text=_("容灾要求"), choices=AffinityEnum.get_choices(), default=AffinityEnum.NONE.value
)
time_zone = models.CharField(max_length=16, default=DEFAULT_TIME_ZONE, help_text=_("集群所在的时区"))
tags = models.ManyToManyField(Tag, blank=True, help_text=_("标签(外键)"))

class Meta:
unique_together = [("bk_biz_id", "immute_domain", "cluster_type", "db_module_id"), ("immute_domain",)]
Expand Down
21 changes: 14 additions & 7 deletions dbm-ui/backend/db_meta/models/tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,27 @@
from django.utils.translation import ugettext_lazy as _

from backend.bk_web.models import AuditedModel
from backend.configuration.constants import PLAT_BIZ_ID
from backend.db_meta.enums.comm import TagType
from backend.db_meta.models import Cluster


class Tag(AuditedModel):
bk_biz_id = models.IntegerField(default=0)
name = models.CharField(max_length=64, default="", help_text=_("tag名称"))
type = models.CharField(max_length=64, help_text=_("tag类型"), choices=TagType.get_choices())
cluster = models.ManyToManyField(Cluster, blank=True, help_text=_("关联集群"))
bk_biz_id = models.IntegerField(help_text=_("业务 ID"), default=0)
key = models.CharField(help_text=_("标签键"), default="", max_length=64)
value = models.CharField(help_text=_("标签值"), default="", max_length=64)
type = models.CharField(help_text=_("tag类型"), max_length=64, choices=TagType.get_choices())

class Meta:
unique_together = ["bk_biz_id", "name"]
unique_together = ["bk_biz_id", "key", "value"]

@property
def tag_desc(self):
"""仅返回tag的信息"""
return {"bk_biz_id": self.bk_biz_id, "name": self.name, "type": self.type}
return {"bk_biz_id": self.bk_biz_id, "key": self.key, "type": self.type}

@classmethod
def get_or_create_system_tag(cls, key: str, value: str):
tag, created = cls.objects.get_or_create(
bk_biz_id=PLAT_BIZ_ID, key=key, value=value, type=TagType.SYSTEM.value
)
return tag
13 changes: 11 additions & 2 deletions dbm-ui/backend/db_services/dbbase/resources/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ def export_instance(cls, bk_biz_id: int, bk_host_ids: list) -> HttpResponse:
@classmethod
def get_temporary_cluster_info(cls, cluster, ticket_type):
"""如果当前集群是临时集群,则补充临时集群相关信息。"""
# TODO 临时关闭 tag
return {}
tags = [tag.name for tag in cluster.tag_set.all()]
if SystemTagEnum.TEMPORARY.value not in tags:
return {}
Expand Down Expand Up @@ -395,8 +397,14 @@ def _list_clusters(
for param in filter_params_map:
if query_params.get(param):
query_filters &= filter_params_map[param]

# 对标签进行过滤,标签“且”查询,需以追加 filter 的方式实现
cluster_queryset = Cluster.objects.filter(query_filters)
for tag_id in query_params.get("tag_ids", "").split(","):
cluster_queryset = cluster_queryset.filter(tags__id=tag_id)

# 一join多的一方会有重复的数据,去重
cluster_queryset = Cluster.objects.filter(query_filters).distinct()
cluster_queryset = cluster_queryset.distinct()

def filter_inst_queryset(_cluster_queryset, _proxy_queryset, _storage_queryset, _filters):
# 注意这里用新的变量获取过滤后的queryset,不要用原queryset过滤,会影响后续集群关联实例的获取
Expand Down Expand Up @@ -470,7 +478,7 @@ def _filter_cluster_hook(
Prefetch("proxyinstance_set", queryset=proxy_queryset.select_related("machine"), to_attr="proxies"),
Prefetch("storageinstance_set", queryset=storage_queryset.select_related("machine"), to_attr="storages"),
Prefetch("clusterentry_set", to_attr="entries"),
"tag_set",
"tags",
)
cluster_ids = list(cluster_queryset.values_list("id", flat=True))

Expand Down Expand Up @@ -562,6 +570,7 @@ def _to_cluster_representation(
"updater": cluster.updater,
"create_at": datetime2str(cluster.create_at),
"update_at": datetime2str(cluster.update_at),
"tags": [{tag.key: tag.value} for tag in cluster.tags.all()],
}

@classmethod
Expand Down
1 change: 1 addition & 0 deletions dbm-ui/backend/db_services/dbbase/resources/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class ListResourceSLZ(serializers.Serializer):
db_module_id = serializers.CharField(required=False, help_text=_("所属DB模块"))
bk_cloud_id = serializers.CharField(required=False, help_text=_("管控区域"))
cluster_type = serializers.CharField(required=False, help_text=_("集群类型"))
tag_ids = serializers.CharField(required=False, help_text=_("标签"))


class ListMySQLResourceSLZ(ListResourceSLZ):
Expand Down
7 changes: 1 addition & 6 deletions dbm-ui/backend/db_services/group/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from backend.db_meta.models import Group, GroupInstance


class GroupSerializer(AuditedSerializer, serializers.ModelSerializer):
class TagSerializer(AuditedSerializer, serializers.ModelSerializer):
instance_count = serializers.SerializerMethodField(help_text=_("实例数量"))

class Meta:
Expand All @@ -32,8 +32,3 @@ class Meta:
def get_instance_count(self, obj):
instance_count = GroupInstance.objects.filter(group_id=obj.id).count()
return instance_count


class GroupMoveInstancesSerializer(serializers.Serializer):
new_group_id = serializers.IntegerField(help_text=_("新分组ID"))
instance_ids = serializers.ListSerializer(help_text=_("待移动实例的ID列表"), child=serializers.IntegerField())
12 changes: 6 additions & 6 deletions dbm-ui/backend/db_services/group/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
)
from backend.db_meta.models import Group
from backend.db_services.group.handlers import GroupHandler
from backend.db_services.group.serializers import GroupMoveInstancesSerializer, GroupSerializer
from backend.db_services.group.serializers import GroupMoveInstancesSerializer, TagSerializer
from backend.iam_app.handlers.drf_perm.base import RejectPermission, get_request_key_id

SWAGGER_TAG = _("分组")
Expand All @@ -35,7 +35,7 @@ class GroupViewSet(viewsets.AuditedModelViewSet):
"""

queryset = Group.objects.all()
serializer_class = GroupSerializer
serializer_class = TagSerializer
pagination_class = AuditedLimitOffsetPagination

# TODO: 暂时屏蔽对influxdb的鉴权
Expand Down Expand Up @@ -74,7 +74,7 @@ def get_queryset(self):

@common_swagger_auto_schema(
operation_summary=_("分组详情"),
responses={status.HTTP_200_OK: GroupSerializer(label=_("分组详情"))},
responses={status.HTTP_200_OK: TagSerializer(label=_("分组详情"))},
tags=[SWAGGER_TAG],
)
def retrieve(self, request, *args, **kwargs):
Expand All @@ -98,7 +98,7 @@ def list(self, request, *args, **kwargs):
@common_swagger_auto_schema(
operation_summary=_("创建新分组"),
auto_schema=ResponseSwaggerAutoSchema,
responses={status.HTTP_200_OK: GroupSerializer(label=_("创建新分组"))},
responses={status.HTTP_200_OK: TagSerializer(label=_("创建新分组"))},
tags=[SWAGGER_TAG],
)
def create(self, request, *args, **kwargs):
Expand All @@ -107,7 +107,7 @@ def create(self, request, *args, **kwargs):
@common_swagger_auto_schema(
operation_summary=_("更新分组信息"),
auto_schema=ResponseSwaggerAutoSchema,
responses={status.HTTP_200_OK: GroupSerializer(label=_("更新分组信息"))},
responses={status.HTTP_200_OK: TagSerializer(label=_("更新分组信息"))},
tags=[SWAGGER_TAG],
)
def update(self, request, *args, **kwargs):
Expand All @@ -116,7 +116,7 @@ def update(self, request, *args, **kwargs):
@common_swagger_auto_schema(
operation_summary=_("删除分组"),
auto_schema=ResponseSwaggerAutoSchema,
responses={status.HTTP_200_OK: GroupSerializer(label=_("删除分组"))},
responses={status.HTTP_200_OK: TagSerializer(label=_("删除分组"))},
tags=[SWAGGER_TAG],
)
def destroy(self, request, *args, **kwargs):
Expand Down
10 changes: 10 additions & 0 deletions dbm-ui/backend/db_services/tag/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- 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.
"""
42 changes: 42 additions & 0 deletions dbm-ui/backend/db_services/tag/handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# -*- 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 typing import Dict, List


class TagHandler:
"""标签的操作类"""

def batch_set_tags(self, tag_ids: List[int]):
"""
给资源批量设置标签
"""
# 1. 判断标签中 key 是否允许多值

# 2. 批量设置标签
pass

def delete_tags(self, tag_ids: List[int]):
"""
删除标签
"""
# 1. 检查标签是否被引用

# 2. 批量删除标签

def create_tags(self, tags: List[Dict[str, str]]):
"""
批量创建标签
"""

def list_tags(self):
"""
标签列表
"""
20 changes: 20 additions & 0 deletions dbm-ui/backend/db_services/tag/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- 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 rest_framework import serializers

from backend.bk_web.serializers import AuditedSerializer


class TagSerializer(AuditedSerializer, serializers.ModelSerializer):
"""
标签序列化器
"""
19 changes: 19 additions & 0 deletions dbm-ui/backend/db_services/tag/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# -*- 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 rest_framework.routers import DefaultRouter

from . import views

routers = DefaultRouter(trailing_slash=True)
routers.register("", views.TagViewSet, basename="tag")

urlpatterns = routers.urls
Loading

0 comments on commit 45ddbd7

Please sign in to comment.