mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-18 23:45:52 +08:00
update
This commit is contained in:
@@ -15,6 +15,39 @@
|
||||
.inlineBlock {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.db_list{
|
||||
padding: 0px 0 10px 0;
|
||||
font-size: 13px;
|
||||
line-height: 35px;
|
||||
height: 45px;
|
||||
}
|
||||
.db_list a{
|
||||
margin-right: 15px;
|
||||
color: #555;
|
||||
font-weight: 600;
|
||||
}
|
||||
.db_list span:nth-child(1){
|
||||
display: block;
|
||||
float: left;
|
||||
padding-left: 15px;
|
||||
background: #ececec;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#db_tools button {
|
||||
margin-right: 10px;
|
||||
}
|
||||
#db_tools button:last-child{
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.conf_p span {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
width: 115px;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="bt-form">
|
||||
@@ -40,6 +73,7 @@
|
||||
<script type="text/javascript">
|
||||
//mongodb start
|
||||
resetPluginWinHeight(530);
|
||||
resetPluginWinWidth(800);
|
||||
$.getScript('/plugins/file?name=mongodb&f=js/mongodb.js', function(){
|
||||
pluginService('mongodb');
|
||||
});
|
||||
|
||||
+150
-6
@@ -310,12 +310,7 @@ def saveConfig():
|
||||
reload()
|
||||
return mw.returnJson(True,'设置成功')
|
||||
|
||||
# print(mg_pass)
|
||||
# listDbs = client.admin.command({"listDatabases": 1})
|
||||
# print(listDbs)
|
||||
# print(client_pass.list_database_names());
|
||||
def initMgRoot(password='',force=0):
|
||||
|
||||
if force == 1:
|
||||
d = getConfigData()
|
||||
auth_t = d['security']['authorization']
|
||||
@@ -552,6 +547,10 @@ def addDb():
|
||||
if not data_name:
|
||||
return mw.returnJson(False, "数据库名不能为空!")
|
||||
|
||||
nameArr = ['admin', 'config', 'local']
|
||||
if data_name in nameArr:
|
||||
return mw.returnJson(False, "数据库名是保留名称!")
|
||||
|
||||
addTime = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
username = ''
|
||||
password = ''
|
||||
@@ -569,7 +568,7 @@ def addDb():
|
||||
client[data_name].chat.insert_one({})
|
||||
user_roles = [{'role': 'dbOwner', 'db': data_name}, {'role': 'userAdmin', 'db': data_name}]
|
||||
if auth_status:
|
||||
db.command("dropUser", username)
|
||||
# db.command("dropUser", username)
|
||||
db.command("createUser", username, pwd=password, roles=user_roles)
|
||||
|
||||
ps = args['ps']
|
||||
@@ -581,6 +580,35 @@ def addDb():
|
||||
return mw.returnJson(True, '添加成功')
|
||||
|
||||
|
||||
def delDb():
|
||||
client = mongdbClient()
|
||||
db = client.admin
|
||||
sqlite_db = pSqliteDb('databases')
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['id', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
try:
|
||||
sid = args['id']
|
||||
name = args['name']
|
||||
find = sqlite_db.where("id=?", (sid,)).field('id,name,username,password,accept,ps,addtime').find()
|
||||
accept = find['accept']
|
||||
username = find['username']
|
||||
|
||||
client.drop_database(name)
|
||||
|
||||
try:
|
||||
db.command('dropUser',username)
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
# 删除SQLITE
|
||||
sqlite_db.where("id=?", (sid,)).delete()
|
||||
return mw.returnJson(True, '删除成功!')
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, '删除失败!' + str(ex))
|
||||
|
||||
def setRootPwd(version=''):
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['password'])
|
||||
@@ -602,6 +630,112 @@ def setRootPwd(version=''):
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, '修改错误:' + str(ex))
|
||||
|
||||
def setUserPwd(version=''):
|
||||
|
||||
client = mongdbClient()
|
||||
db = client.admin
|
||||
sqlite_db = pSqliteDb('databases')
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['password', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
newpassword = args['password']
|
||||
username = args['name']
|
||||
uid = args['id']
|
||||
try:
|
||||
name = sqlite_db.where('id=?', (uid,)).getField('name')
|
||||
user_roles = [{'role': 'dbOwner', 'db': name}, {'role': 'userAdmin', 'db': name}]
|
||||
|
||||
try:
|
||||
db.command("updateUser", username, pwd=newpassword, roles=user_roles)
|
||||
except Exception as e:
|
||||
db.command("createUser", username, pwd=newpassword, roles=user_roles)
|
||||
|
||||
sqlite_db.where("id=?", (uid,)).setField('password', newpassword)
|
||||
return mw.returnJson(True, mw.getInfo('修改数据库[{1}]密码成功!', (name,)))
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, mw.getInfo('修改数据库[{1}]密码失败[{2}]!', (name, str(ex),)))
|
||||
|
||||
|
||||
def syncGetDatabases():
|
||||
client = mongdbClient()
|
||||
sqlite_db = pSqliteDb('databases')
|
||||
db = client.admin
|
||||
data = client.admin.command({"listDatabases": 1})
|
||||
nameArr = ['admin', 'config', 'local']
|
||||
n = 0
|
||||
|
||||
for value in data['databases']:
|
||||
vdb_name = value["name"]
|
||||
b = False
|
||||
for key in nameArr:
|
||||
if vdb_name == key:
|
||||
b = True
|
||||
break
|
||||
if b:
|
||||
continue
|
||||
if sqlite_db.where("name=?", (vdb_name,)).count() > 0:
|
||||
continue
|
||||
|
||||
host = '127.0.0.1'
|
||||
ps = vdb_name
|
||||
addTime = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
if sqlite_db.add('name,username,password,accept,ps,addtime', (vdb_name, vdb_name, '', host, ps, addTime)):
|
||||
n += 1
|
||||
|
||||
msg = mw.getInfo('本次共从服务器获取了{1}个数据库!', (str(n),))
|
||||
return mw.returnJson(True, msg)
|
||||
|
||||
def setDbPs():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['id', 'name', 'ps'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
ps = args['ps']
|
||||
sid = args['id']
|
||||
name = args['name']
|
||||
try:
|
||||
psdb = pSqliteDb('databases')
|
||||
psdb.where("id=?", (sid,)).setField('ps', ps)
|
||||
return mw.returnJson(True, mw.getInfo('修改数据库[{1}]备注成功!', (name,)))
|
||||
except Exception as e:
|
||||
return mw.returnJson(True, mw.getInfo('修改数据库[{1}]备注失败!', (name,)))
|
||||
|
||||
|
||||
def getDbInfo():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
ret = {}
|
||||
|
||||
client = mongdbClient()
|
||||
|
||||
db_name = args['name']
|
||||
db = client[db_name]
|
||||
|
||||
result = db.command("dbStats")
|
||||
result["collection_list"] = []
|
||||
for collection_name in db.list_collection_names():
|
||||
collection = db.command("collStats", collection_name)
|
||||
data = {
|
||||
"collection_name": collection_name,
|
||||
"count": collection.get("count"), # 文档数
|
||||
"size": collection.get("size"), # 内存中的大小
|
||||
"avg_obj_size": collection.get("avgObjSize"), # 对象平均大小
|
||||
"storage_size": collection.get("storageSize"), # 存储大小
|
||||
"capped": collection.get("capped"),
|
||||
"nindexes": collection.get("nindexes"), # 索引数
|
||||
"total_index_size": collection.get("totalIndexSize"), # 索引大小
|
||||
}
|
||||
result["collection_list"].append(data)
|
||||
|
||||
return mw.returnJson(True,'ok', result)
|
||||
|
||||
def testData():
|
||||
'''
|
||||
cd /www/server/mdserver-web && source bin/activate && python3 /www/server/mdserver-web/plugins/mongodb/index.py test_data
|
||||
@@ -788,8 +922,18 @@ if __name__ == "__main__":
|
||||
print(getDbList())
|
||||
elif func == 'add_db':
|
||||
print(addDb())
|
||||
elif func == 'del_db':
|
||||
print(delDb())
|
||||
elif func == 'set_root_pwd':
|
||||
print(setRootPwd())
|
||||
elif func == 'set_user_pwd':
|
||||
print(setUserPwd())
|
||||
elif func == 'sync_get_databases':
|
||||
print(syncGetDatabases())
|
||||
elif func == 'set_db_ps':
|
||||
print(setDbPs())
|
||||
elif func == 'get_db_info':
|
||||
print(getDbInfo())
|
||||
elif func == 'run_log':
|
||||
print(runLog())
|
||||
elif func == 'test':
|
||||
|
||||
+205
-23
@@ -26,6 +26,18 @@ function mgPost(method, version, args,callback){
|
||||
},'json');
|
||||
}
|
||||
|
||||
function mgAsyncPost(method,args){
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
return syncPost('/plugins/run', {name:'mongodb', func:method, args:_args});
|
||||
}
|
||||
|
||||
|
||||
function mongoStatus() {
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
@@ -38,7 +50,7 @@ function mongoStatus() {
|
||||
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var con = '<div class="divtable">\
|
||||
<table class="table table-hover table-bordered" style="width: 490px;">\
|
||||
<table class="table table-hover table-bordered" style="width: 660px;">\
|
||||
<thead><th>字段</th><th>当前值</th><th>说明</th></thead>\
|
||||
<tbody>\
|
||||
<tr><th>host</th><td>' + rdata.host + '</td><td>服务器</td></tr>\
|
||||
@@ -87,7 +99,7 @@ function mongoDocStatus() {
|
||||
// console.log(t);
|
||||
|
||||
var con = '<div class="divtable">\
|
||||
<table class="table table-hover table-bordered" style="width: 490px;">\
|
||||
<table class="table table-hover table-bordered" style="width: 660px;">\
|
||||
<thead><th>库名</th><th>大小</th><th>存储大小</th><th>数据</th><th>索引</th><th>文档数据</th><th>对象</th></thead>\
|
||||
<tbody>'+t+'<tbody>\
|
||||
</table></div>';
|
||||
@@ -121,7 +133,7 @@ function mongoReplStatus() {
|
||||
}
|
||||
|
||||
var con = '<div class="divtable">\
|
||||
<table class="table table-hover table-bordered" style="width: 490px;">\
|
||||
<table class="table table-hover table-bordered" style="width: 660px;">\
|
||||
<thead><th>字段</th><th>当前值</th><th>说明</th></thead>\
|
||||
<tbody>\
|
||||
'+tbody+'\
|
||||
@@ -222,27 +234,8 @@ function dbList(page, search){
|
||||
|
||||
list += '<a href="javascript:;" class="btlink" class="btlink" onclick="setBackup(\''+rdata.data[i]['name']+'\',this)" title="数据库备份">'+(rdata.data[i]['is_backup']?'备份':'未备份') +'</a> | ';
|
||||
|
||||
var rw = '';
|
||||
var rw_change = 'all';
|
||||
if (typeof(rdata.data[i]['rw'])!='undefined'){
|
||||
var rw_val = '读写';
|
||||
if (rdata.data[i]['rw'] == 'all'){
|
||||
rw_val = "所有";
|
||||
rw_change = 'rw';
|
||||
} else if (rdata.data[i]['rw'] == 'rw'){
|
||||
rw_val = "读写";
|
||||
rw_change = 'r';
|
||||
} else if (rdata.data[i]['rw'] == 'r'){
|
||||
rw_val = "只读";
|
||||
rw_change = 'all';
|
||||
}
|
||||
rw = '<a href="javascript:;" class="btlink" onclick="setDbRw(\''+rdata.data[i]['id']+'\',\''+rdata.data[i]['name']+'\',\''+rw_change+'\')" title="设置读写">'+rw_val+'</a> | ';
|
||||
}
|
||||
|
||||
|
||||
list += '<a href="javascript:;" class="btlink" onclick="repTools(\''+rdata.data[i]['name']+'\')" title="MySQL优化修复工具">工具</a> | ' +
|
||||
'<a href="javascript:;" class="btlink" onclick="setDbAccess(\''+rdata.data[i]['username']+'\')" title="设置数据库权限">权限</a> | ' +
|
||||
rw +
|
||||
'<a href="javascript:;" class="btlink" onclick="setDbPass('+rdata.data[i]['id']+',\''+ rdata.data[i]['username'] +'\',\'' + rdata.data[i]['password'] + '\')">改密</a> | ' +
|
||||
'<a href="javascript:;" class="btlink" onclick="delDb(\''+rdata.data[i]['id']+'\',\''+rdata.data[i]['name']+'\')" title="删除数据库">删除</a>' +
|
||||
'</td>';
|
||||
@@ -250,10 +243,10 @@ function dbList(page, search){
|
||||
}
|
||||
|
||||
//<button onclick="" id="dataRecycle" title="删除选中项" class="btn btn-default btn-sm" style="margin-left: 5px;"><span class="glyphicon glyphicon-trash" style="margin-right: 5px;"></span>回收站</button>
|
||||
// <button onclick="setDbAccess(\'root\')" title="ROOT权限" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">ROOT权限</button>\
|
||||
var con = '<div class="safe bgw">\
|
||||
<button onclick="addDatabase()" title="添加数据库" class="btn btn-success btn-sm" type="button" style="margin-right: 5px;">添加数据库</button>\
|
||||
<button onclick="setRootPwd(0,\''+rdata.info['root_pwd']+'\')" title="设置Mongodb管理员密码" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">root密码</button>\
|
||||
<button onclick="setDbAccess(\'root\')" title="ROOT权限" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">ROOT权限</button>\
|
||||
<span style="float:right"> \
|
||||
<button batch="true" style="float: right;display: none;margin-left:10px;" onclick="delDbBatch();" title="删除选中项" class="btn btn-default btn-sm">删除选中</button>\
|
||||
</span>\
|
||||
@@ -418,3 +411,192 @@ function setRootPwd(type, pwd){
|
||||
});
|
||||
}
|
||||
|
||||
function syncGetDatabase(){
|
||||
mgPost('sync_get_databases', '', '', function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
dbList();
|
||||
},{ icon: rdata.status ? 1 : 2 });
|
||||
});
|
||||
}
|
||||
|
||||
function showHidePass(obj){
|
||||
var a = "glyphicon-eye-open";
|
||||
var b = "glyphicon-eye-close";
|
||||
|
||||
if($(obj).hasClass(a)){
|
||||
$(obj).removeClass(a).addClass(b);
|
||||
$(obj).prev().text($(obj).prev().attr('data-pw'))
|
||||
}
|
||||
else{
|
||||
$(obj).removeClass(b).addClass(a);
|
||||
$(obj).prev().text('***');
|
||||
}
|
||||
}
|
||||
|
||||
function setDbPs(id, name, obj) {
|
||||
var _span = $(obj);
|
||||
var _input = $("<input class='baktext' value=\""+_span.text()+"\" type='text' placeholder='备注信息' />");
|
||||
_span.hide().after(_input);
|
||||
_input.focus();
|
||||
_input.blur(function(){
|
||||
$(this).remove();
|
||||
var ps = _input.val();
|
||||
_span.text(ps).show();
|
||||
var data = {name:name,id:id,ps:ps};
|
||||
mgPost('set_db_ps', '',data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
});
|
||||
});
|
||||
_input.keyup(function(){
|
||||
if(event.keyCode == 13){
|
||||
_input.trigger('blur');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function delDb(id, name){
|
||||
safeMessage('删除['+name+']','您真的要删除['+name+']吗?',function(){
|
||||
var data='id='+id+'&name='+name;
|
||||
mgPost('del_db', '', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
dbList();
|
||||
},{icon: rdata.status ? 1 : 2}, 600);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function delDbBatch(){
|
||||
var arr = [];
|
||||
$('input[type="checkbox"].check:checked').each(function () {
|
||||
var _val = $(this).val();
|
||||
var _name = $(this).parent().next().text();
|
||||
if (!isNaN(_val)) {
|
||||
arr.push({'id':_val,'name':_name});
|
||||
}
|
||||
});
|
||||
|
||||
safeMessage('批量删除数据库','<a style="color:red;">您共选择了[2]个数据库,删除后将无法恢复,真的要删除吗?</a>',function(){
|
||||
var i = 0;
|
||||
$(arr).each(function(){
|
||||
var data = mgAsyncPost('del_db', this);
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if (!rdata.status){
|
||||
layer.msg(rdata.msg,{icon:2,time:2000,shade: [0.3, '#000']});
|
||||
}
|
||||
i++;
|
||||
});
|
||||
|
||||
var msg = '成功删除['+i+']个数据库!';
|
||||
showMsg(msg,function(){
|
||||
dbList();
|
||||
},{icon: 1}, 600);
|
||||
});
|
||||
}
|
||||
|
||||
function setDbPass(id, username, password){
|
||||
layer.open({
|
||||
type: 1,
|
||||
area: '500px',
|
||||
title: '修改数据库密码',
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
shadeClose: true,
|
||||
btn:["提交","关闭"],
|
||||
content: "<form class='bt-form pd20' id='mod_pwd'>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>用户名</span>\
|
||||
<div class='info-r'><input readonly='readonly' name=\"name\" class='bt-input-text mr5' type='text' style='width:330px;outline:none;' value='"+username+"' /></div>\
|
||||
</div>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>密码</span>\
|
||||
<div class='info-r'>\
|
||||
<input class='bt-input-text mr5' type='text' name='password' id='MyPassword' style='width:330px' value='"+password+"' />\
|
||||
<span title='随机密码' class='glyphicon glyphicon-repeat cursor' onclick='repeatPwd(16)'></span></div>\
|
||||
</div>\
|
||||
<input type='hidden' name='id' value='"+id+"'>\
|
||||
</form>",
|
||||
yes:function(index){
|
||||
// var data = $("#mod_pwd").serialize();
|
||||
var data = {};
|
||||
data['name'] = $('input[name=name]').val();
|
||||
data['password'] = $('#MyPassword').val();
|
||||
data['id'] = $('input[name=id]').val();
|
||||
mgPost('set_user_pwd', '',data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
layer.close(index);
|
||||
dbList();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function repTools(db_name, res){
|
||||
mgPost('get_db_info', '', {name:db_name}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var rdata = rdata.data;
|
||||
|
||||
console.log(rdata.collection_list);
|
||||
var tbody = '';
|
||||
for (var i = 0; i < rdata.collection_list.length; i++) {
|
||||
tbody += '<tr>\
|
||||
<td><span style="width:220px;"> ' + rdata.collection_list[i].collection_name + '</span></td>\
|
||||
<td><span style="width:220px;"> ' + rdata.collection_list[i].count + '</span></td>\
|
||||
<td>' + toSize(rdata.collection_list[i].size) + '</td>\
|
||||
<td><span style="width:90px;"> ' + toSize(rdata.collection_list[i].avg_obj_size) + '</span></td>\
|
||||
<td>' + toSize(rdata.collection_list[i].storage_size) + '</td>\
|
||||
<td>' + rdata.collection_list[i].nindexes + '</td>\
|
||||
<td>' + toSize(rdata.collection_list[i].total_index_size) + '</td>\
|
||||
</tr> '
|
||||
}
|
||||
|
||||
if (res) {
|
||||
$(".gztr").html(tbody);
|
||||
$("#db_tools").html('');
|
||||
$("input[type='checkbox']").attr("checked", false);
|
||||
$(".tools_size").html('大小:' + rdata.data_size);
|
||||
return;
|
||||
}
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: "MongoDB工具箱【" + db_name + "】",
|
||||
area: ['780px', '480px'],
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
content: '<div class="pd15">\
|
||||
<div class="db_list">\
|
||||
<span><a>数据库名称:'+ db_name + '</a>\
|
||||
<a>集合:'+ rdata.collections + '</a>\
|
||||
<a class="tools_size">存储大小:'+ toSize(rdata.storageSize) + '</a>\
|
||||
<a class="tools_size">索引大小:'+ toSize(rdata.indexSize) + '</a>\
|
||||
</span>\
|
||||
<span id="db_tools" style="float: right;"></span>\
|
||||
</div >\
|
||||
<div class="divtable">\
|
||||
<div id="database_fix" style="height:360px;overflow:auto;border:#ddd 1px solid">\
|
||||
<table class="table table-hover "style="border:none">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th>集合名称</th>\
|
||||
<th>文档数量</th>\
|
||||
<th>内存中的大小</th>\
|
||||
<th>对象平均大小</th>\
|
||||
<th>存储大小</th>\
|
||||
<th>索引数量</th>\
|
||||
<th>索引大小</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody class="gztr">' + tbody + '</tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>'
|
||||
});
|
||||
tableFixed('database_fix');
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user