diff --git a/dbm-ui/backend/components/bkmonitorv3/client.py b/dbm-ui/backend/components/bkmonitorv3/client.py index a20a352138..4e916b6450 100644 --- a/dbm-ui/backend/components/bkmonitorv3/client.py +++ b/dbm-ui/backend/components/bkmonitorv3/client.py @@ -210,6 +210,11 @@ def __init__(self): url="list_shield/", description=_("获取告警屏蔽列表"), ) + self.get_shield = self.generate_data_api( + method="GET", + url="get_shield/", + description=_("获取告警屏蔽详情"), + ) BKMonitorV3Api = _BKMonitorV3Api() diff --git a/dbm-ui/backend/db_monitor/mock_data.py b/dbm-ui/backend/db_monitor/mock_data.py index 1009d84db6..4a7c3eef9d 100644 --- a/dbm-ui/backend/db_monitor/mock_data.py +++ b/dbm-ui/backend/db_monitor/mock_data.py @@ -645,28 +645,28 @@ "signal": "abnormal", "title_tmpl": "{{business.bk_biz_name}} - {{alarm.name}}{{alarm.display_type}}", "message_tmpl": "{{content.level}}\n{{content.begin_time}}\n{{content.time}}\n{{content.duration}}" - "\n{{content.target_type}}\n{{content.data_source}}\n{{content.content}}" - "\n{{content.current_value}}\n{{content.biz}}\n{{content.target}}" - "\n{{content.dimension}}\n{{content.detail}}\n{{content.assign_detail}}" - "\n{{content.related_info}}", + "\n{{content.target_type}}\n{{content.data_source}}\n{{content.content}}" + "\n{{content.current_value}}\n{{content.biz}}\n{{content.target}}" + "\n{{content.dimension}}\n{{content.detail}}\n{{content.assign_detail}}" + "\n{{content.related_info}}", }, { "signal": "recovered", "title_tmpl": "{{business.bk_biz_name}} - {{alarm.name}}{{alarm.display_type}}", "message_tmpl": "{{content.level}}\n{{content.begin_time}}\n{{content.time}}\n{{content.duration}}" - "\n{{content.target_type}}\n{{content.data_source}}\n{{content.content}}" - "\n{{content.current_value}}\n{{content.biz}}\n{{content.target}}" - "\n{{content.dimension}}\n{{content.detail}}\n{{content.assign_detail}}" - "\n{{content.related_info}}", + "\n{{content.target_type}}\n{{content.data_source}}\n{{content.content}}" + "\n{{content.current_value}}\n{{content.biz}}\n{{content.target}}" + "\n{{content.dimension}}\n{{content.detail}}\n{{content.assign_detail}}" + "\n{{content.related_info}}", }, { "signal": "closed", "title_tmpl": "{{business.bk_biz_name}} - {{alarm.name}}{{alarm.display_type}}", "message_tmpl": "{{content.level}}\n{{content.begin_time}}\n{{content.time}}\n{{content.duration}}" - "\n{{content.target_type}}\n{{content.data_source}}\n{{content.content}}" - "\n{{content.current_value}}\n{{content.biz}}\n{{content.target}}" - "\n{{content.dimension}}\n{{content.detail}}\n{{content.assign_detail}}" - "\n{{content.related_info}}", + "\n{{content.target_type}}\n{{content.data_source}}\n{{content.content}}" + "\n{{content.current_value}}\n{{content.biz}}\n{{content.target}}" + "\n{{content.dimension}}\n{{content.detail}}\n{{content.assign_detail}}" + "\n{{content.related_info}}", }, ], "need_poll": True, @@ -737,11 +737,8 @@ "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 + "dimension_config": {"scope_type": "ip", "target": [{"bk_host_id": 1, "ip": "127.0.0.1", "bk_cloud_id": 0}]}, + "bk_biz_id": 3, } # 维度屏蔽 @@ -749,24 +746,17 @@ "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}, + "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": "tags.appid", - "method": "eq", - "value": ["100706"], - "name": "appid" - } + {"condition": "and", "key": "appid", "method": "eq", "value": ["100706"], "name": "appid"} ], - "strategy_id": "" + "strategy_id": "", }, - "bk_biz_id": 3 + "bk_biz_id": 3, } # 策略屏蔽 @@ -782,32 +772,18 @@ "id": [98043], "level": [2], "dimension_conditions": [ - { - "condition": "and", - "key": "appid", - "method": "eq", - "value": ["11111111"], - "name": "dbm_meta app id" - } - ] + {"condition": "and", "key": "appid", "method": "eq", "value": ["11111111"], "name": "dbm_meta app id"} + ], }, "level": [2], - "bk_biz_id": 3 + "bk_biz_id": 3, } -# 策略屏蔽 -UPDATE_ALARM_SHIELD = { - "bk_biz_id": 3, - "id": 1, - "begin_time": "2024-11-21 00:00:00", - "end_time": "2024-11-21 23:59:59", - "description": "xxxx" -} +# 更新策略屏蔽 +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 = {"bk_biz_id": 3} LIST_ALARM_SHIELD_RESPONSE = [ { @@ -821,37 +797,19 @@ "is_enabled": True, "scope_type": "", "dimension_config": { - "strategy_id": [ - 98043 - ], - "level": [ - 2 - ], + "strategy_id": [98043], + "level": [2], "dimension_conditions": [ - { - "key": "appid", - "value": [ - "11111111" - ], - "method": "eq", - "condition": "and", - "name": "dbm_meta app id" - } - ] + {"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": "" - }, + "cycle_config": {"type": 1, "week_list": [], "day_list": [], "begin_time": "", "end_time": ""}, "shield_notice": False, "notice_config": "{}", "description": "xxxx", "source": "", - "update_user": "admin" + "update_user": "admin", }, { "id": 769271, @@ -865,31 +823,17 @@ "scope_type": "", "dimension_config": { "dimension_conditions": [ - { - "key": "tags.appid", - "value": [ - "100706" - ], - "method": "eq", - "condition": "and", - "name": "appid" - } + {"key": "appid", "value": ["100706"], "method": "eq", "condition": "and", "name": "appid"} ], - "_strategy_id": 0 + "_strategy_id": 0, }, "content": "", - "cycle_config": { - "type": 1, - "week_list": [], - "day_list": [], - "begin_time": "", - "end_time": "" - }, + "cycle_config": {"type": 1, "week_list": [], "day_list": [], "begin_time": "", "end_time": ""}, "shield_notice": False, "notice_config": "{}", "description": "test", "source": "", - "update_user": "admin" + "update_user": "admin", }, { "id": 769270, @@ -902,27 +846,14 @@ "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 - } - ] + "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": "" - }, + "cycle_config": {"type": 1, "week_list": [], "day_list": [], "begin_time": "", "end_time": ""}, "shield_notice": False, "notice_config": "{}", "description": "xxxx", "source": "", - "update_user": "admin" + "update_user": "admin", }, - ] diff --git a/dbm-ui/backend/db_monitor/serializers.py b/dbm-ui/backend/db_monitor/serializers.py index 2724f56572..112c558ddb 100644 --- a/dbm-ui/backend/db_monitor/serializers.py +++ b/dbm-ui/backend/db_monitor/serializers.py @@ -260,7 +260,7 @@ def to_internal_value(self, data): class CreateAlarmShieldSerializer(serializers.Serializer): category = serializers.CharField(help_text=_("屏蔽类型")) - bk_biz_id = serializers.IntegerField(help_text=_("业务ID")) + 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=_("开始时间")) @@ -270,16 +270,25 @@ class CreateAlarmShieldSerializer(serializers.Serializer): 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): - bk_biz_id = serializers.IntegerField(help_text=_("业务ID")) - id = serializers.IntegerField(help_text=_("屏蔽 ID")) 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} diff --git a/dbm-ui/backend/db_monitor/views/shield.py b/dbm-ui/backend/db_monitor/views/shield.py index cad71f3927..8d84c58c51 100644 --- a/dbm-ui/backend/db_monitor/views/shield.py +++ b/dbm-ui/backend/db_monitor/views/shield.py @@ -9,6 +9,7 @@ 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 @@ -18,10 +19,19 @@ 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): - # TODO 权限控制 + 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, @@ -66,20 +76,23 @@ def create(self, request): request_body=serializers.DisableAlarmShieldSerializer(), tags=[SWAGGER_TAG], ) - def disable(self, request): - return Response(BKMonitorV3Api.disable_shield(self.validated_data)) + @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): + 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, - "description": format_shield_description(data["bk_biz_id"], description=data["description"]), + "id": pk, + "description": format_shield_description(shield["bk_biz_id"], description=data["description"]), } ) return Response(BKMonitorV3Api.edit_shield(data))