diff --git a/common/static/dist/js/utils.js b/common/static/dist/js/utils.js index b706c69cc9..4ff8392310 100644 --- a/common/static/dist/js/utils.js +++ b/common/static/dist/js/utils.js @@ -5,3 +5,21 @@ var onLoadErrorCallback = function (status, jqXHR) { alert("未知错误,请联系管理员处理!"); } }; + +// 实例配置页面根据db_type选择显示或隐藏mode字段,mode字段只适用于redis实例 +(function($) { + $(function() { + let db_type = $('#id_db_type'); + let mode = $('#id_mode').parent().parent(); + + function toggleMode(value) { + value === 'redis' ? mode.show() : mode.hide(); + } + + toggleMode(db_type.val()); + + db_type.change(function() { + toggleMode($(this).val()); + }); + }); +})(django.jQuery); diff --git a/sql/admin.py b/sql/admin.py index 2389956f10..d3f532caad 100755 --- a/sql/admin.py +++ b/sql/admin.py @@ -11,7 +11,7 @@ WorkflowAudit, WorkflowLog, ParamTemplate, ParamHistory, InstanceTag, \ Tunnel, AuditEntry -from sql.form import TunnelForm +from sql.form import TunnelForm, InstanceForm # 用户管理 @@ -62,6 +62,7 @@ def get_readonly_fields(self, request, obj=None): # 实例管理 @admin.register(Instance) class InstanceAdmin(admin.ModelAdmin): + form = InstanceForm list_display = ('id', 'instance_name', 'db_type', 'type', 'host', 'port', 'user', 'create_time') search_fields = ['instance_name', 'host', 'port', 'user'] list_filter = ('db_type', 'type', 'instance_tag') diff --git a/sql/engines/__init__.py b/sql/engines/__init__.py index 00d91f3d91..26aef9bffe 100644 --- a/sql/engines/__init__.py +++ b/sql/engines/__init__.py @@ -17,6 +17,7 @@ def __init__(self, instance=None): self.user = instance.user self.password = instance.password self.db_name = instance.db_name + self.mode = instance.mode # 判断如果配置了隧道则连接隧道,只测试了MySQL if self.instance.tunnel: diff --git a/sql/engines/redis.py b/sql/engines/redis.py index 99b90a94bb..564431d140 100644 --- a/sql/engines/redis.py +++ b/sql/engines/redis.py @@ -25,8 +25,12 @@ class RedisEngine(EngineBase): def get_connection(self, db_name=None): db_name = db_name or self.db_name - return redis.Redis(host=self.host, port=self.port, db=db_name, password=self.password, - encoding_errors='ignore', decode_responses=True, socket_connect_timeout=10) + if self.mode == 'cluster': + return redis.cluster.RedisCluster(host=self.host, port=self.port, password=self.password, + encoding_errors='ignore', decode_responses=True, socket_connect_timeout=10) + else: + return redis.Redis(host=self.host, port=self.port, db=db_name, password=self.password, + encoding_errors='ignore', decode_responses=True, socket_connect_timeout=10) @property def name(self): diff --git a/sql/engines/tests.py b/sql/engines/tests.py index c5413fd208..159fdefc7e 100644 --- a/sql/engines/tests.py +++ b/sql/engines/tests.py @@ -539,8 +539,8 @@ def test_seconds_behind_master(self, _query): class TestRedis(TestCase): @classmethod def setUpClass(cls): - cls.ins = Instance(instance_name='some_ins', type='slave', db_type='redis', host='some_host', - port=1366, user='ins_user', password='some_str') + cls.ins = Instance(instance_name='some_ins', type='slave', db_type='redis', mode='standalone', + host='some_host', port=1366, user='ins_user', password='some_str') cls.ins.save() @classmethod diff --git a/sql/form.py b/sql/form.py index 9b8280bb37..7459dd9f6f 100644 --- a/sql/form.py +++ b/sql/form.py @@ -9,7 +9,7 @@ --------------------------------------------------------- """ from django.forms import ModelForm, Textarea -from sql.models import Tunnel +from sql.models import Tunnel, Instance from django.core.exceptions import ValidationError @@ -30,3 +30,9 @@ def clean(self): cleaned_data['pkey'] = str(pkey_path, 'utf-8').replace(r'\r', '').replace(r'\n', '') except IOError: raise ValidationError("秘钥文件不存在, 请勾选秘钥路径的清除选项再进行保存") + + +class InstanceForm(ModelForm): + class Media: + model = Instance + js = ('jquery/jquery.min.js', 'dist/js/utils.js', ) diff --git a/sql/models.py b/sql/models.py index 883557d9c1..3fa06286bc 100755 --- a/sql/models.py +++ b/sql/models.py @@ -129,6 +129,7 @@ class Instance(models.Model): instance_name = models.CharField('实例名称', max_length=50, unique=True) type = models.CharField('实例类型', max_length=6, choices=(('master', '主库'), ('slave', '从库'))) db_type = models.CharField('数据库类型', max_length=20, choices=DB_TYPE_CHOICES) + mode = models.CharField('运行模式', max_length=10, default='', blank=True, choices=(('standalone', '单机'), ('cluster', '集群'))) host = models.CharField('实例连接', max_length=200) port = models.IntegerField('端口', default=0) user = fields.EncryptedCharField(verbose_name='用户名', max_length=200, default='', blank=True) diff --git a/src/init_sql/v1.8.3.sql b/src/init_sql/v1.8.3.sql index 732810c819..17b07bc25c 100644 --- a/src/init_sql/v1.8.3.sql +++ b/src/init_sql/v1.8.3.sql @@ -28,4 +28,8 @@ insert IGNORE INTO auth_permission (name, content_type_id, codename) VALUES -- 在线查询下载权限 set @content_type_id=(select id from django_content_type where app_label='sql' and model='permission'); insert IGNORE INTO auth_permission (name, content_type_id, codename) VALUES -('在线查询下载权限', @content_type_id, 'query_download'); \ No newline at end of file +('在线查询下载权限', @content_type_id, 'query_download'); + +-- 实例配置表新增mode字段,用于redis实例;为历史数据设置默认值 +alter table sql_instance add column `mode` varchar(10) DEFAULT '' after `db_type`; +update sql_instance set mode='standalone' where db_type='redis';