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

添加业务低峰时间范围,ddl只能够在在业务低峰执行选项,避免非dba执行sql锁表影响业务 #2731

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
99 changes: 64 additions & 35 deletions common/templates/config.html
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,29 @@ <h5 style="color: darkgrey"><b>SQL上线</b></h5>
</div>
</div>
</div>
<div class="form-group">
<label for="query_low_peak_query"
class="col-sm-4 control-label">QUERY_LOW_PEAK_QUERY</label>
<div class="col-sm-5">
<select id="query_low_peak_query" key="query_low_peak_query"
class="selectpicker show-tick form-control bs-select-hidden"
data-live-search="true"
data-none-selected-text="必须在低峰期执行操作操作?默认DML,DDL"
multiple required>
</select>
</div>
</div>
<div class="form-group">
<label for="query_low_peak" class="col-sm-4 control-label">QUERY_LOW_PEAK</label>
<div class="col-sm-5">
<input type="text" class="form-control"
id="query_low_peak" key="query_low_peak"
value="{{ config.query_low_peak }}"
placeholder="每天业务低峰开始时间,单位小时,默认为空"
pattern="^([01]?[0-9]|2[0-3]):[0-5][0-9]-([01]?[0-9]|2[0-3]):[0-5][0-9](,([01]?[0-9]|2[0-3]):[0-5][0-9]-([01]?[0-9]|2[0-3]):[0-5][0-9])*$"
title="请输入正确的时间范围,如:12:00-14:00,16:00-21:00,23:00-24:00" />
</div>
</div>
<div class="form-group">
<label for="ban_self_audit"
class="col-sm-4 control-label">BAN_SELF_AUDIT</label>
Expand Down Expand Up @@ -1096,18 +1119,7 @@ <h4 style="color: darkgrey"><b>其他配置</b></h4>
key="announcement_content"
value="{{ config.announcement_content }}"
placeholder="公告内容">

</div>
</div>
<div class="form-group">
<label for="custom_title_suffix"
class="col-sm-4 control-label">CUSTOM_TITLE_SUFFIX</label>
<div class="col-sm-5">
<input type="text" class="form-control"
id="custom_title_suffix"
key="custom_title_suffix"
value="{{ config.custom_title_suffix }}"
placeholder="在网站标题及登录页面追加此内容, 可用于多archery实例的区分">

</div>
</div>
</div>
Expand Down Expand Up @@ -1159,29 +1171,30 @@ <h5 class="control-label text-bold">当前审批流程:<b id="workflow_auditor
<script>

$(document).ready(function (){
// notify_phase_control参数处理
let cfg_value = "{{ config.notify_phase_control }}";
let phases = ['Apply', 'Pass', 'Execute', 'Cancel'];
// notify_phase_control未设置时默认全部开启
if (cfg_value === "") {
for (let i in phases) {
let phase = "<option value=\"" + phases[i]+ "\" selected>" + phases[i] + "</option>"
$("#notify_phase_control").append(phase)
}
} else {
for (let i=0;i<phases.length;i++) {
let phase = "";
let cfg_arr = cfg_value.split(',');
if (cfg_arr.indexOf(phases[i]) >= 0) {
phase = "<option value=\"" + phases[i]+ "\" selected>" + phases[i] + "</option>"
} else {
phase = "<option value=\"" + phases[i]+ "\">" + phases[i] + "</option>"
}
$("#notify_phase_control").append(phase)
}
function setupSelectPicker(selector, configValue, defaultPhases) {
let $select = $(selector);
let cfgArr = configValue ? configValue.split(',') : defaultPhases;
$select.empty();

defaultPhases.forEach(phase => {
let isSelected = cfgArr.includes(phase) ? ' selected' : '';
let option = `<option value="${phase}"${isSelected}>${phase}</option>`;
$select.append(option);
});

$select.selectpicker('render');
$select.selectpicker('refresh');
}
$("#notify_phase_control").selectpicker('render');
$("#notify_phase_control").selectpicker('refresh');

// notify_phase_control参数处理
let notifyConfig = "{{ config.notify_phase_control }}";
let notifyPhases = ['Apply', 'Pass', 'Execute', 'Cancel'];
setupSelectPicker("#notify_phase_control", notifyConfig, notifyPhases);

// query_low_peak_query参数处理
let queryConfig = "{{ config.query_low_peak_query }}";
let queryPhases = ['DML', 'DDL'];
setupSelectPicker("#query_low_peak_query", queryConfig, queryPhases);

// api_user_whitelist参数处理
let api_config = "{{ config.api_user_whitelist }}";
Expand Down Expand Up @@ -1304,7 +1317,6 @@ <h5 class="control-label text-bold">当前审批流程:<b id="workflow_auditor
}
}
});

// 修改系统设置
$("#saveconfig").click(function () {
// 当开启钉钉通知到个人时,企业id和secret等必须填写
Expand All @@ -1319,6 +1331,23 @@ <h5 class="control-label text-bold">当前审批流程:<b id="workflow_auditor
return;
}
}
// 校验时间段格式和有效性的函数
var query_low_peak = $("#query_low_peak").val();
var periods = query_low_peak.split(',');
var timePattern = /^([01]\d|2[0-3]):([0-5]\d)-([01]\d|2[0-3]):([0-5]\d)$/;
for (var i = 0; i < periods.length; i++) {
if (!timePattern.test(periods[i])) {
alert('业务低峰时段时间格式错误,正确格式为 HH:MM-HH:MM,例如 "12:00-14:00"');
return ;
}
var times = periods[i].split('-');
var startTime = times[0];
var endTime = times[1];
if (startTime >= endTime) {
alert('业务低峰时段时间范围错误,结束时间必须大于开始时间');
return ;
}
}
var sys_config = $("#div-system-config");
var configs = [];
sys_config.find('[key]').each(
Expand Down
13 changes: 13 additions & 0 deletions sql/sql_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
can_timingtask,
can_cancel,
can_execute,
on_query_low_peak_time_ddl,
on_correct_time_period,
can_view,
can_rollback,
Expand Down Expand Up @@ -306,6 +307,18 @@ def execute(request):
"errMsg": "不在可执行时间范围内,如果需要修改执行时间请重新提交工单!"
}
return render(request, "error.html", context)
sys_config = SysConfig()
if (
not request.user.is_superuser
and on_query_low_peak_time_ddl(workflow_id) is False
):
periods = sys_config.get("query_low_peak", "")
peak_action = sys_config.get("query_low_peak_query", "")
context = {
"errMsg": "管理员设置了业务低峰期时间范围:%s,你只能在业务低峰时间范围执行%s工单操作!"
% (periods, peak_action)
}
return render(request, "error.html", context)
# 获取审核信息
audit_id = Audit.detail_by_workflow_id(
workflow_id=workflow_id, workflow_type=WorkflowType.SQL_REVIEW
Expand Down
30 changes: 30 additions & 0 deletions sql/utils/sql_review.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,36 @@ def can_execute(user, workflow_id):
return result


def on_query_low_peak_time_ddl(workflow_id, run_date=None):
"""
判断是否是ddl,ddl必须在业务低峰期执行,包括人工执行和定时执行
:param workflow_id:
:param run_date:
:return:
"""
config = SysConfig()
workflow_detail = SqlWorkflow.objects.get(id=workflow_id)
result = True
ctime = run_date or datetime.datetime.now()
run_time = f"{ctime.hour:02}:{ctime.minute:02}"
syntax_type = workflow_detail.syntax_type
periods = config.get("query_low_peak", "")
peak_action = config.get("query_low_peak_query", "")

def is_without_peak_periods(run_time, periods):
for period in periods.split(","):
start, end = period.split("-")
if start <= run_time <= end:
return True # 如果 run_time 在当前时间段内,直接返回 True
return False # 只有当 run_time 不在任何时间段内时,才返回 False

if "DML" in peak_action and syntax_type == 2:
return is_without_peak_periods(run_time, periods)
if "DDL" in peak_action and syntax_type == 1:
return is_without_peak_periods(run_time, periods)
return result


def on_correct_time_period(workflow_id, run_date=None):
"""
判断是否在可执行时间段内,包括人工执行和定时执行
Expand Down
20 changes: 19 additions & 1 deletion sql_api/api_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@
from sql.notify import notify_for_audit, notify_for_execute
from sql.query_privileges import _query_apply_audit_call_back
from sql.utils.resource_group import user_groups
from sql.utils.sql_review import can_cancel, can_execute, on_correct_time_period
from sql.utils.sql_review import (
can_cancel,
can_execute,
on_correct_time_period,
on_query_low_peak_time_ddl,
)
from sql.utils.tasks import del_schedule
from sql.utils.workflow_audit import Audit, get_auditor, AuditException
from .filters import WorkflowFilter, WorkflowAuditFilter
Expand Down Expand Up @@ -340,6 +345,19 @@ def post(self, request):
"errors": "不在可执行时间范围内,如果需要修改执行时间请重新提交工单!"
}
)
sys_config = SysConfig()
if (
not request.user.is_superuser
and on_query_low_peak_time_ddl(workflow_id) is False
):
periods = sys_config.get("query_low_peak", "")
peak_action = sys_config.get("query_low_peak_query", "")
raise serializers.ValidationError(
{
"errMsg": "管理员设置了业务低峰期时间范围:%s,你只能在业务低峰时间范围执行%s工单操作!"
% (periods, peak_action)
}
)

# 获取审核信息
audit_id = Audit.detail_by_workflow_id(
Expand Down
Loading