From 9d3185c6fbc875e175cebde13a24f7a2b28504bf Mon Sep 17 00:00:00 2001 From: midoks Date: Thu, 28 Jul 2022 23:08:34 +0800 Subject: [PATCH] rsyncd ip xx1 --- plugins/rsyncd/conf/config.json | 26 +++ plugins/rsyncd/index.py | 204 ++++++++++++++++---- plugins/rsyncd/js/rsyncd.js | 322 +++++++++++++++++++++++++------- 3 files changed, 445 insertions(+), 107 deletions(-) create mode 100644 plugins/rsyncd/conf/config.json diff --git a/plugins/rsyncd/conf/config.json b/plugins/rsyncd/conf/config.json new file mode 100644 index 000000000..2e301d90e --- /dev/null +++ b/plugins/rsyncd/conf/config.json @@ -0,0 +1,26 @@ +{ + "receive":{ + "default":{ + "uid": "root", + "use chroot": "no", + "dont compress": "*.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 *.mp4 *.avi *.swf *.rar", + "hosts allow": "", + "max connections": 200, + "gid": "root", + "timeout": 600, + "pid file": "/var/run/rsyncd.pid", + "log file": "/var/log/rsyncd.log", + "port": 873 + }, + "list":[] + }, + "send":{ + "default":{ + "logfile": "/www/server/rsyncd/lsyncd.log", + "inotifyMode": "CloseWrite", + "maxProcesses": "8", + "statusFile": "/www/server/rsyncd/lsyncd.status" + }, + "list":[] + } +} \ No newline at end of file diff --git a/plugins/rsyncd/index.py b/plugins/rsyncd/index.py index 42436a931..993915142 100755 --- a/plugins/rsyncd/index.py +++ b/plugins/rsyncd/index.py @@ -202,12 +202,36 @@ def initDSend(): return file_bin +def getDefaultConf(): + path = getServerDir() + "/config.json" + data = mw.readFile(path) + data = json.loads(data) + return data + + +def setDefaultConf(data): + path = getServerDir() + "/config.json" + mw.writeFile(path, json.dumps(data)) + return True + + +def initConfigJson(): + path = getServerDir() + "/config.json" + tpl = getPluginDir() + "/conf/config.json" + if not os.path.exists(path): + data = mw.readFile(tpl) + data = json.loads(data) + mw.writeFile(path, json.dumps(data)) + + def initDreplace(): initDSend() # conf file_bin = initDReceive() + initConfigJson() + return file_bin @@ -299,23 +323,18 @@ def getRecListData(): return ret_list +def getRecListDataBy(name): + l = getRecListData() + for x in range(len(l)): + if name == l[x]["name"]: + return l[x] + + def getRecList(): ret_list = getRecListData() return mw.returnJson(True, 'ok', ret_list) -def getUPwdList(): - pwd_path = appConfPwd() - pwd_content = mw.readFile(pwd_path) - plist = pwd_content.strip().split('\n') - plist_len = len(plist) - data = {} - for x in range(plist_len): - tmp = plist[x].split(':') - data[tmp[0]] = tmp[1] - return data - - def addRec(): args = getArgs() data = checkArgs(args, ['name', 'path', 'pwd', 'ps']) @@ -327,6 +346,8 @@ def addRec(): args_path = args['path'] args_ps = args['ps'] + delRecBy(args_name) + auth_path = appAuthPwd(args_name) pwd_content = args_name + ':' + args_pwd + "\n" mw.writeFile(auth_path, pwd_content) @@ -343,69 +364,168 @@ def addRec(): con += 'secrets file = ' + auth_path + "\n" con += 'read only = false' - content = content + con + content = content.strip() + "\n" + con mw.writeFile(path, content) return mw.returnJson(True, '添加成功') -def delRec(): +def getRec(): args = getArgs() data = checkArgs(args, ['name']) if not data[0]: return data[1] - args_name = args['name'] - cmd = "sed -i '_bak' '/" + args_name + "/d' " + appConfPwd() - mw.execShell(cmd) + name = args['name'] - try: + if name == "": + tmp = {} + tmp["name"] = "" + tmp["path"] = mw.getWwwDir() + tmp["pwd"] = mw.getRandomString(16) + return mw.returnJson(True, 'OK', tmp) + + data = getRecListDataBy(name) + + content = mw.readFile(data['secrets file']) + pwd = content.strip().split(":") + data['pwd'] = pwd[1] + return mw.returnJson(True, 'OK', data) + +def delRecBy(name): + try: path = appConf() content = mw.readFile(path) - ret_list = getRecListData() - ret_list_len = len(ret_list) + reclist = getRecListData() + ret_list_len = len(reclist) is_end = False next_name = '' for x in range(ret_list_len): - tmp = ret_list[x] - if tmp['name'] == args_name: + tmp = reclist[x] + if tmp['name'] == name: + + secrets_file = tmp['secrets file'] + tp = os.path.dirname(secrets_file) + if os.path.exists(tp): + mw.execShell("rm -rf " + tp) + if x + 1 == ret_list_len: is_end = True else: - next_name = ret_list[x + 1]['name'] + next_name = reclist[x + 1]['name'] reg = '' if is_end: - reg = '\[' + args_name + '\]\s*(.*)' + reg = '\[' + name + '\]\s*(.*)' else: - reg = '\[' + args_name + '\]\s*(.*)\s*\[' + next_name + '\]' + reg = '\[' + name + '\]\s*(.*)\s*\[' + next_name + '\]' conre = re.search(reg, content, re.S) content = content.replace( - "[" + args_name + "]\n" + conre.groups()[0], '') + "[" + name + "]\n" + conre.groups()[0], '') mw.writeFile(path, content) - return mw.returnJson(True, '删除成功!') except Exception as e: - return mw.returnJson(False, '删除失败!') + return False + return True -def cmdRec(): +def delRec(): args = getArgs() data = checkArgs(args, ['name']) if not data[0]: return data[1] + name = args['name'] + ok = delRecBy(name) + if ok: + return mw.returnJson(True, '删除成功!') + return mw.returnJson(False, '删除失败!') + - an = args['name'] - pwd_list = getUPwdList() +def cmdRecSecretKey(): + import base64 + + args = getArgs() + data = checkArgs(args, ['name']) + if not data[0]: + return data[1] + + name = args['name'] + info = getRecListDataBy(name) + + m = json.dumps(info) + m = m.encode("utf-8") + m = base64.b64encode(m) + cmd = m.decode("utf-8") + return mw.returnJson(True, 'OK!', cmd) + + +def cmdRecCmd(): + args = getArgs() + data = checkArgs(args, ['name']) + if not data[0]: + return data[1] + + name = args['name'] + info = getRecListDataBy(name) ip = mw.getLocalIp() - cmd = 'echo "' + pwd_list[an] + '" > /tmp/p.pass' + "
" - cmd += 'chmod 600 /tmp/p.pass' + "
" - cmd += 'rsync -arv --password-file=/tmp/p.pass --progress --delete /project ' + \ - an + '@' + ip + '::' + an + content = mw.readFile(info['secrets file']) + pwd = content.strip().split(":") + + tmp_name = '/tmp/' + name + '.pass' + + cmd = 'echo "' + pwd[1] + '" > ' + tmp_name + '
' + cmd += 'chmod 600 ' + tmp_name + '
' + cmd += 'rsync -arv --password-file=' + tmp_name + \ + ' --progress --delete /project ' + name + '@' + ip + '::' + name return mw.returnJson(True, 'OK!', cmd) -# rsyncdReceive + +# ----------------------------- rsyncdSend start ------------------------- + + +def lsyncdListFindIp(slist, ip): + for x in range(len(slist)): + if slist[x]["ip"] == ip: + return (True, x) + return (False, -1) + + +def lsyncdList(): + data = getDefaultConf() + send = data['send'] + return mw.returnJson(True, "设置成功!", send) + + +def lsyncdAdd(): + + args = getArgs() + data = checkArgs(args, ['ip', 'name']) + if not data[0]: + return data[1] + + ip = args['ip'] + path = args['path'] + + info = { + "ip": ip, + "path": path + } + + data = getDefaultConf() + slist = data['send']["list"] + res = lsyncdListFindIp(slist, ip) + if res[0]: + list_index = res[1] + slist[list_index] = info + else: + slist.append(info) + data['send']["list"] = slist + + setDefaultConf(data) + return mw.returnJson(True, "设置成功!") + + if __name__ == "__main__": func = sys.argv[1] if func == 'status': @@ -434,7 +554,15 @@ if __name__ == "__main__": print(addRec()) elif func == 'del_rec': print(delRec()) - elif func == 'cmd_rec': - print(cmdRec()) + elif func == 'get_rec': + print(getRec()) + elif func == 'cmd_rec_secret_key': + print(cmdRecSecretKey()) + elif func == 'cmd_rec_cmd': + print(cmdRecCmd()) + elif func == 'lsyncd_list': + print(lsyncdList()) + elif func == 'lsyncd_add': + print(lsyncdAdd()) else: print('error') diff --git a/plugins/rsyncd/js/rsyncd.js b/plugins/rsyncd/js/rsyncd.js index 04d86cb8d..0f83aa026 100755 --- a/plugins/rsyncd/js/rsyncd.js +++ b/plugins/rsyncd/js/rsyncd.js @@ -38,42 +38,204 @@ function rsPost(method,args,callback, title){ ///////////////// ----------------- 发送配置 ---------------- ////////////// +function createSendTask(){ + + layer.open({ + type: 1, + area: ['600px','500px'], + title: "创建发送任务", + closeBtn: 1, + shift: 0, + shadeClose: false, + btn: ['提交','取消'], + content:"
\ +
\ + 服务器IP\ +
\ + \ +
\ +
\ +
\ + 同步目录\ +
\ + \ + ?\ +
\ +
\ +
\ + 同步方式\ +
\ + \ + ?\ + 同步周期\ + \ +
\ +
\ + \ + \ +
\ + 限速\ +
\ + KB\ + ?\ + 延迟 秒\ + ?\ +
\ +
\ +
\ + 连接方式\ +
\ + \ + 压缩传输\ + \ + ?\ +
\ +
\ +
\ + 接收密钥\ +
\ + \ +
\ +
\ +
\ + 用户名\ +
\ + \ +
\ +
\ +
\ + 密码\ +
\ + \ +
\ +
\ +
\ + 端口\ +
\ + \ +
\ +
\ + \ +
", + success:function(){ + $('[data-toggle="tooltip"]').tooltip(); + + $(".conn-user").hide(); + $("select[name='conn_type']").change(function(){ + if($(this).val() == 'key'){ + $(".conn-user").hide(); + $(".conn-key").show(); + }else{ + $(".conn-user").show(); + $(".conn-key").hide(); + } + }); + }, + yes:function(){ + var args = {}; + args['ip'] = $('input[name="ip"]').val(); + args['path'] = $('input[name="path"]').val(); + args['delete'] = $('input[name="delete"]').val(); + args['realtime'] = $('input[name="realtime"]').val(); + + args['bwlimit'] = $('input[name="bwlimit"]').val(); + args['conn_type'] = $('input[name="conn_type"]').val(); + args['compress'] = $('input[name="compress"]').val(); + + + console.log(args); + rsPost('lsyncd_add', args, function(rdata){ + console.log(rdata); + }); + return false; + } + }); +} + function rsyncdSend(){ - rsPost('rec_list', '', function(data){ + rsPost('lsyncd_list', '', function(data){ var rdata = $.parseJSON(data.data); + console.log(rdata); if (!rdata.status){ layer.msg(rdata.msg,{icon:rdata.status?1:2,time:2000,shade: [0.3, '#000']}); return; } - // console.log(rdata); - var list = rdata.data; + var list = rdata.data.list; var con = ''; con += '
\ - \ + \ \ \
'; con += '
'; con += ''; - con += ''; - con += ''; - con += ''; - con += ''; + con += ''; + con += ''; + con += ''; + con += ''; + con += ''; + con += ''; con += ''; con += ''; - //编辑 for (var i = 0; i < list.length; i++) { con += ''+ - '' + - '' + - '' + + '' + + '' + + '' + + '' + + '' + '\ + 同步\ + | 日志\ + | 过滤器\ + | 编辑\ + | 删除\ + \ '; } @@ -136,7 +298,9 @@ function rsyncdReceive(){ '' + '' + '\ '; } @@ -148,61 +312,67 @@ function rsyncdReceive(){ }); } -function addReceive(){ - var loadOpen = layer.open({ - type: 1, - title: '创建接收', - area: '400px', - content:"
\ -
\ - 项目名\ -
\ - \ + +function addReceive(name = ""){ + rsPost('get_rec',{"name":name},function(rdata) { + var rdata = $.parseJSON(rdata.data); + var data = rdata.data; + + var readonly = ""; + if (name !=""){ + readonly = 'readonly="readonly"' + } + + var loadOpen = layer.open({ + type: 1, + title: '创建接收', + area: '400px', + btn:['确认','取消'], + content:"
\ +
\ + 项目名\ +
\ + \ +
\
\ -
\ -
\ - 密钥\ -
\ - \ - \ +
\ + 密钥\ +
\ + \ + \ +
\
\ -
\ -
\ - 同步到\ -
\ - \ - \ +
\ + 同步到\ +
\ + \ + \ +
\
\ -
\ -
\ - 备注\ -
\ - \ +
\ + 备注\ +
\ + \ +
\
\ -
\ -
\ - \ -
\ -
", - success:function(layero, index){ - repeatPwd(16); - } - }); - - $('#add_ok').click(function(){ - _data = {}; - _data['name'] = $('#name').val(); - _data['pwd'] = $('#MyPassword').val(); - _data['path'] = $('#inputPath').val(); - _data['ps'] = $('#ps').val(); - var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 }); - rsPost('add_rec', _data, function(data){ - var rdata = $.parseJSON(data.data); - layer.close(loadOpen); - layer.msg(rdata.msg,{icon:rdata.status?1:2,time:2000,shade: [0.3, '#000']}); - setTimeout(function(){rsyncdReceive();},2000); +
", + success:function(layero, index){}, + yes:function(){ + var args = {}; + args['name'] = $('#name').val(); + args['pwd'] = $('#MyPassword').val(); + args['path'] = $('#inputPath').val(); + args['ps'] = $('#ps').val(); + var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 }); + rsPost('add_rec', args, function(data){ + var rdata = $.parseJSON(data.data); + layer.close(loadOpen); + layer.msg(rdata.msg,{icon:rdata.status?1:2,time:2000,shade: [0.3, '#000']}); + setTimeout(function(){rsyncdReceive();},2000); + }); + } }); - }); + }) } @@ -218,20 +388,34 @@ function delReceive(name){ }); } -function cmdReceive(name){ +function cmdRecSecretKey(name){ var _data = {}; _data['name'] = name; - rsPost('cmd_rec', _data, function(data){ + rsPost('cmd_rec_secret_key', _data, function(data){ var rdata = $.parseJSON(data.data); layer.open({ type: 1, - title: '命令事例', + title: '接收密钥', area: '400px', - content:"
"+rdata.data+"
" + content:"
" }); }); } +function cmdRecCmd(name){ + var _data = {}; + _data['name'] = name; + rsPost('cmd_rec_cmd', _data, function(data){ + var rdata = $.parseJSON(data.data); + layer.open({ + type: 1, + title: '接收命令例子', + area: '400px', + content:"
"+rdata.data+"
" + }); + }); +} + function rsRead(){ var readme = '
    ';
服务名路径备注操作(添加)名称(标识)源目录同步到模式周期操作
' + list[i]['name']+'' + list[i]['path']+'' + list[i]['comment']+'' + "dd"+'' + list[i]['path']+'' + list[i]['ip']+":"+"cc"+'' + "增量"+'' + "实时" +'\ - 命令\ - | 删除
' + list[i]['path']+'' + list[i]['comment']+'\ - 命令\ + 命令\ + | 密钥\ + | 编辑\ | 删除