|
7 | 7 | from django.contrib.auth.decorators import permission_required
|
8 | 8 | from django.core.exceptions import PermissionDenied
|
9 | 9 | from django.db import transaction
|
10 |
| -from django.db.models import Q |
11 | 10 | from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
|
12 | 11 | from django.shortcuts import render, get_object_or_404
|
13 | 12 | from django.urls import reverse
|
14 |
| -from django.utils import timezone |
15 | 13 |
|
16 | 14 | from common.config import SysConfig
|
17 |
| -from common.utils.const import Const, WorkflowDict |
| 15 | +from common.utils.const import WorkflowDict |
18 | 16 | from common.utils.extend_json_encoder import ExtendJSONEncoder
|
19 |
| -from sql.engines.models import ReviewResult, ReviewSet |
20 | 17 | from sql.notify import notify_for_audit, notify_for_execute
|
21 |
| -from sql.models import ResourceGroup |
22 |
| -from sql.utils.resource_group import user_groups, user_instances |
23 | 18 | from sql.utils.tasks import add_sql_schedule, del_schedule
|
24 | 19 | from sql.utils.sql_review import (
|
25 | 20 | can_timingtask,
|
26 | 21 | can_cancel,
|
27 | 22 | can_execute,
|
28 | 23 | on_correct_time_period,
|
29 |
| - can_view, |
30 | 24 | can_rollback,
|
31 | 25 | )
|
32 | 26 | from sql.utils.workflow_audit import Audit
|
33 |
| -from .models import SqlWorkflow, SqlWorkflowContent, Instance |
| 27 | +from .models import SqlWorkflow |
34 | 28 | from django_q.tasks import async_task
|
35 | 29 |
|
36 | 30 | from sql.engines import get_engine
|
37 | 31 |
|
38 | 32 | logger = logging.getLogger("default")
|
39 | 33 |
|
40 | 34 |
|
41 |
| -@permission_required("sql.menu_sqlworkflow", raise_exception=True) |
42 |
| -def sql_workflow_list(request): |
43 |
| - return _sql_workflow_list(request) |
44 |
| - |
45 |
| - |
46 |
| -@permission_required("sql.audit_user", raise_exception=True) |
47 |
| -def sql_workflow_list_audit(request): |
48 |
| - return _sql_workflow_list(request) |
49 |
| - |
50 |
| - |
51 |
| -def _sql_workflow_list(request): |
52 |
| - """ |
53 |
| - 获取审核列表 |
54 |
| - :param request: |
55 |
| - :return: |
56 |
| - """ |
57 |
| - nav_status = request.POST.get("navStatus") |
58 |
| - instance_id = request.POST.get("instance_id") |
59 |
| - resource_group_id = request.POST.get("group_id") |
60 |
| - start_date = request.POST.get("start_date") |
61 |
| - end_date = request.POST.get("end_date") |
62 |
| - limit = int(request.POST.get("limit", 0)) |
63 |
| - offset = int(request.POST.get("offset", 0)) |
64 |
| - limit = offset + limit |
65 |
| - limit = limit if limit else None |
66 |
| - search = request.POST.get("search") |
67 |
| - user = request.user |
68 |
| - |
69 |
| - # 组合筛选项 |
70 |
| - filter_dict = dict() |
71 |
| - # 工单状态 |
72 |
| - if nav_status: |
73 |
| - filter_dict["status"] = nav_status |
74 |
| - # 实例 |
75 |
| - if instance_id: |
76 |
| - filter_dict["instance_id"] = instance_id |
77 |
| - # 资源组 |
78 |
| - if resource_group_id: |
79 |
| - filter_dict["group_id"] = resource_group_id |
80 |
| - # 时间 |
81 |
| - if start_date and end_date: |
82 |
| - end_date = datetime.datetime.strptime( |
83 |
| - end_date, "%Y-%m-%d" |
84 |
| - ) + datetime.timedelta(days=1) |
85 |
| - filter_dict["create_time__range"] = (start_date, end_date) |
86 |
| - # 管理员,审计员,可查看所有工单 |
87 |
| - if user.is_superuser or user.has_perm("sql.audit_user"): |
88 |
| - pass |
89 |
| - # 非管理员,拥有审核权限、资源组粒度执行权限的,可以查看组内所有工单 |
90 |
| - elif user.has_perm("sql.sql_review") or user.has_perm( |
91 |
| - "sql.sql_execute_for_resource_group" |
92 |
| - ): |
93 |
| - # 先获取用户所在资源组列表 |
94 |
| - group_list = user_groups(user) |
95 |
| - group_ids = [group.group_id for group in group_list] |
96 |
| - filter_dict["group_id__in"] = group_ids |
97 |
| - # 其他人只能查看自己提交的工单 |
98 |
| - else: |
99 |
| - filter_dict["engineer"] = user.username |
100 |
| - |
101 |
| - # 过滤组合筛选项 |
102 |
| - workflow = SqlWorkflow.objects.filter(**filter_dict) |
103 |
| - |
104 |
| - # 过滤搜索项,模糊检索项包括提交人名称、工单名 |
105 |
| - if search: |
106 |
| - workflow = workflow.filter( |
107 |
| - Q(engineer_display__icontains=search) | Q(workflow_name__icontains=search) |
108 |
| - ) |
109 |
| - |
110 |
| - count = workflow.count() |
111 |
| - workflow_list = workflow.order_by("-create_time")[offset:limit].values( |
112 |
| - "id", |
113 |
| - "workflow_name", |
114 |
| - "engineer_display", |
115 |
| - "status", |
116 |
| - "is_backup", |
117 |
| - "create_time", |
118 |
| - "instance__instance_name", |
119 |
| - "db_name", |
120 |
| - "group_name", |
121 |
| - "syntax_type", |
122 |
| - ) |
123 |
| - |
124 |
| - # QuerySet 序列化 |
125 |
| - rows = [row for row in workflow_list] |
126 |
| - result = {"total": count, "rows": rows} |
127 |
| - # 返回查询结果 |
128 |
| - return HttpResponse( |
129 |
| - json.dumps(result, cls=ExtendJSONEncoder, bigint_as_string=True), |
130 |
| - content_type="application/json", |
131 |
| - ) |
132 |
| - |
133 |
| - |
134 |
| -def detail_content(request): |
135 |
| - """获取工单内容""" |
136 |
| - workflow_id = request.GET.get("workflow_id") |
137 |
| - workflow_detail = get_object_or_404(SqlWorkflow, pk=workflow_id) |
138 |
| - if not can_view(request.user, workflow_id): |
139 |
| - raise PermissionDenied |
140 |
| - if workflow_detail.status in ["workflow_finish", "workflow_exception"]: |
141 |
| - rows = workflow_detail.sqlworkflowcontent.execute_result |
142 |
| - else: |
143 |
| - rows = workflow_detail.sqlworkflowcontent.review_content |
144 |
| - |
145 |
| - review_result = ReviewSet() |
146 |
| - if rows: |
147 |
| - try: |
148 |
| - # 检验rows能不能正常解析 |
149 |
| - loaded_rows = json.loads(rows) |
150 |
| - # 兼容旧数据'[[]]'格式,转换为新格式[{}] |
151 |
| - if isinstance(loaded_rows[-1], list): |
152 |
| - for r in loaded_rows: |
153 |
| - review_result.rows += [ReviewResult(inception_result=r)] |
154 |
| - rows = review_result.json() |
155 |
| - except IndexError: |
156 |
| - review_result.rows += [ |
157 |
| - ReviewResult( |
158 |
| - id=1, |
159 |
| - sql=workflow_detail.sqlworkflowcontent.sql_content, |
160 |
| - errormessage="Json decode failed." "执行结果Json解析失败, 请联系管理员", |
161 |
| - ) |
162 |
| - ] |
163 |
| - rows = review_result.json() |
164 |
| - except json.decoder.JSONDecodeError: |
165 |
| - review_result.rows += [ |
166 |
| - ReviewResult( |
167 |
| - id=1, |
168 |
| - sql=workflow_detail.sqlworkflowcontent.sql_content, |
169 |
| - # 迫于无法单元测试这里加上英文报错信息 |
170 |
| - errormessage="Json decode failed." "执行结果Json解析失败, 请联系管理员", |
171 |
| - ) |
172 |
| - ] |
173 |
| - rows = review_result.json() |
174 |
| - else: |
175 |
| - rows = workflow_detail.sqlworkflowcontent.review_content |
176 |
| - |
177 |
| - result = {"rows": json.loads(rows)} |
178 |
| - return HttpResponse(json.dumps(result), content_type="application/json") |
179 |
| - |
180 |
| - |
181 |
| -def backup_sql(request): |
182 |
| - """获取回滚语句""" |
183 |
| - workflow_id = request.GET.get("workflow_id") |
184 |
| - if not can_rollback(request.user, workflow_id): |
185 |
| - raise PermissionDenied |
186 |
| - workflow = get_object_or_404(SqlWorkflow, pk=workflow_id) |
187 |
| - |
188 |
| - try: |
189 |
| - query_engine = get_engine(instance=workflow.instance) |
190 |
| - list_backup_sql = query_engine.get_rollback(workflow=workflow) |
191 |
| - except Exception as msg: |
192 |
| - logger.error(traceback.format_exc()) |
193 |
| - return JsonResponse({"status": 1, "msg": f"{msg}", "rows": []}) |
194 |
| - |
195 |
| - result = {"status": 0, "msg": "", "rows": list_backup_sql} |
196 |
| - return HttpResponse(json.dumps(result), content_type="application/json") |
197 |
| - |
198 |
| - |
199 | 35 | @permission_required("sql.sql_review", raise_exception=True)
|
200 | 36 | def alter_run_date(request):
|
201 | 37 | """
|
@@ -264,8 +100,8 @@ def passed(request):
|
264 | 100 |
|
265 | 101 | # 按照审核结果更新业务表审核状态
|
266 | 102 | if (
|
267 |
| - audit_result["data"]["workflow_status"] |
268 |
| - == WorkflowDict.workflow_status["audit_success"] |
| 103 | + audit_result["data"]["workflow_status"] |
| 104 | + == WorkflowDict.workflow_status["audit_success"] |
269 | 105 | ):
|
270 | 106 | # 将流程状态修改为审核通过
|
271 | 107 | SqlWorkflow(id=workflow_id, status="workflow_review_pass").save(
|
@@ -303,8 +139,8 @@ def execute(request):
|
303 | 139 | """
|
304 | 140 | # 校验多个权限
|
305 | 141 | if not (
|
306 |
| - request.user.has_perm("sql.sql_execute") |
307 |
| - or request.user.has_perm("sql.sql_execute_for_resource_group") |
| 142 | + request.user.has_perm("sql.sql_execute") |
| 143 | + or request.user.has_perm("sql.sql_execute_for_resource_group") |
308 | 144 | ):
|
309 | 145 | raise PermissionDenied
|
310 | 146 | workflow_id = int(request.POST.get("workflow_id", 0))
|
@@ -390,8 +226,8 @@ def timing_task(request):
|
390 | 226 | """
|
391 | 227 | # 校验多个权限
|
392 | 228 | if not (
|
393 |
| - request.user.has_perm("sql.sql_execute") |
394 |
| - or request.user.has_perm("sql.sql_execute_for_resource_group") |
| 229 | + request.user.has_perm("sql.sql_execute") |
| 230 | + or request.user.has_perm("sql.sql_execute_for_resource_group") |
395 | 231 | ):
|
396 | 232 | raise PermissionDenied
|
397 | 233 | workflow_id = request.POST.get("workflow_id")
|
@@ -537,8 +373,8 @@ def cancel(request):
|
537 | 373 | workflow_type=WorkflowDict.workflow_type["sqlreview"],
|
538 | 374 | )
|
539 | 375 | if audit_detail.current_status in (
|
540 |
| - WorkflowDict.workflow_status["audit_abort"], |
541 |
| - WorkflowDict.workflow_status["audit_reject"], |
| 376 | + WorkflowDict.workflow_status["audit_abort"], |
| 377 | + WorkflowDict.workflow_status["audit_reject"], |
542 | 378 | ):
|
543 | 379 | async_task(
|
544 | 380 | notify_for_audit,
|
|
0 commit comments