Skip to content

Commit

Permalink
feat(backend): 支持告警屏蔽 #8017
Browse files Browse the repository at this point in the history
feat(backend): 支持告警屏蔽 #8017
  • Loading branch information
zhangzhw8 committed Nov 27, 2024
1 parent bdae8c5 commit 5f40078
Show file tree
Hide file tree
Showing 7 changed files with 320 additions and 1 deletion.
5 changes: 4 additions & 1 deletion dbm-ui/backend/bk_web/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ def validated_data(self):
data.setdefault("bk_username", bk_username)
data.setdefault("bk_app_code", bk_app_code)

serializer = self.serializer_class or self.get_serializer_class()
if self.serializer_class and self.serializer_class is not serializers.Serializer:
serializer = self.serializer_class
else:
serializer = self.get_serializer_class()
return self.params_validate(serializer, data)

def params_validate(self, slz_cls, context: Optional[Dict] = None, init_params: Optional[Dict] = None, **kwargs):
Expand Down
25 changes: 25 additions & 0 deletions dbm-ui/backend/components/bkmonitorv3/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,31 @@ def __init__(self):
url="edit_action_config/",
description=_("编辑处理套餐"),
)
self.add_shield = self.generate_data_api(
method="POST",
url="add_shield/",
description=_("新增告警屏蔽"),
)
self.disable_shield = self.generate_data_api(
method="POST",
url="disable_shield/",
description=_("解除告警屏蔽"),
)
self.edit_shield = self.generate_data_api(
method="POST",
url="edit_shield/",
description=_("编辑告警屏蔽"),
)
self.list_shield = self.generate_data_api(
method="POST",
url="list_shield/",
description=_("获取告警屏蔽列表"),
)
self.get_shield = self.generate_data_api(
method="GET",
url="get_shield/",
description=_("获取告警屏蔽详情"),
)


BKMonitorV3Api = _BKMonitorV3Api()
131 changes: 131 additions & 0 deletions dbm-ui/backend/db_monitor/mock_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,138 @@
"user_groups": [20],
},
}

CREATE_POLICY = [
{"name": "influxDB-n6hfH", "target_priority": 0, "details": CREATE_POLICY_DETAILS},
{"name": "MySql123", "target_priority": 1, "details": CREATE_POLICY_DETAILS},
]

# 范围屏蔽(主机)
CREATE_ALARM_SHIELD_FOR_IP_SCOPE = {
"category": "scope",
"begin_time": "2024-11-21 00:00:00",
"end_time": "2024-11-21 23:59:59",
"cycle_config": {"begin_time": "", "end_time": "", "day_list": [], "week_list": [], "type": 1},
"shield_notice": False,
"notice_config": {},
"description": "xxxx",
"dimension_config": {"scope_type": "ip", "target": [{"bk_host_id": 1, "ip": "127.0.0.1", "bk_cloud_id": 0}]},
"bk_biz_id": 3,
}

# 维度屏蔽
CREATE_ALARM_SHIELD_FOR_DIMENSION = {
"category": "dimension",
"begin_time": "2024-11-21 00:00:00",
"end_time": "2024-11-21 23:59:59",
"cycle_config": {"begin_time": "", "end_time": "", "day_list": [], "week_list": [], "type": 1},
"shield_notice": False,
"notice_config": {},
"description": "test",
"dimension_config": {
"dimension_conditions": [
{"condition": "and", "key": "appid", "method": "eq", "value": ["100706"], "name": "appid"}
],
"strategy_id": "",
},
"bk_biz_id": 3,
}

# 策略屏蔽
CREATE_ALARM_SHIELD_FOR_STRATEGY = {
"category": "strategy",
"begin_time": "2024-11-21 00:00:00",
"end_time": "2024-11-21 23:59:59",
"cycle_config": {"begin_time": "", "end_time": "", "day_list": [], "week_list": [], "type": 1},
"shield_notice": False,
"notice_config": {},
"description": "xxxx",
"dimension_config": {
"id": [98043],
"level": [2],
"dimension_conditions": [
{"condition": "and", "key": "appid", "method": "eq", "value": ["11111111"], "name": "dbm_meta app id"}
],
},
"level": [2],
"bk_biz_id": 3,
}


# 更新策略屏蔽
UPDATE_ALARM_SHIELD = {"begin_time": "2024-11-21 00:00:00", "end_time": "2024-12-21 23:59:59", "description": "update"}

LIST_ALARM_SHIELD = {"bk_biz_id": 3}

LIST_ALARM_SHIELD_RESPONSE = [
{
"id": 769279,
"bk_biz_id": 5005578,
"category": "strategy",
"status": 1,
"begin_time": "2024-11-21 00:00:00",
"end_time": "2024-11-21 23:59:59",
"failure_time": "2024-11-21 23:59:59",
"is_enabled": True,
"scope_type": "",
"dimension_config": {
"strategy_id": [98043],
"level": [2],
"dimension_conditions": [
{"key": "appid", "value": ["11111111"], "method": "eq", "condition": "and", "name": "dbm_meta app id"}
],
},
"content": "",
"cycle_config": {"type": 1, "week_list": [], "day_list": [], "begin_time": "", "end_time": ""},
"shield_notice": False,
"notice_config": "{}",
"description": "xxxx",
"source": "",
"update_user": "admin",
},
{
"id": 769271,
"bk_biz_id": 5005578,
"category": "dimension",
"status": 1,
"begin_time": "2024-11-21 00:00:00",
"end_time": "2024-11-21 23:59:59",
"failure_time": "2024-11-21 23:59:59",
"is_enabled": True,
"scope_type": "",
"dimension_config": {
"dimension_conditions": [
{"key": "appid", "value": ["100706"], "method": "eq", "condition": "and", "name": "appid"}
],
"_strategy_id": 0,
},
"content": "",
"cycle_config": {"type": 1, "week_list": [], "day_list": [], "begin_time": "", "end_time": ""},
"shield_notice": False,
"notice_config": "{}",
"description": "test",
"source": "",
"update_user": "admin",
},
{
"id": 769270,
"bk_biz_id": 5005578,
"category": "scope",
"status": 1,
"begin_time": "2024-11-21 00:00:00",
"end_time": "2024-11-21 23:59:59",
"failure_time": "2024-11-21 23:59:59",
"is_enabled": True,
"scope_type": "ip",
"dimension_config": {
"bk_target_ip": [{"bk_host_id": 1, "bk_target_ip": "127.0.0.1", "bk_target_cloud_id": 0}]
},
"content": "",
"cycle_config": {"type": 1, "week_list": [], "day_list": [], "begin_time": "", "end_time": ""},
"shield_notice": False,
"notice_config": "{}",
"description": "xxxx",
"source": "",
"update_user": "admin",
},
]
53 changes: 53 additions & 0 deletions dbm-ui/backend/db_monitor/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,3 +256,56 @@ def to_internal_value(self, data):

data.update({"ticket_types": ticket_types, "creator": "bkmonitor"})
return data


class CreateAlarmShieldSerializer(serializers.Serializer):
category = serializers.CharField(help_text=_("屏蔽类型"))
bk_biz_id = serializers.IntegerField(help_text=_("业务ID"), required=True)
dimension_config = serializers.DictField(help_text=_("屏蔽维度配置"))
shield_notice = serializers.BaseSerializer(help_text=_("告警屏蔽通知"), default=False)
begin_time = serializers.CharField(help_text=_("开始时间"))
end_time = serializers.CharField(help_text=_("结束时间"))
description = serializers.CharField(help_text=_("屏蔽原因"))

def to_internal_value(self, data):
return data

def validate(self, attrs):
# 取维度中的 appid 维度作为业务,这里要求屏蔽策略的维度一定要有业务
for condition in attrs["dimension_config"]["dimension_conditions"]:
if condition["key"] == "appid":
attrs["bk_biz_id"] = condition["value"][0]
if "bk_biz_id" not in attrs:
raise serializers.ValidationError(_("维度配置中必须包含业务ID"))
return attrs

class Meta:
swagger_schema_fields = {"example": mock_data.CREATE_ALARM_SHIELD_FOR_DIMENSION}


class UpdateAlarmShieldSerializer(serializers.Serializer):
begin_time = serializers.CharField(help_text=_("开始时间"))
end_time = serializers.CharField(help_text=_("结束时间"))
description = serializers.CharField(help_text=_("屏蔽原因"))
cycle_config = serializers.DictField(help_text=_("屏蔽周期"))
shield_notice = serializers.BooleanField(help_text=_("是否有屏蔽通知"), default=False)

class Meta:
swagger_schema_fields = {"example": mock_data.UPDATE_ALARM_SHIELD}


class DisableAlarmShieldSerializer(serializers.Serializer):
id = serializers.IntegerField(help_text=_("屏蔽 ID"))


class ListAlarmShieldSerializer(serializers.Serializer):
bk_biz_id = serializers.IntegerField(help_text=_("业务ID"))
is_active = serializers.BooleanField(help_text=_("是否生效"), default=True)
time_range = serializers.CharField(help_text=_("时间范围"), required=False)
page = serializers.IntegerField(help_text=_("页码"), default=1)
page_size = serializers.IntegerField(help_text=_("每页数量"), default=10)
category = serializers.CharField(help_text=_("屏蔽类型"), required=False)
conditions = serializers.ListSerializer(help_text=_("查询条件"), child=serializers.DictField(), required=False)

class Meta:
swagger_schema_fields = {"example": mock_data.LIST_ALARM_SHIELD}
2 changes: 2 additions & 0 deletions dbm-ui/backend/db_monitor/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
from backend.db_monitor.views.grafana import MonitorGrafanaViewSet
from backend.db_monitor.views.notice_group import MonitorNoticeGroupViewSet
from backend.db_monitor.views.policy import MonitorPolicyViewSet
from backend.db_monitor.views.shield import AlarmShieldView

routers = DefaultRouter(trailing_slash=True)

routers.register(r"grafana", MonitorGrafanaViewSet, basename="grafana")
routers.register(r"policy", MonitorPolicyViewSet, basename="policy")
routers.register(r"notice_group", MonitorNoticeGroupViewSet, basename="notice_group")
routers.register(r"duty_rule", MonitorDutyRuleViewSet, basename="duty_rule")
routers.register(r"alarm_shield", AlarmShieldView, basename="alarm_shield")

urlpatterns = routers.urls
7 changes: 7 additions & 0 deletions dbm-ui/backend/db_monitor/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,10 @@ def create_bklog_collector(startswith: str = ""):
logger.error(_("采集项创建失败,请联系管理员。错误信息:{err}").format(err=err))

return True


def format_shield_description(bk_biz_id, description=""):
prefix = f"[dbm:appid={bk_biz_id}]"
# 先删后补,避免出现多个前缀
description.replace(prefix, "").strip()
return f"{prefix}{description}"
98 changes: 98 additions & 0 deletions dbm-ui/backend/db_monitor/views/shield.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 gettext as _
from rest_framework.decorators import action
from rest_framework.response import Response

from backend import env
from backend.bk_web.swagger import common_swagger_auto_schema
from backend.bk_web.viewsets import SystemViewSet
from backend.components import BKMonitorV3Api
from backend.db_monitor import serializers
from backend.db_monitor.constants import SWAGGER_TAG
from backend.db_monitor.utils import format_shield_description
from backend.iam_app.handlers.drf_perm.base import DBManagePermission, RejectPermission


class AlarmShieldView(SystemViewSet):
def _get_custom_permissions(self):
if self.action == "list":
return [DBManagePermission()]
elif self.action == "create":
return [DBManagePermission()]
elif self.action in ["disable", "update"]:
return [DBManagePermission()]
return [RejectPermission()]

def get_serializer_class(self):
action_slz_map = {
"list": serializers.ListAlarmShieldSerializer,
"create": serializers.CreateAlarmShieldSerializer,
"update": serializers.UpdateAlarmShieldSerializer,
"disable": serializers.DisableAlarmShieldSerializer,
}
return action_slz_map.get(self.action)

@common_swagger_auto_schema(
operation_summary=_("告警屏蔽列表"),
query_serializer=serializers.ListAlarmShieldSerializer(),
tags=[SWAGGER_TAG],
)
def list(self, request):
data = self.validated_data
data.update(
{
"bk_biz_id": env.DBA_APP_BK_BIZ_ID,
"conditions": [{"key": "description", "value": format_shield_description(data["bk_biz_id"])}],
}
)
return Response(BKMonitorV3Api.list_shield(data))

@common_swagger_auto_schema(
operation_summary=_("新增告警屏蔽"),
request_body=serializers.CreateAlarmShieldSerializer(),
tags=[SWAGGER_TAG],
)
def create(self, request):
data = self.validated_data
data.update(
{
"bk_biz_id": env.DBA_APP_BK_BIZ_ID,
"description": format_shield_description(data["bk_biz_id"], description=data["description"]),
}
)
return Response(BKMonitorV3Api.add_shield(data))

@common_swagger_auto_schema(
operation_summary=_("解除告警屏蔽"),
request_body=serializers.DisableAlarmShieldSerializer(),
tags=[SWAGGER_TAG],
)
@action(detail=True, methods=["POST"])
def disable(self, request, pk):
return Response(BKMonitorV3Api.disable_shield({"bk_biz_id": env.DBA_APP_BK_BIZ_ID, "id": pk}))

@common_swagger_auto_schema(
operation_summary=_("编辑告警屏蔽"),
request_body=serializers.UpdateAlarmShieldSerializer(),
tags=[SWAGGER_TAG],
)
def update(self, request, pk):
shield = BKMonitorV3Api.get_shield({"bk_biz_id": env.DBA_APP_BK_BIZ_ID, "id": pk})
data = self.validated_data
data.update(
{
"bk_biz_id": env.DBA_APP_BK_BIZ_ID,
"id": pk,
"description": format_shield_description(shield["bk_biz_id"], description=data["description"]),
}
)
return Response(BKMonitorV3Api.edit_shield(data))

0 comments on commit 5f40078

Please sign in to comment.