Skip to content

Commit

Permalink
Merge pull request #101 from hhyo/redis
Browse files Browse the repository at this point in the history
使用Engines简单实现redis上线,仅作为接入样例
  • Loading branch information
hhyo authored Apr 5, 2019
2 parents b335b7c + ef7bcdb commit cef6873
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 11 deletions.
54 changes: 53 additions & 1 deletion sql/engines/redis.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import logging
import traceback
from . import EngineBase
from .models import ResultSet
from .models import ResultSet, ReviewSet, ReviewResult

__author__ = 'hhyo'

Expand Down Expand Up @@ -91,3 +91,55 @@ def filter_sql(self, sql='', limit_num=0):
def query_masking(self, db_name=None, sql='', resultset=None):
"""不做脱敏"""
return resultset

def execute_check(self, db_name=None, sql=''):
"""上线单执行前的检查, 返回Review set"""
check_result = ReviewSet(full_sql=sql)
result = ReviewResult(id=1,
errlevel=0,
stagestatus='Audit completed',
errormessage='None',
sql=sql,
affected_rows=0,
execute_time=0, )
check_result.rows += [result]
return check_result

def execute_workflow(self, workflow):
"""执行上线单,返回Review set"""
sql = workflow.sqlworkflowcontent.sql_content
execute_result = ReviewSet(full_sql=sql)
try:
conn = self.get_connection()
if workflow.db_name:
conn.execute_command(f"select {workflow.db_name}")
conn.execute_command(workflow.sqlworkflowcontent.sql_content)
except Exception as e:
logger.error(f"Redis命令执行报错,语句:{sql}, 错误信息:{traceback.format_exc()}")
execute_result.error = str(e)
execute_result.status = "workflow_exception"
execute_result.rows.append(ReviewResult(
id=1,
errlevel=2,
stagestatus='Execute Failed',
errormessage=f'异常信息:{e}',
sql=sql,
affected_rows=0,
execute_time=0,
))
else:
execute_result.status = "workflow_finish"
execute_result.rows.append(ReviewResult(
id=1,
errlevel=0,
stagestatus='Execute Successfully',
errormessage='None',
sql=sql,
affected_rows=0,
execute_time=0,
))
finally:
workflow.sqlworkflowcontent.execute_result = execute_result.json()
workflow.sqlworkflowcontent.save()
workflow.save()
return execute_result
52 changes: 49 additions & 3 deletions sql/engines/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.test import TestCase

from sql.engines import EngineBase
from sql.engines.models import ResultSet, ReviewSet
from sql.engines.models import ResultSet, ReviewSet, ReviewResult
from sql.engines.mssql import MssqlEngine
from sql.engines.mysql import MysqlEngine
from sql.engines.redis import RedisEngine
Expand Down Expand Up @@ -45,7 +45,6 @@ def setUpClass(cls):
'id': 1,
'sql': 'some_content'
}]))
cls.wf1.save()

@classmethod
def tearDownClass(cls):
Expand Down Expand Up @@ -240,6 +239,8 @@ def setUpClass(cls):
@classmethod
def tearDownClass(cls):
cls.ins.delete()
SqlWorkflow.objects.all().delete()
SqlWorkflowContent.objects.all().delete()

@patch('redis.Redis')
def test_get_connection(self, _conn):
Expand Down Expand Up @@ -299,6 +300,51 @@ def test_query_masking(self):
masking_result = new_engine.query_masking(db_name=0, sql='', resultset=query_result)
self.assertEqual(masking_result, query_result)

def test_execute_check(self):
sql = 'set 1 1'
row = ReviewResult(id=1,
errlevel=0,
stagestatus='Audit completed',
errormessage='None',
sql=sql,
affected_rows=0,
execute_time=0,
full_sql=sql)
new_engine = RedisEngine(instance=self.ins)
check_result = new_engine.execute_check(db_name=0, sql=sql)
self.assertIsInstance(check_result, ReviewSet)
self.assertEqual(check_result.rows[0].__dict__, row.__dict__)

@patch('redis.Redis.execute_command', return_value='text')
def test_execute_workflow_success(self, _execute_command):
sql = 'set 1 1'
row = ReviewResult(id=1,
errlevel=0,
stagestatus='Execute Successfully',
errormessage='None',
sql=sql,
affected_rows=0,
execute_time=0,
full_sql=sql)
wf = SqlWorkflow.objects.create(
workflow_name='some_name',
group_id=1,
group_name='g1',
engineer_display='',
audit_auth_groups='some_group',
create_time=datetime.now() - timedelta(days=1),
status='workflow_finish',
is_backup='是',
instance=self.ins,
db_name='some_db',
syntax_type=1
)
SqlWorkflowContent.objects.create(workflow=wf, sql_content=sql)
new_engine = RedisEngine(instance=self.ins)
execute_result = new_engine.execute_workflow(workflow=wf)
self.assertIsInstance(execute_result, ReviewSet)
self.assertEqual(execute_result.rows[0].__dict__, row.__dict__)


class TestPgSQL(TestCase):
@classmethod
Expand Down Expand Up @@ -358,7 +404,7 @@ def test_get_all_columns_by_tb(self, _query):
return_value=ResultSet(rows=[('postgres',), ('archery',), ('template1',), ('template0',)]))
def test_describe_table(self, _query):
new_engine = PgSQLEngine(instance=self.ins)
describe = new_engine.describe_table(db_name='archery', schema_name='archery',tb_name='text')
describe = new_engine.describe_table(db_name='archery', schema_name='archery', tb_name='text')
self.assertIsInstance(describe, ResultSet)

def test_query_check_disable_sql(self):
Expand Down
2 changes: 1 addition & 1 deletion sql/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class SqlWorkflow(models.Model):
group_name = models.CharField('组名称', max_length=100)
instance = models.ForeignKey(Instance, on_delete=models.CASCADE)
db_name = models.CharField('数据库', max_length=64)
syntax_type = models.IntegerField('工单类型 0、未知,1、DDL,2、DML', choices=((0, '未知'), (1, 'DDL'), (2, 'DML')), default=0)
syntax_type = models.IntegerField('工单类型 0、未知,1、DDL,2、DML', choices=((0, '其他'), (1, 'DDL'), (2, 'DML')), default=0)
is_backup = models.CharField('是否备份', choices=(('否', '否'), ('是', '是')), max_length=20)
engineer = models.CharField('发起人', max_length=30)
engineer_display = models.CharField('发起人中文名', max_length=50, default='')
Expand Down
2 changes: 1 addition & 1 deletion sql/sql_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def submit(request):

# 验证组权限(用户是否在该组、该组是否有指定实例)
try:
user_instances(request.user, type='master', db_type='mysql').get(instance_name=instance_name)
user_instances(request.user, type='master', db_type='all').get(instance_name=instance_name)
except instance.DoesNotExist:
context = {'errMsg': '你所在组未关联该实例!'}
return render(request, 'error.html', context)
Expand Down
2 changes: 1 addition & 1 deletion sql/templates/queryapplylist.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ <h4 class="modal-title" id="myModalLabel">申请数据库查询权限</h4>
<optgroup id="optgroup-mysql" label="MySQL"></optgroup>
<optgroup id="optgroup-mssql" label="MsSQL"></optgroup>
<optgroup id="optgroup-redis" label="Redis"></optgroup>
<optgroup id="optgroup-pgsql" label="Redis"></optgroup>
<optgroup id="optgroup-pgsql" label="PgSQL"></optgroup>
</select>
</div>
<div class="form-group">
Expand Down
20 changes: 17 additions & 3 deletions sql/templates/sqlsubmit.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
class="selectpicker show-tick form-control bs-select-hidden" data-name="实例"
data-live-search="true" data-placeholder="请选择实例" required>
<option value="is-empty" disabled="" selected="selected">请选择实例:</option>
<optgroup id="optgroup-mysql" label="MySQL"></optgroup>
<optgroup id="optgroup-mssql" label="MsSQL"></optgroup>
<optgroup id="optgroup-redis" label="Redis"></optgroup>
<optgroup id="optgroup-pgsql" label="PgSQL"></optgroup>
</select>
</div>
<div class="form-group">
Expand Down Expand Up @@ -564,12 +568,22 @@ <h4 class="modal-title text-danger">提交信息确认</h4>
success: function (data) {
if (data.status === 0) {
var result = data['data'];
$("#instance_name").empty();
$("#optgroup-mysql").empty();
$("#optgroup-mssql").empty();
$("#optgroup-redis").empty();
$("#optgroup-pgsql").empty();
for (var i = 0; i < result.length; i++) {
var instance = "<option value=\"" + result[i]['instance_name'] + "\">" + result[i]['instance_name'] + "</option>";
$("#instance_name").append(instance);
if (result[i]['db_type'] === 'mysql') {
$("#optgroup-mysql").append(instance);
} else if (result[i]['db_type'] === 'mssql') {
$("#optgroup-mssql").append(instance);
} else if (result[i]['db_type'] === 'redis') {
$("#optgroup-redis").append(instance);
} else if (result[i]['db_type'] === 'pgsql') {
$("#optgroup-pgsql").append(instance);
}
}
$("#instance_name").prepend("<option value=\"is-empty\" disabled=\"\" selected=\"selected\">请选择实例:</option>");
$('#instance_name').selectpicker('render');
$('#instance_name').selectpicker('refresh');
$("#db_name").empty();
Expand Down
4 changes: 3 additions & 1 deletion sql/templates/sqlworkflow.html
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ <h4 class="modal-title text-danger">工单日志</h4>
title: '类型',
field: 'syntax_type',
formatter: function (value, row, index) {
if (value === 1) {
if (value === 0) {
return '其他'
} else if (value === 1) {
return 'DDL'
} else if (value === 2) {
return 'DML'
Expand Down

0 comments on commit cef6873

Please # to comment.