Skip to content

Commit

Permalink
feat(backend): 支持导出接口 #2700
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangzhw8 committed Dec 21, 2023
1 parent eeb070d commit 7c8b97d
Show file tree
Hide file tree
Showing 25 changed files with 172 additions and 42 deletions.
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/bigdata/es/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

from rest_framework.routers import DefaultRouter

from backend.db_services.bigdata.es.views import EsClusterViewSet
from backend.db_services.bigdata.es.views import EsClusterViewSetBigdata

router = DefaultRouter(trailing_slash=True)
router.register(r"es_resources", EsClusterViewSet, basename="es_resources")
router.register(r"es_resources", EsClusterViewSetBigdata, basename="es_resources")

urlpatterns = router.urls
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/bigdata/es/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from backend.db_services.bigdata.es import constants
from backend.db_services.bigdata.es.query import ESListRetrieveResource
from backend.db_services.bigdata.resources import yasg_slz
from backend.db_services.bigdata.resources.views import ResourceViewSet
from backend.db_services.bigdata.resources.views import BigdataResourceViewSet
from backend.db_services.dbbase.resources import serializers


Expand Down Expand Up @@ -80,7 +80,7 @@
tags=[constants.RESOURCE_TAG],
),
)
class EsClusterViewSet(ResourceViewSet):
class EsClusterViewSetBigdata(BigdataResourceViewSet):
query_class = ESListRetrieveResource
query_serializer_class = serializers.ListResourceSLZ

Expand Down
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/bigdata/hdfs/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

from rest_framework.routers import DefaultRouter

from backend.db_services.bigdata.hdfs.views import HDFSClusterViewSet
from backend.db_services.bigdata.hdfs.views import HDFSClusterViewSetBigdata

router = DefaultRouter(trailing_slash=True)
router.register(r"hdfs_resources", HDFSClusterViewSet, basename="hdfs_resources")
router.register(r"hdfs_resources", HDFSClusterViewSetBigdata, basename="hdfs_resources")

urlpatterns = router.urls
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/bigdata/hdfs/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from backend.db_services.bigdata.hdfs.constants import XML_HEADER, XML_LINE_SEPARATOR, XML_TAB_SEPARATOR
from backend.db_services.bigdata.hdfs.query import HDFSListRetrieveResource
from backend.db_services.bigdata.resources import yasg_slz
from backend.db_services.bigdata.resources.views import ResourceViewSet
from backend.db_services.bigdata.resources.views import BigdataResourceViewSet
from backend.db_services.dbbase.resources import serializers
from backend.flow.consts import ConfigTypeEnum, LevelInfoEnum

Expand Down Expand Up @@ -80,7 +80,7 @@
tags=[constants.RESOURCE_TAG],
),
)
class HDFSClusterViewSet(ResourceViewSet):
class HDFSClusterViewSetBigdata(BigdataResourceViewSet):
query_class = HDFSListRetrieveResource
query_serializer_class = serializers.ListResourceSLZ

Expand Down
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/bigdata/influxdb/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

from rest_framework.routers import DefaultRouter

from backend.db_services.bigdata.influxdb.views import InfluxDBClusterViewSet
from backend.db_services.bigdata.influxdb.views import InfluxDBClusterViewSetBigdata

router = DefaultRouter(trailing_slash=True)
router.register(r"influxdb_resources", InfluxDBClusterViewSet, basename="influxdb_resources")
router.register(r"influxdb_resources", InfluxDBClusterViewSetBigdata, basename="influxdb_resources")

urlpatterns = router.urls
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/bigdata/influxdb/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from backend.db_services.bigdata.influxdb.query import InfluxDBListRetrieveResource
from backend.db_services.bigdata.influxdb.serializers import ListInfluxDBInstancesSerializer
from backend.db_services.bigdata.resources import yasg_slz
from backend.db_services.bigdata.resources.views import ResourceViewSet
from backend.db_services.bigdata.resources.views import BigdataResourceViewSet
from backend.db_services.dbbase.resources import serializers


Expand Down Expand Up @@ -54,6 +54,6 @@
tags=[constants.RESOURCE_TAG],
),
)
class InfluxDBClusterViewSet(ResourceViewSet):
class InfluxDBClusterViewSetBigdata(BigdataResourceViewSet):
query_class = InfluxDBListRetrieveResource
query_serializer_class = serializers.ListResourceSLZ
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/bigdata/kafka/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

from rest_framework.routers import DefaultRouter

from backend.db_services.bigdata.kafka.views import KafkaClusterViewSet
from backend.db_services.bigdata.kafka.views import KafkaClusterViewSetBigdata

router = DefaultRouter(trailing_slash=True)
router.register(r"kafka_resources", KafkaClusterViewSet, basename="kafka_resources")
router.register(r"kafka_resources", KafkaClusterViewSetBigdata, basename="kafka_resources")

urlpatterns = router.urls
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/bigdata/kafka/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from backend.db_services.bigdata.kafka import constants
from backend.db_services.bigdata.kafka.query import KafkaListRetrieveResource
from backend.db_services.bigdata.resources import yasg_slz
from backend.db_services.bigdata.resources.views import ResourceViewSet
from backend.db_services.bigdata.resources.views import BigdataResourceViewSet
from backend.db_services.dbbase.resources import serializers


Expand Down Expand Up @@ -70,6 +70,6 @@
tags=[constants.RESOURCE_TAG],
),
)
class KafkaClusterViewSet(ResourceViewSet):
class KafkaClusterViewSetBigdata(BigdataResourceViewSet):
query_class = KafkaListRetrieveResource
query_serializer_class = serializers.ListResourceSLZ
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/bigdata/pulsar/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

from rest_framework.routers import DefaultRouter

from backend.db_services.bigdata.pulsar.views import PulsarClusterViewSet
from backend.db_services.bigdata.pulsar.views import PulsarClusterViewSetBigdata

router = DefaultRouter(trailing_slash=True)
router.register(r"pulsar_resources", PulsarClusterViewSet, basename="pulsar_resources")
router.register(r"pulsar_resources", PulsarClusterViewSetBigdata, basename="pulsar_resources")

urlpatterns = router.urls
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/bigdata/pulsar/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from backend.db_services.bigdata.pulsar import constants
from backend.db_services.bigdata.pulsar.query import PulsarListRetrieveResource
from backend.db_services.bigdata.resources import yasg_slz
from backend.db_services.bigdata.resources.views import ResourceViewSet
from backend.db_services.bigdata.resources.views import BigdataResourceViewSet
from backend.db_services.dbbase.resources import serializers


Expand Down Expand Up @@ -70,6 +70,6 @@
tags=[constants.RESOURCE_TAG],
),
)
class PulsarClusterViewSet(ResourceViewSet):
class PulsarClusterViewSetBigdata(BigdataResourceViewSet):
query_class = PulsarListRetrieveResource
query_serializer_class = serializers.ListResourceSLZ
13 changes: 6 additions & 7 deletions dbm-ui/backend/db_services/bigdata/resources/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@
from backend.components.dbconfig.constants import FormatType, LevelName
from backend.db_meta.enums import ClusterType
from backend.db_meta.models.cluster import Cluster
from backend.db_services.bigdata.resources import constants, yasg_slz
from backend.db_services.dbbase.resources.constants import ResourceNodeType
from backend.db_services.dbbase.resources.serializers import ClusterSLZ, SearchResourceTreeSLZ
from backend.db_services.dbbase.resources.viewsets import ResourceViewSet
from backend.db_services.dbbase.resources.yasg_slz import ResourceTreeSLZ
from backend.flow.consts import ConfigTypeEnum, LevelInfoEnum, UserName
from backend.flow.utils.pulsar.consts import PulsarConfigEnum

from ...dbbase.resources.constants import ResourceNodeType
from ...dbbase.resources.serializers import ClusterSLZ, SearchResourceTreeSLZ
from ...dbbase.resources.viewsets import ResourceViewSet as BaseResourceViewSet
from ...dbbase.resources.yasg_slz import ResourceTreeSLZ
from . import constants, yasg_slz


class ResourceFilterBackend(filters.DjangoFilterBackend):
def get_filterset_kwargs(self, request, queryset, view):
Expand Down Expand Up @@ -78,7 +77,7 @@ def get_filterset_kwargs(self):
return {"bk_biz_id": self.kwargs["bk_biz_id"]}


class ResourceViewSet(BaseResourceViewSet):
class BigdataResourceViewSet(ResourceViewSet):
def _get_password(cls, cluster, username, port=0):
"""查询密码"""
query_params = {
Expand Down
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/bigdata/riak/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

from rest_framework.routers import DefaultRouter

from backend.db_services.bigdata.riak.views import RiakClusterViewSet
from backend.db_services.bigdata.riak.views import RiakClusterViewSetBigdata

router = DefaultRouter(trailing_slash=True)
router.register(r"riak_resources", RiakClusterViewSet, basename="riak_resources")
router.register(r"riak_resources", RiakClusterViewSetBigdata, basename="riak_resources")

urlpatterns = router.urls
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/bigdata/riak/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from backend.bk_web.swagger import common_swagger_auto_schema
from backend.db_services.bigdata.kafka import constants
from backend.db_services.bigdata.resources import yasg_slz
from backend.db_services.bigdata.resources.views import ResourceViewSet
from backend.db_services.bigdata.resources.views import BigdataResourceViewSet
from backend.db_services.bigdata.riak.query import RiakListRetrieveResource
from backend.db_services.dbbase.resources import serializers

Expand Down Expand Up @@ -70,6 +70,6 @@
tags=[constants.RESOURCE_TAG],
),
)
class RiakClusterViewSet(ResourceViewSet):
class RiakClusterViewSetBigdata(BigdataResourceViewSet):
query_class = RiakListRetrieveResource
query_serializer_class = serializers.ListResourceSLZ
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/dbbase/resources/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ class ResourceLimitOffsetPagination(AuditedLimitOffsetPagination):
count = 0

def paginate_list(self, request, bk_biz_id: int, query_method: Callable, query_params: Dict):

limit_query_param = request.query_params.get(self.limit_query_param)
# 支持返回全部数据:/list/?limit=-1
if request.query_params.get(self.limit_query_param) == "-1":
if str(limit_query_param) == "-1":
self.limit = -1
else:
self.limit = self.get_limit(request)
Expand Down
78 changes: 78 additions & 0 deletions dbm-ui/backend/db_services/dbbase/resources/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from backend.db_meta.enums import ClusterEntryType
from backend.db_meta.models import Cluster, ClusterEntry, Machine
from backend.flow.utils.dns_manage import DnsManage
from backend.utils.excel import ExcelHandler


@attr.s
Expand All @@ -27,6 +28,7 @@ class ResourceList:

class ListRetrieveResource(abc.ABC):
fields = [{"name": _("业务"), "key": "bk_biz_name"}]
cluster_types = []

@classmethod
@abc.abstractmethod
Expand Down Expand Up @@ -108,3 +110,79 @@ def get_topo_graph(cls, bk_biz_id: int, cluster_id: int) -> dict:
@classmethod
def get_fields(cls) -> List[Dict[str, str]]:
return cls.fields

@classmethod
def export_cluster(cls, bk_biz_id: int):
# 获取所有符合条件的集群对象
clusters = Cluster.objects.prefetch_related(
"storageinstance_set", "proxyinstance_set", "storageinstance_set__machine", "proxyinstance_set__machine"
).filter(bk_biz_id=bk_biz_id, cluster_type__in=cls.cluster_types)

# 初始化用于存储Excel数据的字典列表
excel_data_dict__list = []
headers = [
"cluster_id",
"cluster_name",
"cluster_alias",
"cluster_type",
"master_domain",
"major_version",
"region",
"disaster_tolerance_level",
]
# 遍历所有的集群对象
for cluster in clusters:

# 创建一个空字典来保存当前集群的信息
cluster_info = {
"cluster_id": cluster.id,
"cluster_name": cluster.name,
"cluster_alias": cluster.alias,
"cluster_type": cluster.cluster_type,
"master_domain": cluster.immute_domain,
"major_version": cluster.major_version,
"region": cluster.region,
"disaster_tolerance_level": cluster.get_disaster_tolerance_level_display(),
}

# 遍历当前集群中的存储实例
for storage in cluster.storageinstance_set.all():

# 获取存储实例所属角色
role = storage.instance_role

# 如果该角色已经存在于集群信息字典中,则添加新的IP和端口;否则,更新字典的值
if role in cluster_info:
cluster_info[role] += f"\n{storage.machine.ip}#{storage.port}"
else:
if role not in headers:
headers.append(role)
cluster_info[role] = f"{storage.machine.ip}#{storage.port}"

# 遍历当前集群中的代理实例
for proxy in cluster.proxyinstance_set.all():

# 获取代理实例所属角色
role = proxy.instance_role

# 如果该角色已经存在于集群信息字典中,则添加新的IP和端口;否则,更新字典的值
if role in cluster_info:
cluster_info[role] += f"\n{proxy.machine.ip}#{proxy.port}"
else:
if role not in headers:
headers.append(role)
headers.append(role)
cluster_info[role] = f"{proxy.machine.ip}#{proxy.port}"

# 将当前集群的信息追加到excel_data_dict__list列表中
excel_data_dict__list.append(cluster_info)

wb = ExcelHandler.serialize(excel_data_dict__list, header=headers, match_header=True)
return ExcelHandler.response(wb, f"biz_{bk_biz_id}_clusters.xlsx")

@classmethod
def export_instance(cls, bk_biz_id: int):
headers = []
excel_data_dict__list = []
wb = ExcelHandler.serialize(excel_data_dict__list, header=headers, match_header=True)
return ExcelHandler.response(wb, f"biz_{bk_biz_id}_instances.xlsx")
10 changes: 10 additions & 0 deletions dbm-ui/backend/db_services/dbbase/resources/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,15 @@ def get_topo_graph(self, request, bk_biz_id: int, cluster_id: int):
"""获取拓扑图"""
return Response(self.query_class.get_topo_graph(bk_biz_id, cluster_id))

@action(methods=["GET"], detail=False, url_path="export_cluster")
def export_cluster(self, request, bk_biz_id: int):
"""导出集群数据为 excel 文件"""
return self.query_class.export_cluster(bk_biz_id)

@action(methods=["GET"], detail=False, url_path="export_instance")
def export_instance(self, request, bk_biz_id: int):
"""导出实例数据为 excel 文件"""
return self.query_class.export_instance(bk_biz_id)

def _paginate_resource_list(self, request, bk_biz_id: int):
return self.paginator.paginate_resource_list(request, bk_biz_id, self)
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class ListRetrieveResource(query.ListRetrieveResource):
"""查看 mysql dbha 架构的资源"""

cluster_type = ClusterType.TenDBHA
cluster_types = [ClusterType.TenDBHA]

fields = [
{"name": _("集群名"), "key": "cluster_name"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class ListRetrieveResource(query.ListRetrieveResource):
"""查看 mysql 单点部署的资源"""

cluster_type = ClusterType.TenDBSingle
cluster_types = [ClusterType.TenDBSingle]

fields = [
{"name": _("集群名"), "key": "cluster_name"},
Expand Down
20 changes: 17 additions & 3 deletions dbm-ui/backend/utils/excel.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,20 @@ def paser_matrix(cls, excel: Union[BytesIO, str]) -> Dict[str, Dict[str, Any]]:

@classmethod
def serialize(
cls, data_dict__list: List[Dict], template: str = None, header: List = None, header_style: List = None
cls,
data_dict__list: List[Dict],
template: str = None,
header: List = None,
header_style: List = None,
match_header: bool = False,
) -> Workbook:
"""
- 将数据字典序列化为excel对象
:param data_dict__list: 数据字典
:param template: excel模板路径(优先以模板的头部样式作为excel的头部)
:param header: excel数据头
:param header_style: excel的头部样式(颜色)
:param match_header: 数据是否匹配表头,如果为True,则根据 header 严格匹配列名,若不存在,则在该 cell 填充空
"""

wb: Workbook = Workbook()
Expand All @@ -123,8 +129,16 @@ def serialize(

# 数据写入单元格
for row, data_dict in enumerate(data_dict__list):
for col, value in enumerate(list(data_dict.values())):
sheet.cell(row + first_data_row, col + 1, value)
if match_header:
# 如果match_header为True,则根据 header 严格匹配列名,若不存在,则在该 cell 填充空
for col, header_name in enumerate(header):
if header_name not in data_dict:
sheet.cell(row + first_data_row, col + 1).value = ""
else:
sheet.cell(row + first_data_row, col + 1, data_dict[header_name])
else:
for col, value in enumerate(list(data_dict.values())):
sheet.cell(row + first_data_row, col + 1, value)

# 自适应设置行高和列宽
cls._adapt_sheet_weight_height(sheet=sheet, first_header_row=first_data_row - 1)
Expand Down
4 changes: 2 additions & 2 deletions helm-charts/bk-dbm/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,5 @@ dependencies:
description: A Helm chart for bk-dbm
name: bk-dbm
type: application
version: 1.3.0-alpha.27
appVersion: 1.3.0-alpha.27
version: 1.3.0-alpha.28
appVersion: 1.3.0-alpha.28
Loading

0 comments on commit 7c8b97d

Please sign in to comment.