diff --git a/dbm-ui/backend/db_services/redis/resources/redis_cluster/views.py b/dbm-ui/backend/db_services/redis/resources/redis_cluster/views.py index 925c121f5e..8d7ee2b362 100644 --- a/dbm-ui/backend/db_services/redis/resources/redis_cluster/views.py +++ b/dbm-ui/backend/db_services/redis/resources/redis_cluster/views.py @@ -118,6 +118,7 @@ class RedisClusterViewSet(viewsets.ResourceViewSet): ActionEnum.REDIS_VIEW, ActionEnum.REDIS_BACKUP, ActionEnum.REDIS_ACCESS_ENTRY_VIEW, + ActionEnum.REDIS_WEBCONSOLE, ] list_instance_perm_actions = [ActionEnum.REDIS_VIEW] list_external_perm_actions = [ActionEnum.ACCESS_ENTRY_EDIT] diff --git a/dbm-ui/backend/ticket/builders/mysql/mysql_priv_change.py b/dbm-ui/backend/ticket/builders/mysql/mysql_priv_change.py index 7570c030d1..7b3a9ac34a 100644 --- a/dbm-ui/backend/ticket/builders/mysql/mysql_priv_change.py +++ b/dbm-ui/backend/ticket/builders/mysql/mysql_priv_change.py @@ -55,12 +55,13 @@ def build_controller_info(self) -> dict: class MySQLAccountRuleChangeItsmFlowParamBuilder(builders.ItsmParamBuilder): + def get_approvers(self): + approver_list = DBRuleActionLog.get_notifiers(self.ticket.details["rule_id"]) + return ",".join(approver_list) + def get_params(self): params = super().get_params() field_map = {field["key"]: field["value"] for field in params["fields"]} - # 获取权限审批人 - approver_list = DBRuleActionLog.get_notifiers(self.ticket.details["rule_id"]) - field_map["approver"] = ",".join(approver_list) # 审批模式改成会签 field_map["approve_mode"] = ItsmApproveMode.CounterSign # 导出itsm字段 diff --git a/dbm-ui/backend/ticket/builders/redis/redis_toolbox_redis_scale_updown.py b/dbm-ui/backend/ticket/builders/redis/redis_toolbox_redis_scale_updown.py index 9dc534a592..096d15ebaf 100644 --- a/dbm-ui/backend/ticket/builders/redis/redis_toolbox_redis_scale_updown.py +++ b/dbm-ui/backend/ticket/builders/redis/redis_toolbox_redis_scale_updown.py @@ -44,7 +44,7 @@ class BackendGroupSerializer(serializers.Serializer): shard_num = serializers.IntegerField(help_text=_("集群分片数")) group_num = serializers.IntegerField(help_text=_("部署机器组数")) db_version = serializers.CharField(help_text=_("版本号")) - capacity = serializers.IntegerField(help_text=_("当前容量需求")) + capacity = serializers.FloatField(help_text=_("当前容量需求")) future_capacity = serializers.IntegerField(help_text=_("未来容量需求")) online_switch_type = serializers.ChoiceField( help_text=_("切换类型"), choices=SwitchConfirmType.get_choices(), default=SwitchConfirmType.NO_CONFIRM diff --git a/dbm-ui/backend/ticket/builders/redis/redis_toolbox_shard_update.py b/dbm-ui/backend/ticket/builders/redis/redis_toolbox_shard_update.py index 6fa37073d2..10b23d5d6d 100644 --- a/dbm-ui/backend/ticket/builders/redis/redis_toolbox_shard_update.py +++ b/dbm-ui/backend/ticket/builders/redis/redis_toolbox_shard_update.py @@ -48,7 +48,7 @@ class SpecSerializer(serializers.Serializer): current_shard_num = serializers.IntegerField(help_text=_("当前分片数")) cluster_shard_num = serializers.IntegerField(help_text=_("目标分片数")) resource_spec = ResourceSpecSerializer(help_text=_("资源申请")) - capacity = serializers.IntegerField(help_text=_("当前容量需求")) + capacity = serializers.FloatField(help_text=_("当前容量需求")) future_capacity = serializers.IntegerField(help_text=_("未来容量需求")) db_version = serializers.CharField(help_text=_("版本号")) online_switch_type = serializers.ChoiceField( diff --git a/dbm-ui/backend/ticket/builders/redis/redis_toolbox_type_update.py b/dbm-ui/backend/ticket/builders/redis/redis_toolbox_type_update.py index 10c2b86d32..3a8c09e849 100644 --- a/dbm-ui/backend/ticket/builders/redis/redis_toolbox_type_update.py +++ b/dbm-ui/backend/ticket/builders/redis/redis_toolbox_type_update.py @@ -51,7 +51,7 @@ class SpecSerializer(serializers.Serializer): current_cluster_type = serializers.ChoiceField(choices=ClusterType.get_choices(), help_text=_("当前集群类型")) target_cluster_type = serializers.ChoiceField(choices=ClusterType.get_choices(), help_text=_("目标集群类型")) resource_spec = ResourceSpecSerializer(help_text=_("资源申请")) - capacity = serializers.IntegerField(help_text=_("当前容量需求")) + capacity = serializers.FloatField(help_text=_("当前容量需求")) future_capacity = serializers.IntegerField(help_text=_("未来容量需求")) db_version = serializers.CharField(help_text=_("版本号")) online_switch_type = serializers.ChoiceField( diff --git a/dbm-ui/backend/ticket/flow_manager/base.py b/dbm-ui/backend/ticket/flow_manager/base.py index 1dc06f2e1f..f7c495daa1 100644 --- a/dbm-ui/backend/ticket/flow_manager/base.py +++ b/dbm-ui/backend/ticket/flow_manager/base.py @@ -31,6 +31,7 @@ FlowType, FlowTypeConfig, TicketFlowStatus, + TodoStatus, ) from backend.ticket.models import ClusterOperateRecord, Flow, InstanceOperateRecord, TicketFlowsConfig, Todo @@ -265,7 +266,7 @@ def _revoke(self, operator) -> Any: # 停止相关联的todo from backend.ticket.todos import ActionType, TodoActorFactory - todos = Todo.objects.filter(ticket=self.ticket, flow=self.flow_obj) + todos = Todo.objects.filter(ticket=self.ticket, flow=self.flow_obj, status=TodoStatus.TODO) for todo in todos: TodoActorFactory.actor(todo).process(operator, ActionType.TERMINATE, params={}) # 刷新flow和单据状态 --> 终止 diff --git a/dbm-ui/backend/ticket/flow_manager/itsm.py b/dbm-ui/backend/ticket/flow_manager/itsm.py index c26587bc8f..9dfdb3e337 100644 --- a/dbm-ui/backend/ticket/flow_manager/itsm.py +++ b/dbm-ui/backend/ticket/flow_manager/itsm.py @@ -82,13 +82,16 @@ def _status(self) -> str: # 把 ITSM 单据状态映射为本系统内的单据状态 current_status = self.ticket_approval_result["current_status"] approve_result = self.ticket_approval_result["approve_result"] - updater = self.ticket_approval_result["updated_by"] - todo = self.flow_obj.todo_of_flow.first() + # 进行中 if current_status == ItsmTicketStatus.RUNNING: return self.flow_obj.update_status(TicketFlowStatus.RUNNING) + + todo = self.flow_obj.todo_of_flow.first() + updater = self.ticket_approval_result["updated_by"] + # 撤单 - elif current_status == ItsmTicketStatus.REVOKED: + if current_status == ItsmTicketStatus.REVOKED: todo.set_status(username=updater, status=TodoStatus.DONE_FAILED) return self.flow_obj.update_status(TicketFlowStatus.TERMINATED) # 审批通过 diff --git a/dbm-ui/backend/ticket/models/todo.py b/dbm-ui/backend/ticket/models/todo.py index b39fdfb2f0..9516896f37 100644 --- a/dbm-ui/backend/ticket/models/todo.py +++ b/dbm-ui/backend/ticket/models/todo.py @@ -18,6 +18,7 @@ from backend.bk_web.constants import LEN_MIDDLE, LEN_SHORT from backend.bk_web.models import AuditedModel from backend.configuration.models import BizSettings, DBAdministrator +from backend.ticket.builders import BuilderFactory from backend.ticket.constants import ( TODO_RUNNING_STATUS, FlowMsgStatus, @@ -42,17 +43,19 @@ def get_operators(self, todo_type, ticket, operators): biz_helpers = BizSettings.get_assistance(ticket.bk_biz_id) # 构造单据状态与处理人之间的对应关系 - # - 审批中:提单人可撤销,dba可处理 + # - 审批中:提单人可撤销,dba可处理, + # 考虑某些单据审批人是特定配置(数据导出 -- 运维审批),所以从ItsmBuilder获得审批人 # - 待执行:提单人 + 单据协助人 - # - 待继续:提单人 + 单据协助人 + dba - # - 待补货:提单人 + 单据协助人 + dba - # - 已失败:提单人 + 单据协助人 + dba + # - 待继续:dba + 提单人 + 单据协助人 + # - 待补货:dba + 提单人 + 单据协助人 + # - 已失败:dba + 提单人 + 单据协助人 + itsm_builder = BuilderFactory.get_builder_cls(ticket.ticket_type).itsm_flow_builder(ticket) todo_operators_map = { - TodoType.ITSM: dba, + TodoType.ITSM: itsm_builder.get_approvers().split(","), TodoType.APPROVE: creator + biz_helpers, - TodoType.INNER_APPROVE: creator + biz_helpers + dba, - TodoType.RESOURCE_REPLENISH: creator + biz_helpers + dba, - TodoType.INNER_FAILED: creator + biz_helpers + dba, + TodoType.INNER_APPROVE: dba + creator + biz_helpers, + TodoType.RESOURCE_REPLENISH: dba + creator + biz_helpers, + TodoType.INNER_FAILED: dba + creator + biz_helpers, } # 按照顺序去重 operators = list(dict.fromkeys(operators + todo_operators_map.get(todo_type, []))) @@ -109,8 +112,10 @@ def url(self): return f"{env.BK_SAAS_HOST}/my-todos?id={self.ticket.id}" def set_status(self, username, status): - self.status = status + if self.status == status: + return + self.status = status if status in [TodoStatus.DONE_SUCCESS, TodoStatus.DONE_FAILED]: self.done_by = username self.done_at = timezone.now()