Skip to content

Commit

Permalink
SQL检测和提交接入api方法
Browse files Browse the repository at this point in the history
  • Loading branch information
hhyo committed Jul 28, 2022
1 parent 6bb36f7 commit 46a4038
Show file tree
Hide file tree
Showing 9 changed files with 291 additions and 675 deletions.
2 changes: 1 addition & 1 deletion sql/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ class SqlWorkflow(models.Model):
"""

workflow_name = models.CharField("工单内容", max_length=50)
demand_url = models.CharField("需求链接", max_length=500)
demand_url = models.CharField("需求链接", max_length=500, blank=True)
group_id = models.IntegerField("组ID")
group_name = models.CharField("组名称", max_length=100)
instance = models.ForeignKey(Instance, on_delete=models.CASCADE)
Expand Down
154 changes: 0 additions & 154 deletions sql/sql_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,160 +131,6 @@ def _sql_workflow_list(request):
)


@permission_required("sql.sql_submit", raise_exception=True)
def check(request):
"""SQL检测按钮, 此处没有产生工单"""
sql_content = request.POST.get("sql_content")
instance_name = request.POST.get("instance_name")
instance = Instance.objects.get(instance_name=instance_name)
db_name = request.POST.get("db_name")

result = {"status": 0, "msg": "ok", "data": {}}
# 服务器端参数验证
if sql_content is None or instance_name is None or db_name is None:
result["status"] = 1
result["msg"] = "页面提交参数可能为空"
return HttpResponse(json.dumps(result), content_type="application/json")

# 交给engine进行检测
try:
check_engine = get_engine(instance=instance)
check_result = check_engine.execute_check(
db_name=db_name, sql=sql_content.strip()
)
except Exception as e:
result["status"] = 1
result["msg"] = str(e)
return HttpResponse(json.dumps(result), content_type="application/json")

# 处理检测结果
result["data"]["rows"] = check_result.to_dict()
result["data"]["CheckWarningCount"] = check_result.warning_count
result["data"]["CheckErrorCount"] = check_result.error_count
return HttpResponse(json.dumps(result), content_type="application/json")


@permission_required("sql.sql_submit", raise_exception=True)
def submit(request):
"""正式提交SQL, 此处生成工单"""
sql_content = request.POST.get("sql_content").strip()
workflow_title = request.POST.get("workflow_name")
demand_url = request.POST.get("demand_url", "")
# 检查用户是否有权限涉及到资源组等, 比较复杂, 可以把检查权限改成一个独立的方法
group_name = request.POST.get("group_name")
group_id = ResourceGroup.objects.get(group_name=group_name).group_id
instance_name = request.POST.get("instance_name")
instance = Instance.objects.get(instance_name=instance_name)
db_name = request.POST.get("db_name")
is_backup = True if request.POST.get("is_backup") == "True" else False
cc_users = request.POST.getlist("cc_users")
run_date_start = request.POST.get("run_date_start")
run_date_end = request.POST.get("run_date_end")

# 服务器端参数验证
if None in [sql_content, db_name, instance_name, db_name, is_backup, demand_url]:
context = {"errMsg": "页面提交参数可能为空"}
return render(request, "error.html", context)

# 验证组权限(用户是否在该组、该组是否有指定实例)
try:
user_instances(request.user, tag_codes=["can_write"]).get(
instance_name=instance_name
)
except instance.DoesNotExist:
context = {"errMsg": "你所在组未关联该实例!"}
return render(request, "error.html", context)

# 再次交给engine进行检测,防止绕过
try:
check_engine = get_engine(instance=instance)
check_result = check_engine.execute_check(
db_name=db_name, sql=sql_content.strip()
)
except Exception as e:
context = {"errMsg": str(e)}
return render(request, "error.html", context)

# 未开启备份选项,并且engine支持备份,强制设置备份
sys_config = SysConfig()
if not sys_config.get("enable_backup_switch") and check_engine.auto_backup:
is_backup = True

# 按照系统配置确定是自动驳回还是放行
auto_review_wrong = sys_config.get(
"auto_review_wrong", ""
) # 1表示出现警告就驳回,2和空表示出现错误才驳回
workflow_status = "workflow_manreviewing"
if check_result.warning_count > 0 and auto_review_wrong == "1":
workflow_status = "workflow_autoreviewwrong"
elif check_result.error_count > 0 and auto_review_wrong in ("", "1", "2"):
workflow_status = "workflow_autoreviewwrong"

# 调用工作流生成工单
# 使用事务保持数据一致性
try:
with transaction.atomic():
# 存进数据库里
sql_workflow = SqlWorkflow.objects.create(
workflow_name=workflow_title,
demand_url=demand_url,
group_id=group_id,
group_name=group_name,
engineer=request.user.username,
engineer_display=request.user.display,
audit_auth_groups=Audit.settings(
group_id, WorkflowDict.workflow_type["sqlreview"]
),
status=workflow_status,
is_backup=is_backup,
instance=instance,
db_name=db_name,
is_manual=0,
syntax_type=check_result.syntax_type,
create_time=timezone.now(),
run_date_start=run_date_start or None,
run_date_end=run_date_end or None,
)
SqlWorkflowContent.objects.create(
workflow=sql_workflow,
sql_content=sql_content,
review_content=check_result.json(),
execute_result="",
)
workflow_id = sql_workflow.id
# 自动审核通过了,才调用工作流
if workflow_status == "workflow_manreviewing":
# 调用工作流插入审核信息, SQL上线权限申请workflow_type=2
Audit.add(WorkflowDict.workflow_type["sqlreview"], workflow_id)
except Exception as msg:
logger.error(f"提交工单报错,错误信息:{traceback.format_exc()}")
context = {"errMsg": msg}
logger.error(traceback.format_exc())
return render(request, "error.html", context)
else:
# 自动审核通过且开启了Apply阶段通知参数才发送消息通知
is_notified = (
"Apply" in sys_config.get("notify_phase_control").split(",")
if sys_config.get("notify_phase_control")
else True
)
if workflow_status == "workflow_manreviewing" and is_notified:
# 获取审核信息
audit_id = Audit.detail_by_workflow_id(
workflow_id=workflow_id,
workflow_type=WorkflowDict.workflow_type["sqlreview"],
).audit_id
async_task(
notify_for_audit,
audit_id=audit_id,
cc_users=cc_users,
timeout=60,
task_name=f"sqlreview-submit-{workflow_id}",
)

return HttpResponseRedirect(reverse("sql:detail", args=(workflow_id,)))


def detail_content(request):
"""获取工单内容"""
workflow_id = request.GET.get("workflow_id")
Expand Down
Loading

0 comments on commit 46a4038

Please sign in to comment.