Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQL检测和提交接入api方法 #1668

Merged
merged 3 commits into from
Sep 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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