From 22acce8bc020cad24f6d2ccb8ed1ad74dd35134f Mon Sep 17 00:00:00 2001 From: midoks Date: Thu, 29 Dec 2022 23:32:14 +0800 Subject: [PATCH] =?UTF-8?q?mysql=E4=B8=BB=E4=BB=8E=E5=8A=A0=E5=85=A5?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E5=90=8C=E6=AD=A5=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/mysql/conf/mysql.sql | 12 ++ plugins/mysql/index.html | 2 +- plugins/mysql/index.py | 217 ++++++++++++++++++++++++++++-- plugins/mysql/js/mysql.js | 253 ++++++++++++++++++++++++++++++++++- route/static/app/public.js | 4 + 5 files changed, 474 insertions(+), 14 deletions(-) diff --git a/plugins/mysql/conf/mysql.sql b/plugins/mysql/conf/mysql.sql index f6df3e957..658e9030f 100755 --- a/plugins/mysql/conf/mysql.sql +++ b/plugins/mysql/conf/mysql.sql @@ -40,4 +40,16 @@ CREATE TABLE IF NOT EXISTS `slave_id_rsa` ( `addtime` TEXT ); +-- drop table `slave_user`; +CREATE TABLE IF NOT EXISTS `slave_sync_user` ( + `id` INTEGER PRIMARY KEY AUTOINCREMENT, + `ip` TEXT, + `port` TEXT, + `user` TEXT, + `pass` TEXT, + `mode` TEXT, + `cmd` TEXT, + `addtime` TEXT +); + diff --git a/plugins/mysql/index.html b/plugins/mysql/index.html index 8525ae05e..bb839bd41 100755 --- a/plugins/mysql/index.html +++ b/plugins/mysql/index.html @@ -53,7 +53,7 @@ .conf_p span { display: inline-block; margin-right: 10px; - width: 135px; + width: 115px; text-align: right; } diff --git a/plugins/mysql/index.py b/plugins/mysql/index.py index eaef4323c..6b84cdd7d 100755 --- a/plugins/mysql/index.py +++ b/plugins/mysql/index.py @@ -133,14 +133,8 @@ def pSqliteDb(dbname='databases'): csql_list = csql.split(';') for index in range(len(csql_list)): conn.execute(csql_list[index], ()) - else: - # 现有run - # conn = mw.M(dbname).dbPos(getServerDir(), name) - # csql = mw.readFile(getPluginDir() + '/conf/mysql.sql') - # csql_list = csql.split(';') - # for index in range(len(csql_list)): - # conn.execute(csql_list[index], ()) - conn = mw.M(dbname).dbPos(getServerDir(), name) + + conn = mw.M(dbname).dbPos(getServerDir(), name) return conn @@ -2103,6 +2097,123 @@ def getSlaveSSHList(version=''): return mw.getJson(data) +def getSlaveSyncUserByIp(version=''): + args = getArgs() + data = checkArgs(args, ['ip']) + if not data[0]: + return data[1] + + ip = args['ip'] + + conn = pSqliteDb('slave_sync_user') + data = conn.field('ip,port,user,pass,mode,cmd').where( + "ip=?", (ip,)).select() + return mw.returnJson(True, 'ok', data) + + +def addSlaveSyncUser(version=''): + import base64 + + args = getArgs() + data = checkArgs(args, ['ip']) + if not data[0]: + return data[1] + + ip = args['ip'] + if ip == "": + return mw.returnJson(True, 'ok') + + data = checkArgs(args, ['port', 'user', 'pass', 'mode']) + if not data[0]: + return data[1] + + cmd = args['cmd'] + port = args['port'] + user = args['user'] + apass = args['pass'] + mode = args['mode'] + addTime = time.strftime('%Y-%m-%d %X', time.localtime()) + + conn = pSqliteDb('slave_sync_user') + data = conn.field('ip').where("ip=?", (ip,)).select() + if len(data) > 0: + res = conn.where("ip=?", (ip,)).save( + 'port,user,pass,mode,cmd', (port, user, apass, mode, cmd)) + else: + conn.add('ip,port,user,cmd,user,pass,mode,addtime', + (ip, port, user, cmd, user, apass, mode, addTime)) + + return mw.returnJson(True, '设置成功!') + + +def delSlaveSyncUser(version=''): + args = getArgs() + data = checkArgs(args, ['ip']) + if not data[0]: + return data[1] + + ip = args['ip'] + + conn = pSqliteDb('slave_sync_user') + conn.where("ip=?", (ip,)).delete() + return mw.returnJson(True, '删除成功!') + + +def getSlaveSyncUserList(version=''): + args = getArgs() + data = checkArgs(args, ['page', 'page_size']) + if not data[0]: + return data[1] + + page = int(args['page']) + page_size = int(args['page_size']) + + conn = pSqliteDb('slave_sync_user') + limit = str((page - 1) * page_size) + ',' + str(page_size) + + field = 'id,ip,port,user,pass,cmd,addtime' + clist = conn.field(field).limit(limit).order('id desc').select() + count = conn.count() + + data = {} + _page = {} + _page['count'] = count + _page['p'] = page + _page['row'] = page_size + _page['tojs'] = args['tojs'] + data['page'] = mw.getPage(_page) + data['data'] = clist + + return mw.getJson(data) + + +def getSyncModeFile(): + return getServerDir() + "/sync.mode" + + +def getSlaveSyncMode(version): + sync_mode = getSyncModeFile() + if os.path.exists(sync_mode): + mode = mw.readFile(sync_mode).strip() + return mw.returnJson(True, 'ok', mode) + return mw.returnJson(False, 'fail') + + +def setSlaveSyncMode(version): + args = getArgs() + data = checkArgs(args, ['mode']) + if not data[0]: + return data[1] + mode = args['mode'] + sync_mode = getSyncModeFile() + + if mode == 'none': + os.remove(sync_mode) + else: + mw.writeFile(sync_mode, mode) + return mw.returnJson(True, '设置成功', mode) + + def getSlaveSSHByIp(version=''): args = getArgs() data = checkArgs(args, ['ip']) @@ -2160,7 +2271,7 @@ def delSlaveSSH(version=''): conn = pSqliteDb('slave_id_rsa') conn.where("ip=?", (ip,)).delete() - return mw.returnJson(True, 'ok') + return mw.returnJson(True, '删除SSH成功!') def updateSlaveSSH(version=''): @@ -2205,6 +2316,47 @@ def getSlaveSyncCmd(version=''): def initSlaveStatus(version=''): + mode_file = getSyncModeFile() + if not os.path.exists(mode_file): + return mw.returnJson(False, '需要先设置同步配置') + + mode = mw.readFile(mode_file) + if mode == 'ssh': + return initSlaveStatusSSH(version) + if mode == 'sync-user': + return initSlaveStatusSyncUser(version) + + +def initSlaveStatusSyncUser(version=''): + conn = pSqliteDb('slave_sync_user') + data = conn.field('ip,port,user,pass,mode,cmd').find() + if len(data) < 1: + return mw.returnJson(False, '需要先添加同步用户配置!') + + # print(data) + db = pMysqlDb() + dlist = db.query('show slave status') + if len(dlist) > 0: + return mw.returnJson(False, '已经初始化好了zz...') + + u = data + + mode_name = 'classic' + if u['mode'] == '1': + mode_name = 'gtid' + + local_mode = recognizeDbMode() + if local_mode != mode_name: + return mw.returnJson(False, '同步模式不一致!') + + t = db.query(u['cmd']) + # print(t) + db.query("start slave user='{}' password='{}';".format( + u['user'], u['pass'])) + return mw.returnJson(True, '初始化成功!') + + +def initSlaveStatusSSH(version=''): db = pMysqlDb() dlist = db.query('show slave status') if len(dlist) > 0: @@ -2214,7 +2366,7 @@ def initSlaveStatus(version=''): data = conn.field('ip,port,id_rsa').find() if len(data) < 1: - return mw.returnJson(False, '需要先配置【[主]SSH配置】!') + return mw.returnJson(False, '需要先添加SSH配置!') SSH_PRIVATE_KEY = "/tmp/t_ssh.txt" ip = data['ip'] @@ -2273,6 +2425,39 @@ def initSlaveStatus(version=''): def setSlaveStatus(version=''): + mode_file = getSyncModeFile() + if not os.path.exists(mode_file): + return mw.returnJson(False, '需要先设置同步配置') + + mode = mw.readFile(mode_file) + if mode == 'ssh': + return setSlaveStatusSSH(version) + if mode == 'sync-user': + return setSlaveStatusSyncUser(version) + + +def setSlaveStatusSyncUser(version=''): + db = pMysqlDb() + dlist = db.query('show slave status') + if len(dlist) == 0: + return mw.returnJson(False, '需要手动添加同步账户或者执行初始化!') + + if len(dlist) > 0 and (dlist[0]["Slave_IO_Running"] == 'Yes' or dlist[0]["Slave_SQL_Running"] == 'Yes'): + db.query('stop slave') + else: + ip = dlist[0]['Master_Host'] + conn = pSqliteDb('slave_sync_user') + data = conn.field('ip,port,user,pass,mode,cmd').find() + if len(data) == 0: + return mw.returnJson(False, '没有数据无法重启!') + user = data['user'] + apass = data['pass'] + db.query("start slave user='{}' password='{}';".format(user, apass)) + + return mw.returnJson(True, '设置成功!') + + +def setSlaveStatusSSH(version=''): db = pMysqlDb() dlist = db.query('show slave status') @@ -2653,6 +2838,18 @@ if __name__ == "__main__": print(delSlaveSSH(version)) elif func == 'update_slave_ssh': print(updateSlaveSSH(version)) + elif func == 'get_slave_sync_user_list': + print(getSlaveSyncUserList(version)) + elif func == 'get_slave_sync_user_by_ip': + print(getSlaveSyncUserByIp(version)) + elif func == 'add_slave_sync_user': + print(addSlaveSyncUser(version)) + elif func == 'del_slave_sync_user': + print(delSlaveSyncUser(version)) + elif func == 'get_slave_sync_mode': + print(getSlaveSyncMode(version)) + elif func == 'set_slave_sync_mode': + print(setSlaveSyncMode(version)) elif func == 'init_slave_status': print(initSlaveStatus(version)) elif func == 'set_slave_status': diff --git a/plugins/mysql/js/mysql.js b/plugins/mysql/js/mysql.js index 55600d0e5..466147187 100755 --- a/plugins/mysql/js/mysql.js +++ b/plugins/mysql/js/mysql.js @@ -1821,8 +1821,23 @@ function addSlaveSSH(ip=''){ function delSlaveSSH(ip){ myPost('del_slave_ssh', {ip:ip}, function(rdata){ var rdata = $.parseJSON(rdata.data); - layer.msg(rdata.msg, {icon: rdata.status ? 1 : 2}); - getSlaveSSHPage(); + showMsg(rdata.msg,function(){ + if (rdata.status){ + getSlaveSSHPage(); + } + },{icon: rdata.status ? 1 : 2}, 600); + }); +} + + +function delSlaveSyncUser(ip){ + myPost('del_slave_sync_user', {ip:ip}, function(rdata){ + var rdata = $.parseJSON(rdata.data); + showMsg(rdata.msg,function(){ + if (rdata.status){ + getSlaveSyncUserPage(); + } + },{icon: rdata.status ? 1 : 2}, 600); }); } @@ -1872,6 +1887,238 @@ function getSlaveSSHPage(page=1){ } + +function addSlaveSyncUser(ip=''){ + + myPost('get_slave_sync_user_by_ip', {ip:ip}, function(rdata){ + + var rdata = $.parseJSON(rdata.data); + + var ip = '127.0.0.1'; + var port = "22"; + var cmd = ''; + var user = 'input_sync_user'; + var pass = 'input_sync_pwd'; + var mode = '0'; + + if (rdata.data.length>0){ + ip = rdata.data[0]['ip']; + port = rdata.data[0]['port']; + cmd = rdata.data[0]['cmd']; + user = rdata.data[0]['user']; + pass = rdata.data[0]['pass']; + mode = rdata.data[0]['mode']; + } + + var index = layer.open({ + type: 1, + area: ['500px','470px'], + title: '同步账户', + closeBtn: 1, + shift: 5, + shadeClose: true, + btn:["确认","取消"], + content: "
\ +
IP
\ +
端口
\ +
同步账户
\ +
同步密码
\ +
\ + CMD[可选]\ +
\ +
\ + \ +
", + success:function(){ + $('textarea[name="cmd"]').html(cmd); + + $('textarea[name="cmd"]').change(function(){ + var val = $(this).val(); + var vlist = val.split(','); + var a = {}; + for (var i in vlist) { + var tmp = toTrim(vlist[i]); + var tmp_a = tmp.split(" "); + var real_tmp = tmp_a[tmp_a.length-1]; + var kv = real_tmp.split("="); + a[kv[0]] = kv[1].replace("'",'').replace("'",''); + } + + $('input[name="ip"]').val(a['MASTER_HOST']); + $('input[name="port"]').val(a['MASTER_PORT']); + $('input[name="user"]').val(a['MASTER_USER']); + $('input[name="pass"]').val(a['MASTER_PASSWORD']); + + console.log(a['MASTER_AUTO_POSITION'],typeof(a['MASTER_AUTO_POSITION'])); + if (typeof(a['MASTER_AUTO_POSITION']) != 'undefined' ){ + $('input[name="mode"]').val('1'); + } + }); + }, + yes:function(index){ + var ip = $('input[name="ip"]').val(); + var port = $('input[name="port"]').val(); + var user = $('input[name="user"]').val(); + var pass = $('input[name="pass"]').val(); + var cmd = $('textarea[name="cmd"]').val(); + var mode = $('input[name="mode"]').val(); + + var data = {ip:ip,port:port,cmd:cmd,user:user,pass:pass,mode:mode}; + myPost('add_slave_sync_user', data, function(ret_data){ + layer.close(index); + var rdata = $.parseJSON(ret_data.data); + showMsg(rdata.msg,function(){ + if (rdata.status){ + getSlaveSyncUserPage(); + } + },{icon: rdata.status ? 1 : 2},600); + }); + } + }); + }); +} + +function getSlaveSyncUserPage(page=1){ + var _data = {}; + _data['page'] = page; + _data['page_size'] = 5; + _data['tojs'] ='getSlaveSyncUserPage'; + myPost('get_slave_sync_user_list', _data, function(data){ + var layerId = null; + var rdata = []; + try { + rdata = $.parseJSON(data.data); + } catch(e) { + console.log(e); + } + + var list = ''; + var user_list = rdata['data']; + for (i in user_list) { + var ip = user_list[i]['ip']; + var port = user_list[i]['port']; + var user = user_list[i]['user']; + var apass = user_list[i]['pass']; + + var cmd = '未设置'; + if (user_list[i]['cmd']!=''){ + cmd = '已设置'; + } + + list += ''+ip+'\ + '+port+'\ + '+user+'\ + '+apass+'\ + '+cmd+'\ + \ + 修改 | \ + 删除\ + \ + '; + } + + $('.get-slave-ssh-list tbody').html(list); + $('.dataTables_paginate_4').html(rdata['page']); + }); +} + +function getSlaveCfg(){ + + + myPost('get_slave_sync_mode', '', function(data){ + var rdata = $.parseJSON(data.data); + var mode_none = 'success'; + var mode_ssh = 'danger'; + var mode_sync_user = 'danger'; + if(rdata.status){ + var mode_none = 'danger'; + if (rdata.data == 'ssh'){ + var mode_ssh = 'success'; + var mode_sync_user = 'danger'; + } else { + var mode_ssh = 'danger'; + var mode_sync_user = 'success'; + } + } + + layerId = layer.open({ + type: 1, + title: '同步配置', + area: ['400px','180px'], + content:"
\ +

\ + 当前从库同步模式\ + \ + \ + \ + \ +

\ +
\ +

\ + 配置设置\ + \ + \ + \ +

\ +
", + success:function(){ + $('.btn-slave-ssh').click(function(){ + getSlaveSSHList(); + }); + + $('.btn-slave-user').click(function(){ + getSlaveUserList(); + }); + + $('.slave-db-mode').click(function(){ + var _this = this; + var mode = 'none'; + if ($(this).hasClass('btn-ssh')){ + mode = 'ssh'; + } + if ($(this).hasClass('btn-sync-user')){ + mode = 'sync-user'; + } + + myPost('set_slave_sync_mode', {mode:mode}, function(data){ + var rdata = $.parseJSON(data.data); + showMsg(rdata.msg,function(){ + $('.slave-db-mode').remove('btn-success').addClass('btn-danger'); + $(_this).removeClass('btn-danger').addClass('btn-success'); + },{icon:rdata.status?1:2},2000); + }); + + }); + } + }); + }); +} + + +function getSlaveUserList(){ + + var page = '
'; + page += '
添加同步账户
'; + + layerId = layer.open({ + type: 1, + title: '同步账户列表', + area: '500px', + content:"
\ +
\ +
\ + \ + \ +
IPPORT同步账户同步密码CMD操作
\ + "+page +"\ +
\ +
", + success:function(){ + getSlaveSyncUserPage(1); + } + }); +} + function getSlaveSSHList(page=1){ var page = '
'; @@ -2110,7 +2357,7 @@ function masterOrSlaveConf(version=''){

\ Slave[从]配置\ \ - \ + \ \

\
\ diff --git a/route/static/app/public.js b/route/static/app/public.js index 08b576838..48b700791 100755 --- a/route/static/app/public.js +++ b/route/static/app/public.js @@ -16,6 +16,10 @@ function toSize(a) { } } +function toTrim(x) { + return x.replace(/^\s+|\s+$/gm,''); +} + function inArray(f, arr){ for (var i = 0; i < arr.length; i++) { if (f == arr[i]) {