Skip to content

Commit

Permalink
feat(backend): 单据状态细化 #6755
Browse files Browse the repository at this point in the history
  • Loading branch information
iSecloud committed Nov 13, 2024
1 parent e94bbe1 commit 5eb1893
Show file tree
Hide file tree
Showing 27 changed files with 736 additions and 391 deletions.
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/bigdata/resources/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from backend.db_proxy.models import ClusterExtension
from backend.db_services.dbbase.resources import query
from backend.db_services.ipchooser.query.resource import ResourceQueryHelper
from backend.ticket.constants import TicketFlowStatus
from backend.ticket.constants import TICKET_RUNNING_STATUS
from backend.ticket.models import InstanceOperateRecord
from backend.utils.time import datetime2str

Expand Down Expand Up @@ -65,7 +65,7 @@ def _filter_instance_hook(cls, bk_biz_id, query_params, instances, **kwargs):

# 获取实例的操作与实例记录
records = InstanceOperateRecord.objects.filter(
instance_id__in=instance_ids, ticket__status=TicketFlowStatus.RUNNING
instance_id__in=instance_ids, ticket__status__in=TICKET_RUNNING_STATUS
)
instance_operate_records_map: Dict[int, List] = defaultdict(list)
for record in records:
Expand Down
4 changes: 2 additions & 2 deletions dbm-ui/backend/db_services/mysql/dumper/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from backend.db_meta.enums import InstanceInnerRole
from backend.db_meta.models import Cluster
from backend.db_services.mysql.dumper.models import DumperSubscribeConfig
from backend.ticket.constants import FlowType, TicketFlowStatus, TicketStatus, TicketType
from backend.ticket.constants import TICKET_RUNNING_STATUS, FlowType, TicketFlowStatus, TicketStatus, TicketType
from backend.ticket.models import Flow, Ticket


Expand Down Expand Up @@ -66,7 +66,7 @@ def patch_dumper_list_info(cls, dumper_results: List[Dict], bk_biz_id: int = 0,
dumper_ticket_types.remove(TicketType.TBINLOGDUMPER_INSTALL)
dumper_ticket_types.extend([TicketType.MYSQL_MASTER_SLAVE_SWITCH, TicketType.MYSQL_MASTER_FAIL_OVER])
active_tickets = Ticket.objects.filter(
bk_biz_id=bk_biz_id, status=TicketStatus.RUNNING, ticket_type__in=dumper_ticket_types
bk_biz_id=bk_biz_id, status__in=TICKET_RUNNING_STATUS, ticket_type__in=dumper_ticket_types
)
# 获取每个dumper单据状态与id的映射
dumper_inst_id__ticket: Dict[int, str] = {}
Expand Down
25 changes: 6 additions & 19 deletions dbm-ui/backend/flow/plugins/components/collections/common/pause.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@
from pipeline.core.flow.io import ObjectItemSchema, StringItemSchema

from backend.flow.plugins.components.collections.common.base_service import BaseService
from backend.ticket.constants import TodoType
from backend.ticket.models import Ticket, Todo
from backend.ticket.todos.pipeline_todo import PipelineTodoContext
from backend.ticket.models import Ticket
from backend.ticket.todos.pipeline_todo import PipelineTodo

logger = logging.getLogger("root")

Expand All @@ -34,26 +33,14 @@ def _execute(self, data, parent_data):
self.log_info("execute PauseService")
kwargs = data.get_one_of_inputs("kwargs")
global_data = data.get_one_of_inputs("global_data")

# 获取单据和flow信息
ticket_id = global_data["uid"]
ticket = Ticket.objects.get(id=ticket_id)

# todo:这里假设ticket中不会出现并行的flow
flow = ticket.current_flow()

Todo.objects.create(
name=_("【{}】流程待确认,是否继续?").format(ticket.get_ticket_type_display()),
flow=flow,
ticket=ticket,
type=TodoType.INNER_APPROVE,
# todo: 待办人暂定为提单人
operators=[ticket.creator],
context=PipelineTodoContext(
flow.id,
ticket_id,
self.runtime_attrs.get("root_pipeline_id"),
self.runtime_attrs.get("id"),
).to_dict(),
)
# 创建一条代办
PipelineTodo.create(ticket, flow, self.runtime_attrs.get("root_pipeline_id"), self.runtime_attrs.get("id"))

self.log_info("pause kwargs: {}".format(kwargs))
return True
Expand Down
6 changes: 3 additions & 3 deletions dbm-ui/backend/tests/ticket/test_doris_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@
SCALEUP_POOL_TICKET_DATA,
)
from backend.tests.ticket.server_base import TestFlowBase
from backend.ticket.constants import TicketFlowStatus, TicketStatus
from backend.ticket.constants import TicketFlowStatus

logger = logging.getLogger("test")
pytestmark = pytest.mark.django_db
client = APIClient()

INITIAL_FLOW_FINISHED_STATUS = [TicketFlowStatus.SKIPPED, TicketStatus.SUCCEEDED]
CHANGED_MOCK_STATUS = [TicketFlowStatus.SKIPPED, TicketStatus.SUCCEEDED, TicketFlowStatus.RUNNING]
INITIAL_FLOW_FINISHED_STATUS = [TicketFlowStatus.SKIPPED, TicketFlowStatus.SUCCEEDED]
CHANGED_MOCK_STATUS = [TicketFlowStatus.SKIPPED, TicketFlowStatus.SUCCEEDED, TicketFlowStatus.RUNNING]


@pytest.fixture(autouse=True) # autouse=True 会自动应用这个fixture到所有的测试中
Expand Down
2 changes: 1 addition & 1 deletion dbm-ui/backend/tests/ticket/test_mongodb_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
pytestmark = pytest.mark.django_db
client = APIClient()

INITIAL_FLOW_FINISHED_STATUS = [TicketFlowStatus.SKIPPED, TicketStatus.SUCCEEDED]
INITIAL_FLOW_FINISHED_STATUS = [TicketFlowStatus.SKIPPED, TicketFlowStatus.SUCCEEDED]
CHANGED_MOCK_STATUS = [TicketFlowStatus.SKIPPED, TicketStatus.SUCCEEDED, TicketFlowStatus.RUNNING]


Expand Down
3 changes: 1 addition & 2 deletions dbm-ui/backend/ticket/builders/mysql/mysql_ha_full_backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,4 @@ class MySQLHaFullBackupFlowParamBuilder(builders.FlowParamBuilder):
class MySQLHaFullBackupFlowBuilder(BaseMySQLHATicketFlowBuilder):
serializer = MySQLHaFullBackupDetailSerializer
inner_flow_builder = MySQLHaFullBackupFlowParamBuilder
inner_flow_name = _("全库备份执行")
retry_type = FlowRetryType.MANUAL_RETRY
retry_type = FlowRetryType.AUTO_RETRY
80 changes: 62 additions & 18 deletions dbm-ui/backend/ticket/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ class TodoType(str, StructuredEnum):
待办类型
"""

ITSM = EnumField("ITSM", _("主流程-单据审批"))
APPROVE = EnumField("APPROVE", _("主流程-人工确认"))
INNER_FAILED = EnumField("INNER_FAILED", _("主流程-失败后待确认"))
INNER_APPROVE = EnumField("INNER_APPROVE", _("自动化流程-人工确认"))
RESOURCE_REPLENISH = EnumField("RESOURCE_REPLENISH", _("资源补货"))

Expand All @@ -39,19 +41,24 @@ class CountType(str, StructuredEnum):
单据计数类型
"""

MY_TODO = EnumField("MY_TODO", _("我的待办"))
MY_APPROVE = EnumField("MY_APPROVE", _("我的申请"))
APPROVE = EnumField("APPROVE", _("待我审批"))
TODO = EnumField("TODO", _("待我确认执行"))
RUNNING = EnumField("RUNNING", _("待我继续"))
RESOURCE_REPLENISH = EnumField("RESOURCE_REPLENISH", _("待我补货"))
FAILED = EnumField("FAILED", _("失败待处理"))
DONE = EnumField("DONE", _("我的已办"))
SELF_MANAGE = EnumField("SELF_MANAGE", _("我负责的业务"))


class TodoStatus(str, StructuredEnum):
"""
待办状态枚举
TODO -> (RUNNING,可选) -> DONE_SUCCESS
| -> DONE_FAILED
TODO -> (RUNNING,可选) -> DONE_SUCCESS
| -> DONE_FAILED
"""

TODO = EnumField("TODO", _("待处理"))
RUNNING = EnumField("RUNNING", _("处理中"))
DONE_SUCCESS = EnumField("DONE_SUCCESS", _("已处理"))
DONE_FAILED = EnumField("DONE_FAILED", _("已终止"))

Expand All @@ -68,18 +75,44 @@ class ResourceApplyErrCode(int, StructuredEnum):


TODO_DONE_STATUS = [TodoStatus.DONE_SUCCESS, TodoStatus.DONE_FAILED]
TODO_RUNNING_STATUS = [TodoStatus.TODO, TodoStatus.RUNNING]
TODO_RUNNING_STATUS = [TodoStatus.TODO]


class TicketStatus(str, StructuredEnum):
"""单据状态枚举"""

PENDING = EnumField("PENDING", _("等待中"))
APPROVE = EnumField("APPROVE", _("待审批"))
RESOURCE_REPLENISH = EnumField("RESOURCE_REPLENISH", _("待补货"))
TODO = EnumField("TODO", _("待执行"))
TIMER = EnumField("TIMER", _("定时中"))
RUNNING = EnumField("RUNNING", _("执行中"))
SUCCEEDED = EnumField("SUCCEEDED", _("成功"))
SUCCEEDED = EnumField("SUCCEEDED", _("已完成"))
FAILED = EnumField("FAILED", _("失败"))
REVOKED = EnumField("REVOKED", _("撤销"))
TERMINATED = EnumField("TERMINATED", _("终止"))
REVOKED = EnumField("REVOKED", _("已撤销"))
TERMINATED = EnumField("TERMINATED", _("已终止"))
# 仅展示,不参与状态流转,不落地db
INNER_TODO = EnumField("INNER_TODO", _("执行中待确认"))


# 单据[正在进行]的状态合集
TICKET_RUNNING_STATUS = [
TicketStatus.APPROVE,
TicketStatus.TODO,
TicketStatus.RESOURCE_REPLENISH,
TicketStatus.RUNNING,
TicketStatus.TIMER,
]
# 单据[包含TODO]的状态合集
TICKET_TODO_STATUS = [
TicketStatus.APPROVE,
TicketStatus.TODO,
TicketStatus.RESOURCE_REPLENISH,
TicketStatus.FAILED,
TicketStatus.RUNNING,
]
# 单据[失败]的状态合集
TICKET_FAILED_STATUS = [TicketStatus.REVOKED, TicketStatus.TERMINATED, TicketStatus.FAILED]


class TicketFlowStatus(str, StructuredEnum):
Expand All @@ -94,8 +127,8 @@ class TicketFlowStatus(str, StructuredEnum):
SKIPPED = EnumField("SKIPPED", _("跳过"))


FLOW_FINISHED_STATUS = [TicketFlowStatus.SKIPPED, TicketStatus.SUCCEEDED]
FLOW_NOT_EXECUTE_STATUS = [TicketFlowStatus.SKIPPED, TicketStatus.PENDING]
FLOW_FINISHED_STATUS = [TicketFlowStatus.SKIPPED, TicketFlowStatus.SUCCEEDED]
FLOW_NOT_EXECUTE_STATUS = [TicketFlowStatus.SKIPPED, TicketFlowStatus.PENDING]

BAMBOO_STATE__TICKET_STATE_MAP = {
StateType.FINISHED.value: TicketFlowStatus.SUCCEEDED.value,
Expand Down Expand Up @@ -214,7 +247,7 @@ def get_cluster_type_by_ticket(cls, ticket_type):
MYSQL_SLAVE_MIGRATE_UPGRADE = TicketEnumField("MYSQL_SLAVE_MIGRATE_UPGRADE", _("MySQL Slave 迁移升级"), _("版本升级"))
MYSQL_RO_SLAVE_UNINSTALL = TicketEnumField("MYSQL_RO_SLAVE_UNINSTALL", _("MySQL非stanby slave下架"), _("集群维护"))
MYSQL_PROXY_UPGRADE = TicketEnumField("MYSQL_PROXY_UPGRADE", _("MySQL Proxy升级"), _("版本升级"))
MYSQL_HA_TRANSFER_TO_OTHER_BIZ = TicketEnumField("MYSQL_HA_TRANSFER_TO_OTHER_BIZ", _("TendbHA集群迁移至其他业务"), register_iam=False)# noqa
MYSQL_HA_TRANSFER_TO_OTHER_BIZ = TicketEnumField("MYSQL_HA_TRANSFER_TO_OTHER_BIZ", _("TendbHA集群迁移至其他业务"), register_iam=False) # noqa
MYSQL_PUSH_PERIPHERAL_CONFIG = TicketEnumField("MYSQL_PUSH_PERIPHERAL_CONFIG", _("推送周边配置"), register_iam=False)

# SPIDER(TenDB Cluster)
Expand Down Expand Up @@ -245,9 +278,9 @@ def get_cluster_type_by_ticket(cls, ticket_type):
TENDBCLUSTER_DISABLE = TicketEnumField("TENDBCLUSTER_DISABLE", _("TenDB Cluster 集群禁用"), register_iam=False)
TENDBCLUSTER_DESTROY = TicketEnumField("TENDBCLUSTER_DESTROY", _("TenDB Cluster 集群销毁"), _("集群管理"))
TENDBCLUSTER_TEMPORARY_DESTROY = TicketEnumField("TENDBCLUSTER_TEMPORARY_DESTROY", _("TenDB Cluster 临时集群销毁"), _("集群管理")) # noqa
TENDBCLUSTER_NODE_REBALANCE = TicketEnumField("TENDBCLUSTER_NODE_REBALANCE", _("TenDB Cluster 集群容量变更"), _("集群维护")) # noqa
TENDBCLUSTER_NODE_REBALANCE = TicketEnumField("TENDBCLUSTER_NODE_REBALANCE", _("TenDB Cluster 集群容量变更"), _("集群维护")) # noqa
TENDBCLUSTER_FULL_BACKUP = TicketEnumField("TENDBCLUSTER_FULL_BACKUP", _("TenDB Cluster 全库备份"), _("备份"))
TENDBCLUSTER_ROLLBACK_CLUSTER = TicketEnumField("TENDBCLUSTER_ROLLBACK_CLUSTER", _("TenDB Cluster 定点构造"), _("回档")) # noqa
TENDBCLUSTER_ROLLBACK_CLUSTER = TicketEnumField("TENDBCLUSTER_ROLLBACK_CLUSTER", _("TenDB Cluster 定点构造"), _("回档")) # noqa
TENDBCLUSTER_FLASHBACK = TicketEnumField("TENDBCLUSTER_FLASHBACK", _("TenDB Cluster 闪回"), _("回档"))
TENDBCLUSTER_CLIENT_CLONE_RULES = TicketEnumField("TENDBCLUSTER_CLIENT_CLONE_RULES", _("TenDB Cluster 客户端权限克隆"), _("权限管理")) # noqa
TENDBCLUSTER_INSTANCE_CLONE_RULES = TicketEnumField("TENDBCLUSTER_INSTANCE_CLONE_RULES", _("TenDB Cluster DB实例权限克隆"), _("权限管理")) # noqa
Expand Down Expand Up @@ -277,9 +310,9 @@ def get_cluster_type_by_ticket(cls, ticket_type):
SQLSERVER_DISABLE = TicketEnumField("SQLSERVER_DISABLE", _("SQLServer 集群禁用"), register_iam=False)
SQLSERVER_ENABLE = TicketEnumField("SQLSERVER_ENABLE", _("SQLServer 集群启用"), register_iam=False)
SQLSERVER_DBRENAME = TicketEnumField("SQLSERVER_DBRENAME", _("SQLServer DB重命名"), _("集群维护"))
SQLSERVER_MASTER_SLAVE_SWITCH = TicketEnumField("SQLSERVER_MASTER_SLAVE_SWITCH", _("SQLServer 主从互切"), _("集群维护")) # noqa
SQLSERVER_MASTER_SLAVE_SWITCH = TicketEnumField("SQLSERVER_MASTER_SLAVE_SWITCH", _("SQLServer 主从互切"), _("集群维护")) # noqa
SQLSERVER_MASTER_FAIL_OVER = TicketEnumField("SQLSERVER_MASTER_FAIL_OVER", _("SQLServer 主库故障切换"), _("集群维护"))
SQLSERVER_RESTORE_LOCAL_SLAVE = TicketEnumField("SQLSERVER_RESTORE_LOCAL_SLAVE", _("SQLServer 原地重建"), _("集群维护")) # noqa
SQLSERVER_RESTORE_LOCAL_SLAVE = TicketEnumField("SQLSERVER_RESTORE_LOCAL_SLAVE", _("SQLServer 原地重建"), _("集群维护")) # noqa
SQLSERVER_RESTORE_SLAVE = TicketEnumField("SQLSERVER_RESTORE_SLAVE", _("SQLServer 新机重建"), _("集群维护"))
SQLSERVER_ADD_SLAVE = TicketEnumField("SQLSERVER_ADD_SLAVE", _("SQLServer 添加从库"), _("集群维护"))
SQLSERVER_RESET = TicketEnumField("SQLSERVER_RESET", _("SQLServer 集群重置"), _("集群维护"))
Expand Down Expand Up @@ -408,8 +441,8 @@ def get_cluster_type_by_ticket(cls, ticket_type):
RIAK_CLUSTER_MIGRATE = TicketEnumField("RIAK_CLUSTER_MIGRATE", _("Riak 集群迁移"), _("集群管理"))

# MONGODB
MONGODB_REPLICASET_APPLY = TicketEnumField("MONGODB_REPLICASET_APPLY", _("MongoDB 副本集集群部署"), register_iam=False) # noqa
MONGODB_SHARD_APPLY = TicketEnumField("MONGODB_SHARD_APPLY", _("MongoDB 分片集群部署"), _("集群管理"), register_iam=False) # noqa
MONGODB_REPLICASET_APPLY = TicketEnumField("MONGODB_REPLICASET_APPLY", _("MongoDB 副本集集群部署"), register_iam=False) # noqa
MONGODB_SHARD_APPLY = TicketEnumField("MONGODB_SHARD_APPLY", _("MongoDB 分片集群部署"), _("集群管理"), register_iam=False) # noqa
MONGODB_EXEC_SCRIPT_APPLY = TicketEnumField("MONGODB_EXEC_SCRIPT_APPLY", _("MongoDB 变更脚本执行"), _("脚本任务"))
MONGODB_REMOVE_NS = TicketEnumField("MONGODB_REMOVE_NS", _("MongoDB 清档"), _("数据处理"))
MONGODB_FULL_BACKUP = TicketEnumField("MONGODB_FULL_BACKUP", _("MongoDB 全库备份"), _("备份"))
Expand All @@ -425,7 +458,7 @@ def get_cluster_type_by_ticket(cls, ticket_type):
MONGODB_DESTROY = TicketEnumField("MONGODB_DESTROY", _("MongoDB 集群删除"), _("集群管理"))
MONGODB_CUTOFF = TicketEnumField("MONGODB_CUTOFF", _("MongoDB 整机替换"), _("集群维护"))
MONGODB_AUTHORIZE_RULES = TicketEnumField("MONGODB_AUTHORIZE_RULES", _("MongoDB 授权"), _("权限管理"))
MONGODB_EXCEL_AUTHORIZE_RULES = TicketEnumField("MONGODB_EXCEL_AUTHORIZE_RULES", _("MongoDB Excel授权"), _("权限管理")) # noqa
MONGODB_EXCEL_AUTHORIZE_RULES = TicketEnumField("MONGODB_EXCEL_AUTHORIZE_RULES", _("MongoDB Excel授权"), _("权限管理")) # noqa
MONGODB_IMPORT = TicketEnumField("MONGODB_IMPORT", _("MongoDB 数据导入"), _("集群维护"))
MONGODB_RESTORE = TicketEnumField("MONGODB_RESTORE", _("MongoDB 定点回档"), _("集群维护"))
MONGODB_TEMPORARY_DESTROY = TicketEnumField("MONGODB_TEMPORARY_DESTROY", _("MongoDB 临时集群销毁"), _("集群维护"))
Expand Down Expand Up @@ -635,6 +668,7 @@ class OperateNodeActionType(str, StructuredEnum):
DISTRIBUTE = EnumField("DISTRIBUTE", _("派单"))
DELIVER = EnumField("DELIVER", _("转单"))
TERMINATE = EnumField("TERMINATE", _("终止节点和单据"))
WITHDRAW = EnumField("WITHDRAW", _("撤销单据"))


class ItsmTicketNodeEnum(str, StructuredEnum):
Expand Down Expand Up @@ -681,3 +715,13 @@ class TicketExpireType(str, StructuredEnum):
FlowType.RESOURCE_APPLY: TicketExpireType.FLOW_TODO,
FlowType.RESOURCE_BATCH_APPLY: TicketExpireType.FLOW_TODO,
}

# 根据流程类型来映射单据状态
RUNNING_FLOW__TICKET_STATUS = {
FlowType.BK_ITSM: TicketStatus.APPROVE,
FlowType.RESOURCE_APPLY: TicketStatus.RESOURCE_REPLENISH,
FlowType.RESOURCE_BATCH_APPLY: TicketStatus.RESOURCE_REPLENISH,
FlowType.PAUSE: TicketStatus.TODO,
FlowType.INNER_FLOW: TicketStatus.RUNNING,
FlowType.TIMER: TicketStatus.TIMER,
}
6 changes: 3 additions & 3 deletions dbm-ui/backend/ticket/contexts.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ def __init__(
self.spec_map = get_spec_display_map()
self.db_config = {}

bizs = list(AppCache.objects.all())
self.biz_name_map = {biz.bk_biz_id: biz.bk_biz_name for biz in bizs}
self.app_abbr_map = {biz.bk_biz_id: biz.db_app_abbr for biz in bizs}
bizs = AppCache.get_appcache(key="appcache_dict")
self.biz_name_map = {int(bk_biz_id): biz["bk_biz_name"] for bk_biz_id, biz in bizs.items()}
self.app_abbr_map = {int(bk_biz_id): biz["db_app_abbr"] for bk_biz_id, biz in bizs.items()}

db_modules = list(DBModule.objects.all())
self.db_module_map = {module.db_module_id: module.db_module_name for module in db_modules}
Expand Down
Loading

0 comments on commit 5eb1893

Please sign in to comment.