Initial YakPanel commit
This commit is contained in:
0
class/databaseModel/__init__.py
Normal file
0
class/databaseModel/__init__.py
Normal file
461
class/databaseModel/base.py
Normal file
461
class/databaseModel/base.py
Normal file
@@ -0,0 +1,461 @@
|
||||
#coding: utf-8
|
||||
import os,sys,time,json
|
||||
panelPath = '/www/server/panel'
|
||||
os.chdir(panelPath)
|
||||
if not panelPath + "/class/" in sys.path:
|
||||
sys.path.insert(0, panelPath + "/class/")
|
||||
import public,re
|
||||
|
||||
class databaseBase:
|
||||
|
||||
|
||||
|
||||
def get_base_list(self,args,sql_type = 'mysql'):
|
||||
"""
|
||||
@获取数据库列表
|
||||
@type:数据库类型,MySQL,SQLServer
|
||||
"""
|
||||
|
||||
search = ''
|
||||
if 'search' in args: search = args['search']
|
||||
|
||||
SQL = public.M('databases');
|
||||
|
||||
where = "lower(type) = lower('{}')".format(sql_type)
|
||||
if search:
|
||||
where += "AND (name like '%{search}%' or ps like '%{search}%')".format(search = search)
|
||||
|
||||
if 'db_type' in args:
|
||||
where += " AND db_type='{}'".format(args['db_type'])
|
||||
|
||||
if 'sid' in args:
|
||||
where += " AND sid='{}'".format(args['sid'])
|
||||
|
||||
order = "id desc"
|
||||
if hasattr(args,'order'): order = args.order
|
||||
|
||||
info = {}
|
||||
rdata = {}
|
||||
|
||||
info['p'] = 1
|
||||
info['row'] = 20
|
||||
result = '1,2,3,4,5,8'
|
||||
info['count'] = SQL.where(where,()).count();
|
||||
|
||||
if hasattr(args,'limit'): info['row'] = int(args.limit)
|
||||
if hasattr(args,'result'): result = args.result;
|
||||
if hasattr(args,'p'): info['p'] = int(args['p'])
|
||||
|
||||
import page
|
||||
#实例化分页类
|
||||
page = page.Page();
|
||||
|
||||
info['uri'] = args
|
||||
info['return_js'] = ''
|
||||
if hasattr(args,'tojs'): info['return_js'] = args.tojs
|
||||
|
||||
rdata['where'] = where;
|
||||
|
||||
#获取分页数据
|
||||
rdata['page'] = page.GetPage(info,result)
|
||||
#取出数据
|
||||
rdata['data'] = SQL.where(where,()).order(order).field('id,sid,pid,name,username,password,accept,ps,addtime,type,db_type,conn_config').limit(str(page.SHIFT)+','+str(page.ROW)).select()
|
||||
|
||||
for sdata in rdata['data']:
|
||||
|
||||
sdata['backup_count'] = public.M('backup').where("pid=? AND type=1",(sdata['id'])).count()
|
||||
|
||||
sdata['conn_config'] = json.loads(sdata['conn_config'])
|
||||
return rdata;
|
||||
|
||||
|
||||
def get_databaseModel(self):
|
||||
'''
|
||||
获取数据库模型对象
|
||||
@db_type 数据库类型
|
||||
'''
|
||||
from panelDatabaseController import DatabaseController
|
||||
project_obj = DatabaseController()
|
||||
|
||||
return project_obj
|
||||
|
||||
|
||||
def get_average_num(self,slist):
|
||||
"""
|
||||
@批量删除获取平均值
|
||||
"""
|
||||
count = len(slist)
|
||||
limit_size = 1 * 1024 * 1024
|
||||
if count <= 0: return limit_size
|
||||
|
||||
if len(slist) > 1:
|
||||
slist = sorted(slist)
|
||||
limit_size =int((slist[0] + slist[-1])/2 * 0.85)
|
||||
return limit_size
|
||||
|
||||
def get_database_size(self,ids,is_pid = False):
|
||||
"""
|
||||
获取数据库大小
|
||||
"""
|
||||
result = {}
|
||||
p = self.get_databaseModel()
|
||||
for id in ids:
|
||||
if not is_pid:
|
||||
x = public.M('databases').where('id=?',id).field('id,sid,pid,name,type,ps,addtime').find()
|
||||
else:
|
||||
x = public.M('databases').where('pid=?',id).field('id,sid,pid,name,type,ps,addtime').find()
|
||||
if not x: continue
|
||||
x['backup_count'] = public.M('backup').where("pid=? AND type=?",(x['id'],'1')).count()
|
||||
if x['type'] == 'MySQL':
|
||||
x['total'] = int(public.get_database_size_by_id(id))
|
||||
else:
|
||||
try:
|
||||
|
||||
get = public.dict_obj()
|
||||
get['data'] = {'db_id': x['id'] }
|
||||
get['mod_name'] = x['type'].lower()
|
||||
get['def_name'] = 'get_database_size_by_id'
|
||||
|
||||
x['total'] = p.model(get)
|
||||
except :
|
||||
x['total'] = 0
|
||||
result[x['name']] = x
|
||||
return result
|
||||
|
||||
def check_base_del_data(self,get):
|
||||
"""
|
||||
@删除数据库前置检测
|
||||
"""
|
||||
ids = json.loads(get.ids)
|
||||
slist = {};result = [];db_list_size = []
|
||||
db_data = self.get_database_size(ids)
|
||||
|
||||
for key in db_data:
|
||||
data = db_data[key]
|
||||
if not data['id'] in ids: continue
|
||||
|
||||
db_addtime = public.to_date(times = data['addtime'])
|
||||
data['score'] = int(time.time() - db_addtime) + data['total']
|
||||
data['st_time'] = db_addtime
|
||||
|
||||
if data['total'] > 0 : db_list_size.append(data['total'])
|
||||
result.append(data)
|
||||
|
||||
slist['data'] = sorted(result,key= lambda x:x['score'],reverse=True)
|
||||
slist['db_size'] = self.get_average_num(db_list_size)
|
||||
return slist
|
||||
|
||||
def get_test(self,args):
|
||||
|
||||
|
||||
p = self.get_databaseModel()
|
||||
get = public.dict_obj()
|
||||
get['data'] = {'db_id': 18 }
|
||||
get['mod_name'] = args['type'].lower()
|
||||
get['def_name'] = 'get_database_size_by_id'
|
||||
|
||||
return p.model(get)
|
||||
|
||||
def add_base_database(self,get):
|
||||
"""
|
||||
@添加数据库前置检测
|
||||
@return username 用户名
|
||||
data_name 数据库名
|
||||
data_pwd:数据库密码
|
||||
"""
|
||||
data_name = get['name'].strip().lower()
|
||||
if self.check_recyclebin(data_name):
|
||||
return public.returnMsg(False, public.lang("Database ['+data_name+'] is already in recycle bin, please restore from recycle bin!"));
|
||||
|
||||
if len(data_name) > 16:
|
||||
return public.returnMsg(False, public.lang("Database name cannot be more than 16 characters!"))
|
||||
|
||||
if not hasattr(get,'db_user'): get.db_user = data_name;
|
||||
username = get.db_user.strip();
|
||||
checks = ['root','mysql','test','sys','panel_logs']
|
||||
if username in checks or len(username) < 1:
|
||||
return public.returnMsg(False, public.lang("Database username is invalid!"));
|
||||
if data_name in checks or len(data_name) < 1:
|
||||
return public.returnMsg(False, public.lang("Database name is invalid!"));
|
||||
|
||||
reg = r"^\w+$"
|
||||
if not re.match(reg, data_name):
|
||||
return public.returnMsg(False, public.lang("Database name cannot contain special characters!"))
|
||||
|
||||
data_pwd = get['password']
|
||||
if len(data_pwd) < 1:
|
||||
data_pwd = public.md5(str(time.time()))[0:8]
|
||||
|
||||
if public.M('databases').where("name=? or username=?",(data_name,username)).count():
|
||||
return public.returnMsg(False, public.lang("Database exists!"))
|
||||
|
||||
res = {
|
||||
'data_name':data_name,
|
||||
'username':username,
|
||||
'data_pwd':data_pwd,
|
||||
'status':True
|
||||
}
|
||||
return res
|
||||
|
||||
|
||||
def delete_base_backup(self,get):
|
||||
"""
|
||||
@删除备份文件
|
||||
"""
|
||||
|
||||
name = ''
|
||||
id = get.id
|
||||
where = "id=?"
|
||||
filename = public.M('backup').where(where,(id,)).getField('filename')
|
||||
if os.path.exists(filename): os.remove(filename)
|
||||
|
||||
if filename == 'qiniu':
|
||||
name = public.M('backup').where(where,(id,)).getField('name');
|
||||
|
||||
public.ExecShell(public.get_run_python("[PYTHON] "+public.GetConfigValue('setup_path') + '/panel/script/backup_qiniu.py delete_file ' + name))
|
||||
public.M('backup').where(where,(id,)).delete()
|
||||
public.WriteLog("TYPE_DATABASE", 'DATABASE_BACKUP_DEL_SUCCESS',(name,filename))
|
||||
return public.returnMsg(True, public.lang("Delete successfully!"));
|
||||
|
||||
#检查是否在回收站
|
||||
def check_recyclebin(self,name):
|
||||
try:
|
||||
for n in os.listdir('{}/Recycle_bin'.format(public.get_soft_path())):
|
||||
if n.find('BTDB_'+name+'_t_') != -1: return True;
|
||||
return False;
|
||||
except:
|
||||
return False;
|
||||
|
||||
#map to list
|
||||
def map_to_list(self,map_obj):
|
||||
try:
|
||||
if type(map_obj) != list and type(map_obj) != str: map_obj = list(map_obj)
|
||||
return map_obj
|
||||
except: return []
|
||||
#******************************************** 远程数据库 ******************************************/
|
||||
|
||||
def check_cloud_args(self,get,nlist = []):
|
||||
"""
|
||||
验证参数是否合法
|
||||
@get param
|
||||
@args 参数列表
|
||||
"""
|
||||
for key in nlist:
|
||||
if not key in get:
|
||||
return public.returnMsg(False, public.lang("Parameter passing error, missing parameter {}!",key))
|
||||
return public.returnMsg(True, public.lang("Pass!"))
|
||||
|
||||
def check_cloud_database(self,args):
|
||||
'''
|
||||
@检查远程数据库是否存在
|
||||
@conn_config param
|
||||
'''
|
||||
p = self.get_databaseModel()
|
||||
|
||||
get = public.dict_obj()
|
||||
get['data'] = args
|
||||
get['mod_name'] = args['type']
|
||||
get['def_name'] = 'check_cloud_database_status'
|
||||
return p.model(get)
|
||||
|
||||
def AddBaseCloudServer(self,get):
|
||||
"""
|
||||
@name 添加远程服务器
|
||||
@author hwliang<2021-01-10>
|
||||
@param db_host<string> 服务器地址
|
||||
@param db_port<port> 数据库端口
|
||||
@param db_user<string> 用户名
|
||||
@param db_password<string> 数据库密码
|
||||
@param db_ps<string> 数据库备注
|
||||
@param type<string> 数据库类型,mysql/sqlserver/sqlite
|
||||
@return dict
|
||||
"""
|
||||
|
||||
arrs = ['db_host','db_port','db_user','db_password','db_ps','type']
|
||||
if get.type == 'redis': arrs = ['db_host','db_port','db_password','db_ps','type']
|
||||
|
||||
cRet = self.check_cloud_args(get,arrs)
|
||||
if not cRet['status']: return str(cRet)
|
||||
|
||||
get['db_name'] = None
|
||||
res = self.check_cloud_database(get)
|
||||
if isinstance(res,dict): return str(res)
|
||||
|
||||
if public.M('database_servers').where('db_host=? AND db_port=?',(get['db_host'],get['db_port'])).count():
|
||||
return public.returnMsg(False, public.lang("The specified server already exists: [{}:{}]",get['db_host'],get['db_port']))
|
||||
get['db_port'] = int(get['db_port'])
|
||||
pdata = {
|
||||
'db_host':get['db_host'],
|
||||
'db_port':int(get['db_port']),
|
||||
'db_user':get['db_user'],
|
||||
'db_password':get['db_password'],
|
||||
'db_type':get['type'],
|
||||
'ps': public.xssencode2(get['db_ps'].strip()),
|
||||
'addtime': int(time.time())
|
||||
}
|
||||
result = public.M("database_servers").insert(pdata)
|
||||
|
||||
if isinstance(result,int):
|
||||
public.WriteLog('Database manager','Add remote MySQL server[{}:{}]'.format(get['db_host'],get['db_port']))
|
||||
return public.returnMsg(True, public.lang("Added successfully!"))
|
||||
return public.returnMsg(False, public.lang("Add failed: {}",result))
|
||||
|
||||
|
||||
def GetBaseCloudServer(self,get):
|
||||
'''
|
||||
@name 获取远程服务器列表
|
||||
@author hwliang<2021-01-10>
|
||||
@return list
|
||||
'''
|
||||
where = '1=1'
|
||||
if 'type' in get:where = "db_type = '{}'".format(get['type'])
|
||||
|
||||
data = public.M('database_servers').where(where,()).select()
|
||||
|
||||
if not isinstance(data,list): data = []
|
||||
|
||||
if get['type'] == 'mysql':
|
||||
bt_mysql_bin = public.get_mysql_info()['path'] + '/bin/mysql.exe'
|
||||
if os.path.exists(bt_mysql_bin):
|
||||
data.insert(0,{'id':0,'db_host':'127.0.0.1','db_port':3306,'db_user':'root','db_password':'','ps':'local server','addtime':0,'db_type':'mysql'})
|
||||
elif get['type'] == 'sqlserver':
|
||||
pass
|
||||
elif get['type'] == 'mongodb':
|
||||
if os.path.exists('/www/server/mongodb/bin'):
|
||||
data.insert(0,{'id':0,'db_host':'127.0.0.1','db_port':27017,'db_user':'root','db_password':'','ps':'local server','addtime':0,'db_type':'mongodb'})
|
||||
elif get['type'] == 'redis':
|
||||
if os.path.exists('/www/server/redis'):
|
||||
data.insert(0,{'id':0,'db_host':'127.0.0.1','db_port':6379,'db_user':'root','db_password':'','ps':'local server','addtime':0,'db_type':'redis'})
|
||||
elif get['type'] == 'pgsql':
|
||||
if os.path.exists('/www/server/pgsql'):
|
||||
data.insert(0,{'id':0,'db_host':'127.0.0.1','db_port':5432,'db_user':'postgres','db_password':'','ps':'local server','addtime':0,'db_type':'pgsql'})
|
||||
return data
|
||||
|
||||
def RemoveBaseCloudServer(self,get):
|
||||
'''
|
||||
@name 删除远程服务器
|
||||
@author hwliang<2021-01-10>
|
||||
@param id<int> 远程服务器ID
|
||||
@return dict
|
||||
'''
|
||||
|
||||
id = int(get.id)
|
||||
if not id: return public.returnMsg(False, public.lang("Parameter passed error, please try again!"))
|
||||
db_find = public.M('database_servers').where('id=?',(id,)).find()
|
||||
if not db_find: return public.returnMsg(False, public.lang("The specified remote server does not exist!"))
|
||||
public.M('databases').where('sid=?',id).delete()
|
||||
result = public.M('database_servers').where('id=?',id).delete()
|
||||
if isinstance(result,int):
|
||||
public.WriteLog('Database manager','Delete remote MySQL server [{}:{}]'.format(db_find['db_host'],int(db_find['db_port'])))
|
||||
return public.returnMsg(True, public.lang("Successfully deleted!"))
|
||||
return public.returnMsg(False, public.lang("Successfully deleted: {}",result))
|
||||
|
||||
|
||||
def ModifyBaseCloudServer(self,get):
|
||||
'''
|
||||
@name 修改远程服务器
|
||||
@author hwliang<2021-01-10>
|
||||
@param id<int> 远程服务器ID
|
||||
@param db_host<string> 服务器地址
|
||||
@param db_port<port> 数据库端口
|
||||
@param db_user<string> 用户名
|
||||
@param db_password<string> 数据库密码
|
||||
@param db_ps<string> 数据库备注
|
||||
@return dict
|
||||
'''
|
||||
|
||||
arrs = ['db_host','db_port','db_user','db_password','db_ps','type']
|
||||
if get.type == 'redis': arrs = ['db_host','db_port','db_password','db_ps','type']
|
||||
|
||||
cRet = self.check_cloud_args(get,arrs)
|
||||
if not cRet['status']: return cRet
|
||||
|
||||
id = int(get.id)
|
||||
get['db_port'] = int(get['db_port'])
|
||||
db_find = public.M('database_servers').where('id=?',(id,)).find()
|
||||
if not db_find: return public.returnMsg(False, public.lang("The specified remote server does not exist!"))
|
||||
_modify = False
|
||||
if db_find['db_host'] != get['db_host'] or db_find['db_port'] != get['db_port']:
|
||||
_modify = True
|
||||
if public.M('database_servers').where('db_host=? AND db_port=?',(get['db_host'],get['db_port'])).count():
|
||||
return public.returnMsg(False, public.lang("The specified server already exists: [{}:{}]",get['db_host'],get['db_port']))
|
||||
|
||||
if db_find['db_user'] != get['db_user'] or db_find['db_password'] != get['db_password']:
|
||||
_modify = True
|
||||
_modify = True
|
||||
if _modify:
|
||||
|
||||
res = self.check_cloud_database(get)
|
||||
if isinstance(res,dict): return res
|
||||
|
||||
pdata = {
|
||||
'db_host':get['db_host'],
|
||||
'db_port':int(get['db_port']),
|
||||
'db_user':get['db_user'],
|
||||
'db_password':get['db_password'],
|
||||
'db_type':get['type'],
|
||||
'ps': public.xssencode2(get['db_ps'].strip())
|
||||
}
|
||||
|
||||
result = public.M("database_servers").where('id=?',(id,)).update(pdata)
|
||||
if isinstance(result,int):
|
||||
public.WriteLog('Database manager','Modify the remote MySQL server[{}:{}]'.format(get['db_host'],get['db_port']))
|
||||
return public.returnMsg(True, public.lang("Successfully modified!"))
|
||||
return public.returnMsg(False, public.lang("Fail to edit: {}",result))
|
||||
|
||||
|
||||
#检测数据库执行错误
|
||||
def IsSqlError(self,mysqlMsg):
|
||||
if mysqlMsg:
|
||||
mysqlMsg = str(mysqlMsg)
|
||||
if "MySQLdb" in mysqlMsg: return public.returnMsg(False, public.lang("MySQLdb component is missing!"))
|
||||
if "2002," in mysqlMsg: return public.returnMsg(False, public.lang("ERROR to connect database"))
|
||||
if "2003," in mysqlMsg: return public.returnMsg(False, public.lang("Database connection timed out, please check if the configuration is correct."))
|
||||
if "1045," in mysqlMsg: return public.returnMsg(False, public.lang("MySQL password error."))
|
||||
if "1040," in mysqlMsg: return public.returnMsg(False, public.lang("Exceeded maximum number of connections, please try again later."))
|
||||
if "1130," in mysqlMsg: return public.returnMsg(False, public.lang("Database connection failed, please check whether the root user is authorized to access 127.0.0.1."))
|
||||
if "using password:" in mysqlMsg: return public.returnMsg(False, public.lang("Database password is incorrect!"))
|
||||
if "Connection refused" in mysqlMsg: return public.returnMsg(False, public.lang("ERROR to connect database"))
|
||||
if "1133" in mysqlMsg: return public.returnMsg(False, public.lang("Database user does NOT exist!"))
|
||||
if "2005_login_error" == mysqlMsg: return public.returnMsg(False, public.lang("The connection times out, please manually enable the TCP/IP function (Start Menu->SQL 2005->Configuration Tools->2005 Network Configuration->TCP/IP->Enable)"))
|
||||
if 'already exists' in mysqlMsg: return public.returnMsg(False, public.lang("The specified database already exists, please do not add it repeatedly."))
|
||||
if 'Cannot open backup device' in mysqlMsg: return public.returnMsg(False, public.lang("The operation failed, the remote database does not support the operation."))
|
||||
|
||||
if '1142' in mysqlMsg: return public.returnMsg(False, public.lang("Insufficient permissions, please use root user."))
|
||||
|
||||
if "DB-Lib error message 20018" in mysqlMsg: return public.returnMsg(False, public.lang("Create failed, SQL Server requires GUI support"))
|
||||
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
#******************************************** 数据库公用方法 ******************************************/
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
#get = {}
|
||||
#get['db_host'] = '192.168.1.37'
|
||||
#get['db_port'] = '3306'
|
||||
#get['db_user'] = 'root'
|
||||
|
||||
#get['db_password'] = 'HLANEMJFRbPE7Ny2'
|
||||
#get['db_ps'] = '2'
|
||||
#get['type'] = 'mysql'
|
||||
#bt = databaseBase()
|
||||
#ret = bt.AddCloudServer(get)
|
||||
#print(ret)
|
||||
|
||||
get = {}
|
||||
get['db_host'] = '192.168.66.73'
|
||||
get['db_port'] = '1433'
|
||||
get['db_user'] = 'sa'
|
||||
|
||||
get['db_password'] = 'dPYi6Gt8GC7SL58C'
|
||||
get['db_ps'] = '2'
|
||||
get['type'] = 'sqlserver'
|
||||
bt = databaseBase()
|
||||
ret = bt.get_test(get)
|
||||
print(ret)
|
||||
|
||||
777
class/databaseModel/mongodbModel.py
Normal file
777
class/databaseModel/mongodbModel.py
Normal file
@@ -0,0 +1,777 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# YakPanel
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 YakPanel(www.yakpanel.com) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: hwliang <hwl@yakpanel.com>
|
||||
#-------------------------------------------------------------------
|
||||
#角色说明:
|
||||
#read:允许用户读取指定数据库
|
||||
#readWrite:允许用户读写指定数据库
|
||||
#dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
|
||||
#userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
|
||||
#clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
|
||||
#readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
|
||||
#readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
|
||||
#userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
|
||||
#dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
|
||||
#root:只在admin数据库中可用。超级账号,超级权限
|
||||
|
||||
# sqlite模型
|
||||
#------------------------------
|
||||
import os,re,json,time
|
||||
from databaseModel.base import databaseBase
|
||||
import public
|
||||
try:
|
||||
import pymongo
|
||||
except:
|
||||
public.ExecShell("btpip install pymongo")
|
||||
import pymongo
|
||||
try:
|
||||
from YakPanel import session
|
||||
except :pass
|
||||
|
||||
|
||||
class panelMongoDB():
|
||||
|
||||
__DB_PASS = None
|
||||
__DB_USER = None
|
||||
__DB_PORT = 27017
|
||||
__DB_HOST = '127.0.0.1'
|
||||
__DB_CONN = None
|
||||
__DB_ERR = None
|
||||
|
||||
__DB_CLOUD = None
|
||||
def __init__(self):
|
||||
self.__config = self.get_options(None)
|
||||
|
||||
def __Conn(self,auth):
|
||||
|
||||
if not self.__DB_CLOUD:
|
||||
path = '{}/data/mongo.root'.format(public.get_panel_path())
|
||||
if os.path.exists(path): self.__DB_PASS = public.readFile(path)
|
||||
self.__DB_PORT = int(self.__config['port'])
|
||||
|
||||
try:
|
||||
if not self.__DB_USER and auth:
|
||||
self.__DB_USER = "root"
|
||||
self.__DB_CONN = pymongo.MongoClient(host=self.__DB_HOST, port=self.__DB_PORT, username = self.__DB_USER, password=self.__DB_PASS)
|
||||
self.__DB_CONN.admin.command({"listDatabases":1})
|
||||
return True
|
||||
except :
|
||||
try:
|
||||
self.__DB_CONN = pymongo.MongoClient(host=self.__DB_HOST, port=self.__DB_PORT, username = self.__DB_USER, password=self.__DB_PASS)
|
||||
self.__DB_CONN.admin.authenticate('root', self.__DB_PASS)
|
||||
return True
|
||||
except :
|
||||
self.__DB_ERR = public.get_error_info()
|
||||
return False
|
||||
|
||||
|
||||
def get_db_obj(self,db_name = 'admin',auth=0):
|
||||
"""
|
||||
@获取连接对象
|
||||
"""
|
||||
if not self.__Conn(auth): return self.__DB_ERR
|
||||
|
||||
return self.__DB_CONN[db_name]
|
||||
|
||||
def set_host(self,host,port,name,username,password,prefix = ''):
|
||||
self.__DB_HOST = host
|
||||
self.__DB_PORT = int(port)
|
||||
self.__DB_NAME = name
|
||||
if self.__DB_NAME: self.__DB_NAME = str(self.__DB_NAME)
|
||||
self.__DB_USER = str(username)
|
||||
self._USER = str(username)
|
||||
self.__DB_PASS = str(password)
|
||||
self.__DB_PREFIX = prefix
|
||||
self.__DB_CLOUD = 1
|
||||
return self
|
||||
|
||||
|
||||
|
||||
#获取配置文件
|
||||
def get_config(self,get):
|
||||
filename = '{}/mongodb/config.conf'.format(public.get_setup_path())
|
||||
if os.path.exists(filename):
|
||||
return public.readFile(filename);
|
||||
return ""
|
||||
|
||||
#获取配置项
|
||||
def get_options(self,get):
|
||||
options = ['port','bind_ip','logpath','dbpath','authorization']
|
||||
data = {}
|
||||
conf = self.get_config(None)
|
||||
|
||||
for opt in options:
|
||||
tmp = re.findall(opt + r":\s+(.+)",conf)
|
||||
if not tmp: continue;
|
||||
data[opt] = tmp[0]
|
||||
|
||||
if not 'authorization' in data:data['authorization'] = "disabled"
|
||||
|
||||
# public.writeFile('/www/server/1.txt',json.dumps(data))
|
||||
return data
|
||||
|
||||
|
||||
class main(databaseBase):
|
||||
|
||||
__conf_path = '{}/mongodb/config.conf'.format(public.get_setup_path())
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
||||
def get_list(self,args):
|
||||
"""
|
||||
@获取数据库列表
|
||||
@sql_type = sqlserver
|
||||
"""
|
||||
return self.get_base_list(args, sql_type = 'mongodb')
|
||||
|
||||
def GetCloudServer(self,args):
|
||||
'''
|
||||
@name 获取远程服务器列表
|
||||
@author hwliang<2021-01-10>
|
||||
@return list
|
||||
'''
|
||||
return self.GetBaseCloudServer(args)
|
||||
|
||||
|
||||
def AddCloudServer(self,args):
|
||||
'''
|
||||
@添加远程数据库
|
||||
'''
|
||||
return self.AddBaseCloudServer(args)
|
||||
|
||||
def RemoveCloudServer(self,args):
|
||||
'''
|
||||
@删除远程数据库
|
||||
'''
|
||||
return self.RemoveBaseCloudServer(args)
|
||||
|
||||
def ModifyCloudServer(self,args):
|
||||
'''
|
||||
@修改远程数据库
|
||||
'''
|
||||
return self.ModifyBaseCloudServer(args)
|
||||
|
||||
#获取数据库列表
|
||||
def exists_databases(self,get):
|
||||
db_name = get
|
||||
if type(get) != str:db_name = get['db_name']
|
||||
auth_status = self.get_local_auth(get)
|
||||
db_obj = self.get_obj_by_sid(self.sid).get_db_obj('admin',auth=auth_status)
|
||||
data = db_obj.command({"listDatabases":1})
|
||||
if 'databases' in data:
|
||||
for x in data['databases']:
|
||||
if x['name'] == db_name:
|
||||
return True
|
||||
return False
|
||||
|
||||
def __set_auth_open(self,status):
|
||||
"""
|
||||
@设置数据库密码访问开关
|
||||
@状态 status:1 开启,2:关闭
|
||||
"""
|
||||
|
||||
conf = public.readFile(self.__conf_path)
|
||||
if status:
|
||||
conf = re.sub(r'authorization\s*\:\s*disabled','authorization: enabled',conf)
|
||||
else:
|
||||
conf = re.sub(r'authorization\s*\:\s*enabled','authorization: disabled',conf)
|
||||
|
||||
public.writeFile(self.__conf_path,conf)
|
||||
self.restart_services()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def set_auth_status(self,get):
|
||||
"""
|
||||
@设置密码认证状态
|
||||
@status int 0:关闭,1:开启
|
||||
"""
|
||||
|
||||
if not public.process_exists("mongod") :
|
||||
return public.returnMsg(False, public.lang("Mongodb service has not been started yet!"))
|
||||
|
||||
status = int(get.status)
|
||||
path = '{}/data/mongo.root'.format(public.get_panel_path())
|
||||
if status:
|
||||
if hasattr(get,'password'):
|
||||
password = get['password'].strip()
|
||||
if not password or not re.search(r"^[\w@\.]+$", password):
|
||||
return public.return_msg_gettext(False, public.lang("Database password cannot be empty or have special characters!"))
|
||||
|
||||
# if re.search('[\u4e00-\u9fa5]',password):
|
||||
# return public.returnMsg(False, public.lang("Database password cannot be Chinese, please change the name!"))
|
||||
else:
|
||||
password = public.GetRandomString(16)
|
||||
self.__set_auth_open(0)
|
||||
|
||||
_client = panelMongoDB().get_db_obj('admin')
|
||||
try:
|
||||
_client.command("dropUser", "root")
|
||||
except : pass
|
||||
|
||||
_client.command("createUser", "root", pwd=password, roles=[
|
||||
{'role':'root','db':'admin'},
|
||||
{'role':'clusterAdmin','db':'admin'},
|
||||
{'role':'readAnyDatabase','db':'admin'},
|
||||
{'role':'readWriteAnyDatabase','db':'admin'},
|
||||
{'role':'userAdminAnyDatabase','db':'admin'},
|
||||
{'role':'dbAdminAnyDatabase','db':'admin'},
|
||||
{'role':'userAdmin','db':'admin'},
|
||||
{'role':'dbAdmin','db':'admin'}
|
||||
])
|
||||
|
||||
self.__set_auth_open(1)
|
||||
|
||||
public.writeFile(path,password)
|
||||
else:
|
||||
if os.path.exists(path): os.remove(path)
|
||||
self.__set_auth_open(0)
|
||||
|
||||
return public.return_msg_gettext(True, public.lang("Setup successfully!"))
|
||||
|
||||
def restart_services(self):
|
||||
"""
|
||||
@重启服务
|
||||
"""
|
||||
public.ExecShell('/etc/init.d/mongodb restart')
|
||||
return True
|
||||
|
||||
def get_obj_by_sid(self,sid = 0,conn_config = None):
|
||||
"""
|
||||
@取mssql数据库对像 By sid
|
||||
@sid 数据库分类,0:本地
|
||||
"""
|
||||
if type(sid) == str:
|
||||
try:
|
||||
sid = int(sid)
|
||||
except :sid = 0
|
||||
|
||||
if sid:
|
||||
if not conn_config: conn_config = public.M('database_servers').where("id=?" ,sid).find()
|
||||
db_obj = panelMongoDB()
|
||||
|
||||
try:
|
||||
db_obj = db_obj.set_host(conn_config['db_host'],conn_config['db_port'],None,conn_config['db_user'],conn_config['db_password'])
|
||||
except Exception as e:
|
||||
raise public.PanelError(e)
|
||||
else:
|
||||
db_obj = panelMongoDB()
|
||||
return db_obj
|
||||
|
||||
|
||||
|
||||
def get_local_auth(self,get):
|
||||
"""
|
||||
@验证本地数据库是否需要密码
|
||||
"""
|
||||
self.sid = get.get('sid/d',0)
|
||||
if self.sid != 0: return True
|
||||
|
||||
conf = panelMongoDB().get_options(None)
|
||||
if conf['authorization'] == 'enabled':
|
||||
return True
|
||||
return False
|
||||
|
||||
def AddDatabase(self,args):
|
||||
"""
|
||||
@添加数据库
|
||||
"""
|
||||
try:
|
||||
int(args.sid)
|
||||
except:
|
||||
return public.returnMsg(False, public.lang("Database type sid needs int type!"))
|
||||
if not int(args.sid) and not public.process_exists("mongod"):
|
||||
return public.returnMsg(False, public.lang("Mongodb service has not been started yet!"))
|
||||
username = ''
|
||||
password = ''
|
||||
auth_status = self.get_local_auth(args) #auth为true时如果__DB_USER为空则将它赋值为 root,用于开启本地认证后数据库用户为空的情况
|
||||
data_name = args.name.strip()
|
||||
if not data_name:
|
||||
return public.returnMsg(False, public.lang("Database name cannot be empty!"))
|
||||
if auth_status:
|
||||
res = self.add_base_database(args)
|
||||
if not res['status']: return res
|
||||
|
||||
data_name = res['data_name']
|
||||
username = res['username']
|
||||
password = res['data_pwd']
|
||||
else:
|
||||
username = data_name
|
||||
db_obj = self.get_obj_by_sid(self.sid).get_db_obj(data_name,auth=auth_status)
|
||||
dtype = 'MongoDB'
|
||||
if not hasattr(args,'ps'): args['ps'] = public.getMsg('INPUT_PS');
|
||||
addTime = time.strftime('%Y-%m-%d %X',time.localtime())
|
||||
|
||||
pid = 0
|
||||
if hasattr(args,'pid'): pid = args.pid
|
||||
|
||||
if hasattr(args,'contact'):
|
||||
site = public.M('sites').where("id=?",(args.contact,)).field('id,name').find()
|
||||
if site:
|
||||
pid = int(args.contact)
|
||||
args['ps'] = site['name']
|
||||
|
||||
db_type = 0
|
||||
if self.sid: db_type = 2
|
||||
|
||||
db_obj.chat.insert_one({})
|
||||
if auth_status:
|
||||
db_obj.command("createUser", username, pwd=password, roles=[{'role':'dbOwner','db':data_name},{'role':'userAdmin','db':data_name}])
|
||||
|
||||
public.set_module_logs('linux_mongodb','AddDatabase',1)
|
||||
|
||||
#添加入SQLITE
|
||||
public.M('databases').add('pid,sid,db_type,name,username,password,accept,ps,addtime,type',(pid,self.sid,db_type,data_name,username,password,'127.0.0.1',args['ps'],addTime,dtype))
|
||||
public.WriteLog("TYPE_DATABASE", 'DATABASE_ADD_SUCCESS',(data_name,))
|
||||
return public.returnMsg(True, public.lang("Added successfully!"))
|
||||
|
||||
|
||||
def DeleteDatabase(self,args):
|
||||
"""
|
||||
@删除数据库
|
||||
"""
|
||||
id = args['id']
|
||||
find = public.M('databases').where("id=?",(id,)).field('id,pid,name,username,password,type,accept,ps,addtime,sid,db_type').find()
|
||||
if not find: return public.returnMsg(False, public.lang("The specified database does not exist."))
|
||||
try:
|
||||
int(find['sid'])
|
||||
except:
|
||||
return public.returnMsg(False, public.lang("Database type sid needs int type!"))
|
||||
if not public.process_exists("mongod") and not int(find['sid']):
|
||||
return public.returnMsg(False, public.lang("Mongodb service has not been started yet!"))
|
||||
name = args['name']
|
||||
username = find['username']
|
||||
auth_status = self.get_local_auth(args)
|
||||
db_obj = self.get_obj_by_sid(find['sid']).get_db_obj(name,auth_status)
|
||||
try:
|
||||
db_obj.command("dropUser", username)
|
||||
except :
|
||||
pass
|
||||
|
||||
db_obj.command('dropDatabase')
|
||||
#删除SQLITE
|
||||
public.M('databases').where("id=?",(id,)).delete()
|
||||
public.WriteLog("Database manager", 'Successfully deleted!',(name,))
|
||||
return public.returnMsg(True, public.lang("Successfully deleted!"))
|
||||
|
||||
|
||||
def get_info_by_db_id(self,db_id):
|
||||
"""
|
||||
@获取数据库连接详情
|
||||
@db_id 数据库id
|
||||
"""
|
||||
find = public.M('databases').where("id=?" ,db_id).find()
|
||||
if not find: return False
|
||||
|
||||
data = {
|
||||
'db_host':'127.0.0.1',
|
||||
'db_port':int(panelMongoDB().get_options(None)['port']),
|
||||
'db_user':find['username'],
|
||||
'db_password':find['password']
|
||||
}
|
||||
|
||||
if int(find['sid']):
|
||||
conn_config = public.M('database_servers').where("id=?" ,find['sid']).find()
|
||||
|
||||
data['db_host'] = conn_config['db_host']
|
||||
data['db_port'] = int(conn_config['db_port'])
|
||||
|
||||
|
||||
return data
|
||||
|
||||
#导入
|
||||
def InputSql(self,args):
|
||||
name = args.name
|
||||
file = args.file
|
||||
|
||||
if not os.path.exists(file): return public.returnMsg(False, public.lang("The import path doesn't exist!"))
|
||||
if not os.path.isfile(file): return public.returnMsg(False, public.lang("Only compressed files can be imported!"))
|
||||
find = public.M('databases').where("name=? AND LOWER(type)=LOWER('MongoDB')",(name,)).find()
|
||||
if not find: return public.returnMsg(False, public.lang("This database was not found!"))
|
||||
|
||||
get = public.dict_obj()
|
||||
get.sid = find['sid']
|
||||
if not public.process_exists("mongod") and not int(find['sid']):
|
||||
return public.returnMsg(False, public.lang("Mongodb service has not been started yet!"))
|
||||
info = self.get_info_by_db_id(find['id'])
|
||||
mongorestore_obj = '{}/mongodb/bin/mongorestore'.format(public.get_setup_path())
|
||||
mongoimport_obj = '{}/mongodb/bin/mongoimport'.format(public.get_setup_path())
|
||||
if not os.path.exists(mongorestore_obj): return public.returnMsg(False, public.lang("Lack of backup tools, please install MongoDB through [APP Store] first!"))
|
||||
|
||||
dir_tmp, file_tmp = os.path.split(file)
|
||||
split_tmp = file_tmp.split(".")
|
||||
ext = split_tmp[-1]
|
||||
|
||||
ext_err = ".".join(split_tmp[1:])
|
||||
if len(split_tmp[1:]) == 2 and split_tmp[1] not in ['json', 'csv']:
|
||||
return public.returnMsg(False, f'.{ext_err} This file format is not currently supported!')
|
||||
if ext not in ['json', 'csv', 'gz', 'zip']:
|
||||
return public.returnMsg(False, f'.{ext_err} This file format is not currently supported!')
|
||||
|
||||
tmpFile = ".".join(split_tmp[:-1])
|
||||
isgzip = False
|
||||
if ext != '': # gz zip
|
||||
if tmpFile == '':
|
||||
return public.returnMsg(False, 'FILE_NOT_EXISTS', (tmpFile,))
|
||||
isgzip = True
|
||||
|
||||
# 面板默认备份路径
|
||||
backupPath = session['config']['backup_path'] + '/database'
|
||||
input_path = os.path.join(backupPath, tmpFile)
|
||||
# 备份文件的路径
|
||||
input_path2 = os.path.join(dir_tmp, tmpFile)
|
||||
|
||||
if ext == 'zip': # zip
|
||||
public.ExecShell("cd " + backupPath + " && unzip " + '"' + file + '"')
|
||||
else: # gz
|
||||
public.ExecShell("cd " + backupPath + " && tar zxf " + '"' + file + '"')
|
||||
if not os.path.exists(input_path):
|
||||
# 兼容从备份文件所在目录恢复
|
||||
if not os.path.exists(input_path2):
|
||||
public.ExecShell("cd " + backupPath + " && gunzip -q " + '"' + file + '"')
|
||||
else:
|
||||
input_path = input_path2
|
||||
|
||||
if not os.path.exists(input_path) and os.path.isfile(input_path2):
|
||||
input_path = input_path2
|
||||
else:
|
||||
input_path = file
|
||||
|
||||
if os.path.isdir(input_path): # zip,gz,bson
|
||||
if self.get_local_auth(get):
|
||||
for temp_file in os.listdir(input_path):
|
||||
shell = f"""
|
||||
{mongorestore_obj} \
|
||||
--host={info['db_host']} \
|
||||
--port={info['db_port']} \
|
||||
--db={find['name']} \
|
||||
--username={info['db_user']} \
|
||||
--password={info['db_password']} \
|
||||
--drop \
|
||||
{os.path.join(input_path, temp_file)}
|
||||
"""
|
||||
public.ExecShell(shell)
|
||||
else:
|
||||
for temp_file in os.listdir(input_path):
|
||||
shell = f"""
|
||||
{mongorestore_obj} \
|
||||
--host={info['db_host']} \
|
||||
--port={info['db_port']} \
|
||||
--db={find['name']} \
|
||||
--drop \
|
||||
{os.path.join(input_path, temp_file)}
|
||||
"""
|
||||
public.ExecShell(shell)
|
||||
if isgzip is True:
|
||||
public.ExecShell("rm -f " + input_path)
|
||||
else:# json,csv
|
||||
file_tmp = os.path.basename(input_path)
|
||||
file_name = file_tmp.split(".")[0]
|
||||
ext = file_tmp.split(".")[-1]
|
||||
|
||||
if ext not in ["json","csv"]:
|
||||
return public.returnMsg(False, public.lang("File format is incorrect!"))
|
||||
|
||||
shell_txt = ""
|
||||
if ext == "csv":
|
||||
fp = open(input_path, "r")
|
||||
fields_list = fp.readline()
|
||||
fp.close()
|
||||
shell_txt = f"--fields={fields_list}"
|
||||
if self.get_local_auth(get):
|
||||
shell = f"""
|
||||
{mongoimport_obj} \
|
||||
--host={info['db_host']} \
|
||||
--port={info['db_port']} \
|
||||
--db={find['name']} \
|
||||
--username={info['db_user']} \
|
||||
--password={info['db_password']} \
|
||||
--collection={file_name} \
|
||||
--file={input_path} \
|
||||
--type={ext} \
|
||||
--drop
|
||||
"""
|
||||
else:
|
||||
shell = f"""
|
||||
{mongoimport_obj} \
|
||||
--host={info['db_host']} \
|
||||
--port={info['db_port']} \
|
||||
--db={find['name']} \
|
||||
--collection={file_name} \
|
||||
--file={input_path} \
|
||||
--type={ext} \
|
||||
--drop
|
||||
"""
|
||||
shell = f"{shell} {shell_txt}"
|
||||
public.ExecShell(shell)
|
||||
public.WriteLog("Database manager", 'Import database [{}] succeeded'.format(name))
|
||||
return public.returnMsg(True, public.lang("Successfully imported database!"))
|
||||
|
||||
|
||||
def ToBackup(self,args):
|
||||
"""
|
||||
@备份数据库 id 数据库id
|
||||
"""
|
||||
id = args['id']
|
||||
find = public.M('databases').where("id=? AND LOWER(type)=LOWER('MongoDB')",(id,)).find()
|
||||
if not find: return public.returnMsg(False, public.lang("The specified database does not exist."))
|
||||
|
||||
fileName = f"{find['name']}_mongodb_data_{time.strftime('%Y%m%d_%H%M%S',time.localtime())}"
|
||||
backupName = session['config']['backup_path'] + '/database/mongodb/' + fileName
|
||||
|
||||
spath = os.path.dirname(backupName)
|
||||
if not os.path.exists(spath): os.makedirs(spath)
|
||||
|
||||
get = public.dict_obj()
|
||||
get.sid = find['sid']
|
||||
try:
|
||||
sid = int(find['sid'])
|
||||
except:
|
||||
return public.returnMsg(False, public.lang("Database type sid needs int type!"))
|
||||
if not public.process_exists("mongod") and not int(find['sid']):
|
||||
return public.returnMsg(False, public.lang("Mongodb service has not been started yet!"))
|
||||
info = self.get_info_by_db_id(id)
|
||||
|
||||
sql_dump = '{}/mongodb/bin/mongodump'.format(public.get_setup_path())
|
||||
if not os.path.exists(sql_dump): return public.returnMsg(False, public.lang("Lack of backup tools, please install MongoDB through [APP Store] first!"))
|
||||
|
||||
if self.get_local_auth(get):
|
||||
if not info['db_password']:
|
||||
return public.returnMsg(False, public.lang("Password authentication has been enabled. The password cannot be empty when the database is backed up. Please set a password and try again!"))
|
||||
shell = "{} -h {} --port {} -u {} -p {} -d {} -o {} ".format(sql_dump,info['db_host'],info['db_port'],info['db_user'],info['db_password'],find['name'] ,backupName)
|
||||
else:
|
||||
shell = "{} -h {} --port {} -d {} -o {} ".format(sql_dump,info['db_host'],info['db_port'],find['name'] ,backupName)
|
||||
|
||||
ret = public.ExecShell(shell)
|
||||
if not os.path.exists(backupName):
|
||||
return public.returnMsg(False, public.lang("Database backup failed, file does not exist"));
|
||||
|
||||
|
||||
backupFile = f"{backupName}.zip"
|
||||
public.ExecShell(f"cd {spath} && zip {backupFile} -r {fileName}")
|
||||
fileName = f"{fileName}.zip"
|
||||
public.M('backup').add('type,name,pid,filename,size,addtime',(1,fileName,id,backupFile,0,time.strftime('%Y-%m-%d %X',time.localtime())))
|
||||
public.WriteLog("TYPE_DATABASE", "DATABASE_BACKUP_SUCCESS",(find['name'],))
|
||||
|
||||
public.ExecShell(f"rm -rf {backupName}")
|
||||
if not os.path.exists(backupFile):
|
||||
return public.returnMsg(True, public.lang("Backup failed,{}.",ret[0]))
|
||||
if os.path.getsize(backupFile) < 1:
|
||||
return public.returnMsg(True, public.lang("The backup is executed successfully, the backup file is less than 1b, please check the backup integrity."))
|
||||
else:
|
||||
return public.returnMsg(True, public.lang("Backup Succeeded!"))
|
||||
|
||||
def DelBackup(self,args):
|
||||
"""
|
||||
@删除备份文件
|
||||
"""
|
||||
return self.delete_base_backup(args)
|
||||
|
||||
#同步数据库到服务器
|
||||
def SyncToDatabases(self,get):
|
||||
type = int(get['type'])
|
||||
n = 0
|
||||
sql = public.M('databases')
|
||||
if type == 0:
|
||||
data = sql.field('id,name,username,password,accept,type,sid,db_type').where('type=?',('MongoDB',)).select()
|
||||
|
||||
for value in data:
|
||||
if value['db_type'] in ['1',1]:
|
||||
continue # 跳过远程数据库
|
||||
result = self.ToDataBase(value)
|
||||
if result == 1: n +=1
|
||||
else:
|
||||
import json
|
||||
data = json.loads(get.ids)
|
||||
for value in data:
|
||||
find = sql.where("id=?",(value,)).field('id,name,username,password,sid,db_type,accept,type').find()
|
||||
result = self.ToDataBase(find)
|
||||
if result == 1: n +=1
|
||||
if n == 1:
|
||||
return public.returnMsg(True, public.lang("Synchronization succeeded"))
|
||||
elif n == 0:
|
||||
return public.returnMsg(False, public.lang("Sync failed"))
|
||||
return public.returnMsg(True,'Database sync success',(str(n),))
|
||||
|
||||
#添加到服务器
|
||||
def ToDataBase(self,find):
|
||||
if find['username'] == 'bt_default': return 0
|
||||
if len(find['password']) < 3 :
|
||||
find['username'] = find['name']
|
||||
find['password'] = public.md5(str(time.time()) + find['name'])[0:10]
|
||||
public.M('databases').where("id=?",(find['id'],)).save('password,username',(find['password'],find['username']))
|
||||
|
||||
self.sid = find['sid']
|
||||
try:
|
||||
int(find['sid'])
|
||||
except:
|
||||
return public.returnMsg(False, public.lang("Database type sid needs int type!!"))
|
||||
if not public.process_exists("mongod") and not int(find['sid']):
|
||||
return public.returnMsg(False, public.lang("Mongodb service has not been started yet!!"))
|
||||
|
||||
|
||||
get = public.dict_obj()
|
||||
get.sid = self.sid
|
||||
auth_status = self.get_local_auth(get)
|
||||
if auth_status:
|
||||
db_obj = self.get_obj_by_sid(self.sid).get_db_obj(find['name'], auth_status)
|
||||
try:
|
||||
db_obj.chat.insert_one({})
|
||||
db_obj.command("dropUser", find['username'])
|
||||
except :pass
|
||||
try:
|
||||
db_obj.command("createUser", find['username'], pwd=find['password'], roles=[{'role':'dbOwner','db':find['name']},{'role':'userAdmin','db':find['name']}])
|
||||
except:
|
||||
pass
|
||||
return 1
|
||||
|
||||
def SyncGetDatabases(self,get):
|
||||
"""
|
||||
@从服务器获取数据库
|
||||
"""
|
||||
n = 0;s = 0;
|
||||
db_type = 0
|
||||
self.sid = get.get('sid/d',0)
|
||||
if self.sid: db_type = 2
|
||||
try:
|
||||
int(get.sid)
|
||||
except:
|
||||
return public.returnMsg(False, public.lang("The database type SID requires an INT!"))
|
||||
if not public.process_exists("mongod") and not int(get.sid):
|
||||
return public.returnMsg(False, public.lang("The Mongodb service is not enabled!"))
|
||||
auth_status = self.get_local_auth(get)
|
||||
data = self.get_obj_by_sid(self.sid).get_db_obj('admin',auth=auth_status).command({"listDatabases":1})
|
||||
|
||||
sql = public.M('databases')
|
||||
nameArr = ['information_schema','performance_schema','mysql','sys','master','model','msdb','tempdb','config','local','admin']
|
||||
for item in data['databases']:
|
||||
dbname = item['name']
|
||||
if sql.where("name=?",(dbname,)).count(): continue
|
||||
if not dbname in nameArr:
|
||||
if sql.table('databases').add('name,username,password,accept,ps,addtime,type,sid,db_type',(dbname,dbname,'','',public.getMsg('INPUT_PS'),time.strftime('%Y-%m-%d %X',time.localtime()),'MongoDB',self.sid,db_type)): n +=1
|
||||
|
||||
return public.returnMsg(True,'Database success',(str(n),))
|
||||
|
||||
|
||||
def ResDatabasePassword(self,args):
|
||||
"""
|
||||
@修改用户密码
|
||||
"""
|
||||
id = args['id']
|
||||
username = args['name'].strip()
|
||||
newpassword = public.trim(args['password'])
|
||||
|
||||
try:
|
||||
if not newpassword:
|
||||
return public.returnMsg(False, public.lang("Modify the failure,The database[' + username + ']password cannot be empty."));
|
||||
if len(re.search(r"^[\w@\.]+$", newpassword).groups()) > 0:
|
||||
return public.returnMsg(False, public.lang("The database password cannot be empty or contain special characters"))
|
||||
|
||||
if re.search('[\u4e00-\u9fa5]',newpassword):
|
||||
return public.returnMsg(False, public.lang("Database password cannot be Chinese, please change the name!"))
|
||||
except :
|
||||
return public.returnMsg(False, public.lang("The database password cannot be empty or contain special characters"))
|
||||
|
||||
find = public.M('databases').where("id=?",(id,)).field('id,pid,name,username,password,type,accept,ps,addtime,sid').find();
|
||||
if not find: return public.returnMsg(False, public.lang("The modification failed because the specified database does not exist."));
|
||||
|
||||
get = public.dict_obj()
|
||||
get.sid = find['sid']
|
||||
try:
|
||||
int(find['sid'])
|
||||
except:
|
||||
return public.returnMsg(False, public.lang("The database type SID requires an INT!"))
|
||||
if not public.process_exists("mongod") and not int(find['sid']):
|
||||
return public.returnMsg(False, public.lang("The Mongodb service is not enabled!"))
|
||||
auth_status = self.get_local_auth(args)
|
||||
if auth_status:
|
||||
db_obj = self.get_obj_by_sid(find['sid']).get_db_obj(username,auth=auth_status)
|
||||
try:
|
||||
print(db_obj.command("updateUser", username, pwd = newpassword))
|
||||
except :
|
||||
print(db_obj.command("createUser", username, pwd=newpassword, roles=[{'role':'dbOwner','db':find['name']},{'role':'userAdmin','db':find['name']}]))
|
||||
else:
|
||||
return public.returnMsg(False, public.lang("Password access is not enabled for the database."))
|
||||
|
||||
#修改SQLITE
|
||||
public.M('databases').where("id=?",(id,)).setField('password',newpassword)
|
||||
|
||||
public.WriteLog("TYPE_DATABASE",'Database password success',(find['name'],))
|
||||
return public.returnMsg(True,'Database password success',(find['name'],))
|
||||
|
||||
def get_root_pwd(self,args):
|
||||
"""
|
||||
@获取root密码
|
||||
"""
|
||||
config = panelMongoDB().get_options(None)
|
||||
sa_path = '{}/data/mongo.root'.format(public.get_panel_path())
|
||||
if os.path.exists(sa_path):
|
||||
config['msg'] = public.readFile(sa_path)
|
||||
else:
|
||||
config['msg'] = ''
|
||||
config['root'] = config['msg']
|
||||
return config
|
||||
|
||||
def get_database_size_by_id(self, args):
|
||||
"""
|
||||
@获取数据库尺寸(批量删除验证)
|
||||
@args json/int 数据库id
|
||||
"""
|
||||
# if not public.process_exists("mongod"):
|
||||
# return public.returnMsg(False, public.lang("The Mongodb service is not enabled!"))
|
||||
total = 0
|
||||
db_id = args
|
||||
if not isinstance(args, int): db_id = args['db_id']
|
||||
|
||||
find = public.M('databases').where('id=?', db_id).find()
|
||||
try:
|
||||
int(find['sid'])
|
||||
except:
|
||||
return 0
|
||||
if not public.process_exists("mongod") and not int(find['sid']):
|
||||
return 0
|
||||
try:
|
||||
auth_status = self.get_local_auth(args)
|
||||
db_obj = self.get_obj_by_sid(find['sid']).get_db_obj(find['name'], auth=auth_status)
|
||||
print(db_obj)
|
||||
print(db_obj.stats())
|
||||
|
||||
total = tables[0][1]
|
||||
if not total: total = 0
|
||||
except:
|
||||
print(public.get_error_info())
|
||||
|
||||
|
||||
|
||||
return total
|
||||
|
||||
def check_del_data(self,args):
|
||||
"""
|
||||
@删除数据库前置检测
|
||||
"""
|
||||
return self.check_base_del_data(args)
|
||||
|
||||
|
||||
def check_cloud_database_status(self,conn_config):
|
||||
"""
|
||||
@检测远程数据库是否连接
|
||||
@conn_config 远程数据库配置,包含host port pwd等信息
|
||||
"""
|
||||
try:
|
||||
if not 'db_name' in conn_config: conn_config['db_name'] = None
|
||||
sql_obj = panelMongoDB().set_host(conn_config['db_host'],conn_config['db_port'],conn_config['db_name'],conn_config['db_user'],conn_config['db_password'])
|
||||
|
||||
db_obj = sql_obj.get_db_obj('admin')
|
||||
data = db_obj.command({"listDatabases":1})
|
||||
|
||||
if 'databases' in data:
|
||||
return True
|
||||
return False
|
||||
except Exception as ex:
|
||||
return public.returnMsg(False,ex)
|
||||
671
class/databaseModel/pgsqlModel.py
Normal file
671
class/databaseModel/pgsqlModel.py
Normal file
@@ -0,0 +1,671 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# YakPanel
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 YakPanel(www.yakpanel.com) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: hezhihong <bt_ahong@yakpanel.com>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# postgresql模型
|
||||
#------------------------------
|
||||
import os,re,json,time
|
||||
from databaseModel.base import databaseBase
|
||||
import public
|
||||
try:
|
||||
from YakPanel import session
|
||||
except :pass
|
||||
try:
|
||||
import psycopg2
|
||||
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
|
||||
except:
|
||||
pass
|
||||
|
||||
class panelPgsql:
|
||||
__DB_PASS = None
|
||||
__DB_USER = 'postgres'
|
||||
__DB_PORT = 5432
|
||||
__DB_HOST = 'localhost'
|
||||
__DB_CONN = None
|
||||
__DB_CUR = None
|
||||
__DB_ERR = None
|
||||
|
||||
__DB_CLOUD = 0 #远程数据库
|
||||
def __init__(self):
|
||||
self.__DB_CLOUD = 0
|
||||
if self.__DB_USER=='postgres' and self.__DB_HOST == 'localhost' and self.__DB_PASS ==None:
|
||||
tmp_args=public.dict_obj()
|
||||
tmp_args.is_True = True
|
||||
self.__DB_PASS =main().get_root_pwd(tmp_args)
|
||||
|
||||
|
||||
def set_host(self,host,port,name,username,password,prefix = ''):
|
||||
self.__DB_HOST = host
|
||||
self.__DB_PORT = int(port)
|
||||
self.__DB_NAME = name
|
||||
if self.__DB_NAME: self.__DB_NAME = str(self.__DB_NAME)
|
||||
self.__DB_USER = str(username)
|
||||
self._USER = str(username)
|
||||
self.__DB_PASS = str(password)
|
||||
self.__DB_PREFIX = prefix
|
||||
self.__DB_CLOUD = 1
|
||||
return self
|
||||
|
||||
|
||||
def check_psycopg(self):
|
||||
"""
|
||||
@name检测依赖是否正常
|
||||
"""
|
||||
try:
|
||||
import psycopg2
|
||||
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
|
||||
except:
|
||||
os.system('btpip install psycopg2-binary')
|
||||
try:
|
||||
import psycopg2
|
||||
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
|
||||
except:
|
||||
return False
|
||||
return True
|
||||
|
||||
#连接MYSQL数据库
|
||||
def __Conn(self):
|
||||
self.check_psycopg()
|
||||
try:
|
||||
import psycopg2
|
||||
except:
|
||||
self.__DB_ERR = public.get_error_info()
|
||||
return False
|
||||
try:
|
||||
if self.__DB_USER == 'postgres' and self.__DB_HOST=='localhost':
|
||||
if not self.__DB_PASS:
|
||||
tmp_args=public.dict_obj()
|
||||
try:
|
||||
self.__DB_PASS==main().get_root_pwd(tmp_args)['msg']
|
||||
except:
|
||||
pass
|
||||
self.__DB_CONN = psycopg2.connect(user=self.__DB_USER, password = self.__DB_PASS, host=self.__DB_HOST, port = self.__DB_PORT)
|
||||
self.__DB_CONN.autocommit = True
|
||||
self.__DB_CONN.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) # <-- ADD THIS LINE
|
||||
|
||||
self.__DB_CUR = self.__DB_CONN.cursor()
|
||||
return True
|
||||
except :
|
||||
|
||||
self.__DB_ERR = public.get_error_info()
|
||||
print(self.__DB_ERR)
|
||||
return False
|
||||
|
||||
def execute(self,sql):
|
||||
#执行SQL语句返回受影响行
|
||||
if not self.__Conn(): return self.__DB_ERR
|
||||
try:
|
||||
#print(sql)
|
||||
result = self.__DB_CUR.execute(sql)
|
||||
self.__DB_CONN.commit()
|
||||
self.__Close()
|
||||
return result
|
||||
except Exception as ex:
|
||||
|
||||
return ex
|
||||
|
||||
def query(self,sql):
|
||||
|
||||
#执行SQL语句返回数据集
|
||||
if not self.__Conn(): return self.__DB_ERR
|
||||
try:
|
||||
self.__DB_CUR.execute(sql)
|
||||
result = self.__DB_CUR.fetchall()
|
||||
|
||||
data = list(map(list,result))
|
||||
self.__Close()
|
||||
return data
|
||||
except Exception as ex:
|
||||
return ex
|
||||
|
||||
#关闭连接
|
||||
def __Close(self):
|
||||
self.__DB_CUR.close()
|
||||
self.__DB_CONN.close()
|
||||
|
||||
class main(databaseBase,panelPgsql):
|
||||
|
||||
__ser_name = None
|
||||
__soft_path = '/www/server/pgsql'
|
||||
__setup_path = '/www/server/panel/'
|
||||
__dbuser_info_path = "{}plugin/pgsql_manager_dbuser_info.json".format(__setup_path)
|
||||
__plugin_path = "{}plugin/pgsql_manager/".format(__setup_path)
|
||||
|
||||
def __init__(self):
|
||||
|
||||
s_path = public.get_setup_path()
|
||||
v_info = public.readFile("{}/pgsql/version.pl".format(s_path))
|
||||
if v_info:
|
||||
ver = v_info.split('.')[0]
|
||||
self.__ser_name = 'postgresql-x64-{}'.format(ver)
|
||||
self.__soft_path = '{}/pgsql/{}'.format(s_path)
|
||||
|
||||
|
||||
#获取配置项
|
||||
def get_options(self,get):
|
||||
data = {}
|
||||
options = ['port','listen_addresses']
|
||||
if not self.__soft_path:self.__soft_path='{}/pgsql'.format(public.get_setup_path())
|
||||
conf = public.readFile('{}/data/postgresql.conf'.format(self.__soft_path))
|
||||
for opt in options:
|
||||
tmp = re.findall(r"\s+" +opt + r"\s*=\s*(.+)#",conf)
|
||||
if not tmp: continue;
|
||||
data[opt] = tmp[0].strip()
|
||||
if opt == 'listen_addresses':
|
||||
data[opt] = data[opt].replace('\'','')
|
||||
data['password'] = self.get_root_pwd(None)['msg']
|
||||
return data
|
||||
|
||||
def get_list(self,args):
|
||||
"""
|
||||
@获取数据库列表
|
||||
@sql_type = pgsql
|
||||
"""
|
||||
return self.get_base_list(args, sql_type = 'pgsql')
|
||||
|
||||
|
||||
def get_sql_obj_by_sid(self,sid = 0,conn_config = None):
|
||||
"""
|
||||
@取pgsql数据库对像 By sid
|
||||
@sid 数据库分类,0:本地
|
||||
"""
|
||||
if type(sid) == str:
|
||||
try:
|
||||
sid = int(sid)
|
||||
except :sid = 0
|
||||
|
||||
if sid:
|
||||
if not conn_config: conn_config = public.M('database_servers').where("id=?" ,sid).find()
|
||||
db_obj = panelPgsql()
|
||||
|
||||
try:
|
||||
db_obj = db_obj.set_host(conn_config['db_host'],conn_config['db_port'],None,conn_config['db_user'],conn_config['db_password'])
|
||||
except Exception as e:
|
||||
raise public.PanelError(e)
|
||||
else:
|
||||
db_obj = panelPgsql()
|
||||
return db_obj
|
||||
|
||||
def get_sql_obj(self,db_name):
|
||||
"""
|
||||
@取pgsql数据库对象
|
||||
@db_name 数据库名称
|
||||
"""
|
||||
is_cloud_db = False
|
||||
if db_name:
|
||||
db_find = public.M('databases').where("name=?" ,db_name).find()
|
||||
if db_find['sid']:
|
||||
return self.get_sql_obj_by_sid(db_find['sid'])
|
||||
is_cloud_db = db_find['db_type'] in ['1',1]
|
||||
|
||||
if is_cloud_db:
|
||||
|
||||
db_obj = panelPgsql()
|
||||
conn_config = json.loads(db_find['conn_config'])
|
||||
try:
|
||||
db_obj = db_obj.set_host(conn_config['db_host'],conn_config['db_port'],conn_config['db_name'],conn_config['db_user'],conn_config['db_password'])
|
||||
except Exception as e:
|
||||
raise public.PanelError(e)
|
||||
else:
|
||||
db_obj = panelPgsql()
|
||||
return db_obj
|
||||
|
||||
def GetCloudServer(self,args):
|
||||
'''
|
||||
@name 获取远程服务器列表
|
||||
@author hwliang<2021-01-10>
|
||||
@return list
|
||||
'''
|
||||
check_result = os.system('/www/server/pgsql/bin/psql --version')
|
||||
if check_result !=0 and not public.M('database_servers').where('db_type=?','pgsql').count():
|
||||
return []
|
||||
return self.GetBaseCloudServer(args)
|
||||
|
||||
|
||||
def AddCloudServer(self,args):
|
||||
'''
|
||||
@添加远程数据库
|
||||
'''
|
||||
return self.AddBaseCloudServer(args)
|
||||
|
||||
def RemoveCloudServer(self,args):
|
||||
'''
|
||||
@删除远程数据库
|
||||
'''
|
||||
return self.RemoveBaseCloudServer(args)
|
||||
|
||||
def ModifyCloudServer(self,args):
|
||||
'''
|
||||
@修改远程数据库
|
||||
'''
|
||||
return self.ModifyBaseCloudServer(args)
|
||||
|
||||
def AddDatabase(self,args):
|
||||
"""
|
||||
@添加数据库
|
||||
"""
|
||||
if not args.get('name/str',0):return public.returnMsg(False, public.lang("Database name cannot be empty!"))
|
||||
import re
|
||||
test_str = re.search(r"\W",args.name)
|
||||
if test_str!=None:
|
||||
return public.returnMsg(False, public.lang("The database name cannot contain special characters"))
|
||||
res = self.add_base_database(args)
|
||||
if not res['status']: return res
|
||||
|
||||
data_name = res['data_name']
|
||||
username = res['username']
|
||||
password = res['data_pwd']
|
||||
try:
|
||||
self.sid = int(args['sid'])
|
||||
except :
|
||||
self.sid = 0
|
||||
|
||||
dtype = 'PgSql'
|
||||
sql_obj = self.get_sql_obj_by_sid(self.sid)
|
||||
result = sql_obj.execute("CREATE DATABASE {};".format(data_name))
|
||||
isError = self.IsSqlError(result)
|
||||
if isError != None: return isError
|
||||
|
||||
#添加用户
|
||||
self.__CreateUsers(data_name,username,password,'127.0.0.1')
|
||||
|
||||
if not hasattr(args,'ps'): args['ps'] = public.getMsg('INPUT_PS');
|
||||
addTime = time.strftime('%Y-%m-%d %X',time.localtime())
|
||||
|
||||
pid = 0
|
||||
if hasattr(args,'pid'): pid = args.pid
|
||||
|
||||
if hasattr(args,'contact'):
|
||||
site = public.M('sites').where("id=?",(args.contact,)).field('id,name').find()
|
||||
if site:
|
||||
pid = int(args.contact)
|
||||
args['ps'] = site['name']
|
||||
|
||||
db_type = 0
|
||||
if self.sid: db_type = 2
|
||||
|
||||
public.set_module_logs('pgsql','AddDatabase',1)
|
||||
#添加入SQLITE
|
||||
public.M('databases').add('pid,sid,db_type,name,username,password,accept,ps,addtime,type',(pid,self.sid,db_type,data_name,username,password,'127.0.0.1',args['ps'],addTime,dtype))
|
||||
public.WriteLog("TYPE_DATABASE", 'DATABASE_ADD_SUCCESS',(data_name,))
|
||||
return public.returnMsg(True, public.lang("Added successfully!"))
|
||||
|
||||
def DeleteDatabase(self,get):
|
||||
"""
|
||||
@删除数据库
|
||||
"""
|
||||
id = get['id']
|
||||
find = public.M('databases').where("id=?",(id,)).field('id,pid,name,username,password,accept,ps,addtime,db_type,conn_config,sid,type').find();
|
||||
if not find: return public.returnMsg(False, public.lang("The specified database does not exist."))
|
||||
|
||||
name = get['name']
|
||||
username = find['username']
|
||||
|
||||
sql_obj = self.get_sql_obj_by_sid(find['sid'])
|
||||
result = sql_obj.execute("drop database {};".format(name))
|
||||
sql_obj.execute("drop user {};".format(username))
|
||||
#删除SQLITE
|
||||
public.M('databases').where("id=?",(id,)).delete()
|
||||
public.WriteLog("TYPE_DATABASE", 'DATABASE_DEL_SUCCESS',(name,))
|
||||
return public.returnMsg(True, public.lang("Delete successfully!"))
|
||||
|
||||
|
||||
def ToBackup(self,args):
|
||||
"""
|
||||
@备份数据库 id 数据库id
|
||||
"""
|
||||
id = args['id']
|
||||
|
||||
find = public.M('databases').where("id=?",(id,)).find()
|
||||
if not find: return public.returnMsg(False, public.lang("Database does not exist!"))
|
||||
|
||||
if not find['password'].strip():
|
||||
return public.returnMsg(False, public.lang("The database password is empty. Set the password first."))
|
||||
|
||||
sql_dump = '{}/bin/pg_dump'.format(self.__soft_path)
|
||||
# return sql_dump
|
||||
if not os.path.isfile(sql_dump):
|
||||
return public.returnMsg(False, public.lang("Lack of backup tools, please first through the software store PGSQL manager!"))
|
||||
|
||||
back_path = session['config']['backup_path'] + '/database/pgsql/'
|
||||
# return back_path
|
||||
if not os.path.exists(back_path): os.makedirs(back_path)
|
||||
|
||||
fileName = find['name'] + '_' + time.strftime('%Y%m%d_%H%M%S',time.localtime()) + '.sql'
|
||||
|
||||
backupName = back_path + fileName
|
||||
|
||||
|
||||
if int(find['sid']):
|
||||
info = self.get_info_by_db_id(id)
|
||||
shell = '{} "host={} port={} user={} dbname={} password={}" > {}'.format(sql_dump,info['db_host'],info['db_port'],info['db_user'],find['name'],info['db_password'],backupName)
|
||||
else:
|
||||
args_one =public.dict_obj()
|
||||
port = self.get_port(args_one)
|
||||
shell = '{} "host=127.0.0.1 port={} user={} dbname={} password={}" > {}'.format(sql_dump,port['data'],find['username'],find['name'],find['password'],backupName)
|
||||
|
||||
ret = public.ExecShell(shell)
|
||||
if not os.path.exists(backupName):
|
||||
return public.returnMsg(False, public.lang("Backup error"));
|
||||
|
||||
public.M('backup').add('type,name,pid,filename,size,addtime',(1,fileName,id,backupName,0,time.strftime('%Y-%m-%d %X',time.localtime())))
|
||||
public.WriteLog("TYPE_DATABASE", "DATABASE_BACKUP_SUCCESS",(find['name'],))
|
||||
|
||||
if os.path.getsize(backupName) < 2048:
|
||||
return public.returnMsg(True, public.lang("The backup file size is smaller than 2Kb. Check the backup integrity."))
|
||||
else:
|
||||
return public.returnMsg(True, public.lang("Backup Succeeded!"))
|
||||
|
||||
def DelBackup(self,args):
|
||||
"""
|
||||
@删除备份文件
|
||||
"""
|
||||
return self.delete_base_backup(args)
|
||||
|
||||
def get_port(self, args): # 获取端口号
|
||||
str_shell = '''netstat -luntp|grep postgres|head -1|awk '{print $4}'|awk -F: '{print $NF}' '''
|
||||
try:
|
||||
port = public.ExecShell(str_shell)[0]
|
||||
if port.strip():
|
||||
return {'data': port.strip(), "status": True}
|
||||
else:
|
||||
return {'data': 5432, "status": False}
|
||||
except:
|
||||
return {'data': 5432, "status": False}
|
||||
|
||||
|
||||
#导入
|
||||
def InputSql(self,get):
|
||||
|
||||
name = get.name
|
||||
file = get.file
|
||||
# return name
|
||||
|
||||
find = public.M('databases').where("name=?",(name,)).find()
|
||||
if not find: return public.returnMsg(False, public.lang("Database does not exist!"))
|
||||
# return find
|
||||
if not find['password'].strip():
|
||||
return public.returnMsg(False, public.lang("The database password is empty. Set the password first."))
|
||||
|
||||
tmp = file.split('.')
|
||||
exts = ['sql']
|
||||
ext = tmp[len(tmp) -1]
|
||||
if ext not in exts:
|
||||
return public.returnMsg(False, public.lang("Select sql、gz、zip file!"))
|
||||
|
||||
sql_dump = '{}/bin/psql'.format(self.__soft_path)
|
||||
if not os.path.exists(sql_dump):
|
||||
return public.returnMsg(False, public.lang("Lack of recovery tool, please use software management to install PGSQL!"))
|
||||
|
||||
if int(find['sid']):
|
||||
info = self.get_info_by_db_id(find['id'])
|
||||
shell = '{} "host={} port={} user={} dbname={} password={}" < {}'.format(sql_dump,info['db_host'],info['db_port'],info['db_user'],find['name'],info['db_password'],file)
|
||||
else:
|
||||
args_one =public.dict_obj()
|
||||
port = self.get_port(args_one)
|
||||
shell = '{} "host=127.0.0.1 port={} user={} dbname={} password={}" < {}'.format(sql_dump,port['data'],find['username'],find['name'],find['password'],file)
|
||||
|
||||
ret = public.ExecShell(shell)
|
||||
|
||||
public.WriteLog("TYPE_DATABASE", 'Description Succeeded in importing database [{}]'.format(name))
|
||||
return public.returnMsg(True, public.lang("Successfully imported database!"));
|
||||
|
||||
|
||||
def SyncToDatabases(self,get):
|
||||
"""
|
||||
@name同步数据库到服务器
|
||||
"""
|
||||
tmp_type = int(get['type'])
|
||||
n = 0
|
||||
sql = public.M('databases')
|
||||
if tmp_type == 0:
|
||||
where = "lower(type) = lower('pgsql')"
|
||||
# data = sql.field('id,name,username,password,accept,type,sid,db_type').where('type=?',('pgsql',)).select()
|
||||
data = sql.field('id,name,username,password,accept,type,sid,db_type').where(where,()).select()
|
||||
print(data)
|
||||
for value in data:
|
||||
if value['db_type'] in ['1',1]:
|
||||
continue # 跳过远程数据库
|
||||
result = self.ToDataBase(value)
|
||||
if result == 1: n +=1
|
||||
else:
|
||||
import json
|
||||
data = json.loads(get.ids)
|
||||
for value in data:
|
||||
find = sql.where("id=?",(value,)).field('id,name,username,password,sid,db_type,accept,type').find()
|
||||
result = self.ToDataBase(find)
|
||||
if result == 1: n +=1
|
||||
if n == 1:
|
||||
return public.returnMsg(True, public.lang("Synchronization succeeded"))
|
||||
elif n == 0:
|
||||
return public.returnMsg(False, public.lang("Sync failed"))
|
||||
return public.returnMsg(True,'Database sync success',(str(n),))
|
||||
|
||||
def ToDataBase(self,find):
|
||||
"""
|
||||
@name 添加到服务器
|
||||
"""
|
||||
if find['username'] == 'bt_default': return 0
|
||||
if len(find['password']) < 3 :
|
||||
find['username'] = find['name']
|
||||
find['password'] = public.md5(str(time.time()) + find['name'])[0:10]
|
||||
public.M('databases').where("id=?",(find['id'],)).save('password,username',(find['password'],find['username']))
|
||||
|
||||
self.sid = find['sid']
|
||||
sql_obj = self.get_sql_obj_by_sid(self.sid)
|
||||
result = sql_obj.execute("CREATE DATABASE {};".format(find['name']))
|
||||
isError = self.IsSqlError(result)
|
||||
if isError != None and isError['status']==False and isError['msg']=='指定数据库已存在,请勿重复添加.':return 1
|
||||
|
||||
self.__CreateUsers(find['name'],find['username'],find['password'],'127.0.0.1')
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
def SyncGetDatabases(self,get):
|
||||
"""
|
||||
@name 从服务器获取数据库
|
||||
@param sid 0为本地数据库 1为远程数据库
|
||||
"""
|
||||
n = 0;s = 0;
|
||||
db_type = 0
|
||||
self.sid = get.get('sid/d',0)
|
||||
if self.sid: db_type = 2
|
||||
|
||||
sql_obj = self.get_sql_obj_by_sid(self.sid)
|
||||
data = sql_obj.query('SELECT datname FROM pg_database;')#select * from pg_database order by datname;
|
||||
isError = self.IsSqlError(data)
|
||||
if isError != None: return isError
|
||||
if type(data) == str: return public.returnMsg(False,data)
|
||||
|
||||
sql = public.M('databases')
|
||||
nameArr = ['information_schema','postgres','template1','template0','performance_schema','mysql','sys','master','model','msdb','tempdb','ReportServerTempDB','YueMiao','ReportServer']
|
||||
for item in data:
|
||||
|
||||
dbname = item[0]
|
||||
|
||||
if sql.where("name=?",(dbname,)).count(): continue
|
||||
if not dbname in nameArr:
|
||||
if sql.table('databases').add('name,username,password,accept,ps,addtime,type,sid,db_type',(dbname,dbname,'','',public.getMsg('INPUT_PS'),time.strftime('%Y-%m-%d %X',time.localtime()),'pgsql',self.sid,db_type)): n +=1
|
||||
|
||||
return public.returnMsg(True,'Database success',(str(n),))
|
||||
|
||||
def ResDatabasePassword(self,args):
|
||||
"""
|
||||
@修改用户密码
|
||||
"""
|
||||
id = args['id']
|
||||
username = args['name'].strip()
|
||||
newpassword = public.trim(args['password'])
|
||||
if not newpassword: return public.returnMsg(False, public.lang("The database password cannot be empty."));
|
||||
|
||||
|
||||
find = public.M('databases').where("id=?",(id,)).field('id,pid,name,username,password,type,accept,ps,addtime,sid').find();
|
||||
if not find: return public.returnMsg(False, public.lang("Modify the failure,The specified database does not exist."));
|
||||
|
||||
sql_obj = self.get_sql_obj_by_sid(find['sid'])
|
||||
result = sql_obj.execute("alter user {} with password '{}';".format(username,newpassword))
|
||||
isError = self.IsSqlError(result)
|
||||
if isError != None: return isError
|
||||
|
||||
#修改SQLITE
|
||||
public.M('databases').where("id=?",(id,)).setField('password',newpassword)
|
||||
|
||||
public.WriteLog("TYPE_DATABASE",'Database password success',(find['name'],))
|
||||
return public.returnMsg(True,'Database password success',(find['name'],))
|
||||
|
||||
|
||||
def get_root_pwd(self,args):
|
||||
"""
|
||||
@获取sa密码
|
||||
"""
|
||||
check_result = os.system('/www/server/pgsql/bin/psql --version')
|
||||
if check_result !=0:return public.returnMsg(False, public.lang("If PgSQL is not installed or started, install or start it first"))
|
||||
password = ''
|
||||
path = '{}/data/postgresAS.json'.format(public.get_panel_path())
|
||||
if os.path.isfile(path):
|
||||
try:
|
||||
password = json.loads(public.readFile(path))['password']
|
||||
print('333333333')
|
||||
print(password)
|
||||
except :pass
|
||||
if 'is_True' in args and args.is_True:return password
|
||||
return public.returnMsg(True,password)
|
||||
|
||||
|
||||
def set_root_pwd(self,args):
|
||||
"""
|
||||
@设置sa密码
|
||||
"""
|
||||
password = public.trim(args['password'])
|
||||
if len(password) < 8 : return public.returnMsg(False, public.lang("The password must not be less than 8 digits."))
|
||||
check_result = os.system('/www/server/pgsql/bin/psql --version')
|
||||
if check_result !=0:return public.returnMsg(False, public.lang("If PgSQL is not installed or started, install or start it first"))
|
||||
sql_obj = self.get_sql_obj_by_sid('0')
|
||||
data = sql_obj.query('SELECT datname FROM pg_database;')
|
||||
isError = self.IsSqlError(data)
|
||||
if isError != None: return isError
|
||||
|
||||
path = '{}/data/pg_hba.conf'.format(self.__soft_path)
|
||||
p_path = '{}/data/postgresAS.json'.format(public.get_panel_path())
|
||||
if not os.path.isfile(path):
|
||||
return public.returnMsg(False,public.lang('{}File does not exist, please check the installation is complete!',path))
|
||||
|
||||
src_conf = public.readFile(path)
|
||||
add_conf = src_conf.replace('md5','trust')
|
||||
# public.writeFile(path,public.readFile(path).replace('md5','trust'))
|
||||
public.writeFile(path,add_conf)
|
||||
|
||||
pg_obj = panelPgsql()
|
||||
pg_obj.execute("ALTER USER postgres WITH PASSWORD '{}';".format(password))
|
||||
data = {"username":"postgres","password":""}
|
||||
try:
|
||||
data = json.loads(public.readFile(p_path))
|
||||
except : pass
|
||||
data['password'] = password
|
||||
public.writeFile(p_path,json.dumps(data))
|
||||
public.writeFile(path, src_conf)
|
||||
return public.returnMsg(True, public.lang("The administrator password is successfully changed. Procedure."))
|
||||
|
||||
|
||||
|
||||
def get_info_by_db_id(self,db_id):
|
||||
"""
|
||||
@获取数据库连接详情
|
||||
@db_id 数据库id
|
||||
"""
|
||||
# print(db_id,'111111111111')
|
||||
find = public.M('databases').where("id=?" ,db_id).find()
|
||||
# return find
|
||||
if not find: return False
|
||||
# print(find)
|
||||
data = {
|
||||
'db_host':'127.0.0.1',
|
||||
'db_port':5432,
|
||||
'db_user':find['username'],
|
||||
'db_password':find['password']
|
||||
}
|
||||
|
||||
if int(find['sid']):
|
||||
conn_config = public.M('database_servers').where("id=?" ,find['sid']).find()
|
||||
|
||||
data['db_host'] = conn_config['db_host']
|
||||
data['db_port'] = int(conn_config['db_port'])
|
||||
return data
|
||||
|
||||
def get_database_size_by_id(self,args):
|
||||
"""
|
||||
@获取数据库尺寸(批量删除验证)
|
||||
@args json/int 数据库id
|
||||
"""
|
||||
total = 0
|
||||
db_id = args
|
||||
if not isinstance(args,int): db_id = args['db_id']
|
||||
|
||||
try:
|
||||
name = public.M('databases').where('id=?',db_id).getField('name')
|
||||
sql_obj = self.get_sql_obj(name)
|
||||
tables = sql_obj.query("select name,size,type from sys.master_files where type=0 and name = '{}'".format(name))
|
||||
|
||||
total = tables[0][1]
|
||||
if not total: total = 0
|
||||
except :pass
|
||||
|
||||
return total
|
||||
|
||||
def check_del_data(self,args):
|
||||
"""
|
||||
@删除数据库前置检测
|
||||
"""
|
||||
return self.check_base_del_data(args)
|
||||
|
||||
#本地创建数据库
|
||||
def __CreateUsers(self,data_name,username,password,address):
|
||||
"""
|
||||
@创建数据库用户
|
||||
"""
|
||||
sql_obj = self.get_sql_obj_by_sid(self.sid)
|
||||
sql_obj.execute("CREATE USER {} WITH PASSWORD '{}';".format(username,password))
|
||||
sql_obj.execute("GRANT ALL PRIVILEGES ON DATABASE {} TO {};".format(data_name,username))
|
||||
return True
|
||||
|
||||
|
||||
def __get_db_list(self,sql_obj):
|
||||
"""
|
||||
获取pgsql数据库列表
|
||||
"""
|
||||
data = []
|
||||
ret = sql_obj.query('SELECT datname FROM pg_database;')
|
||||
if type(ret) == list:
|
||||
for x in ret:
|
||||
data.append(x[0])
|
||||
return data
|
||||
|
||||
def check_cloud_database_status(self,conn_config):
|
||||
"""
|
||||
@检测远程数据库是否连接
|
||||
@conn_config 远程数据库配置,包含host port pwd等信息
|
||||
"""
|
||||
try:
|
||||
|
||||
if not 'db_name' in conn_config: conn_config['db_name'] = None
|
||||
sql_obj = panelPgsql().set_host(conn_config['db_host'],conn_config['db_port'],conn_config['db_name'],conn_config['db_user'],conn_config['db_password'])
|
||||
|
||||
data = sql_obj.query("SELECT datname FROM pg_database;")
|
||||
if type(data) == str:
|
||||
return public.returnMsg(False, public.lang("Connecting to remote PGSQL fails. Perform the following operations to rectify the fault:<br/>1、The database port is correct and the firewall allows access<br/>2、Check whether the database account password is correct<br/>3、pg_hba.confWhether to add a client release record<br/>4、postgresql.conf Add listen_addresses to the correct server IP address."))
|
||||
|
||||
if not conn_config['db_name']: return True
|
||||
for i in data:
|
||||
if i[0] == conn_config['db_name']:
|
||||
return True
|
||||
return public.returnMsg(False, public.lang("The specified database does not exist!"))
|
||||
except Exception as ex:
|
||||
|
||||
return public.returnMsg(False, public.lang(""))
|
||||
428
class/databaseModel/redisModel.py
Normal file
428
class/databaseModel/redisModel.py
Normal file
@@ -0,0 +1,428 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# YakPanel
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 YakPanel(www.yakpanel.com) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: hwliang <hwl@yakpanel.com>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
# sqlite模型
|
||||
#------------------------------
|
||||
import os,re,json,shutil,time
|
||||
from databaseModel.base import databaseBase
|
||||
import public
|
||||
try:
|
||||
import redis
|
||||
except:
|
||||
public.ExecShell("btpip install redis")
|
||||
import redis
|
||||
try:
|
||||
from YakPanel import session
|
||||
except :pass
|
||||
|
||||
|
||||
class panelRedisDB():
|
||||
|
||||
__DB_PASS = None
|
||||
__DB_USER = None
|
||||
__DB_PORT = 6379
|
||||
__DB_HOST = '127.0.0.1'
|
||||
__DB_CONN = None
|
||||
__DB_ERR = None
|
||||
|
||||
__DB_CLOUD = None
|
||||
def __init__(self):
|
||||
self.__config = self.get_options(None)
|
||||
|
||||
def redis_conn(self,db_idx = 0):
|
||||
|
||||
if self.__DB_HOST in ['127.0.0.1','localhost']:
|
||||
if not os.path.exists('/www/server/redis'): return False
|
||||
|
||||
if not self.__DB_CLOUD:
|
||||
self.__DB_PASS = self.__config['requirepass']
|
||||
self.__DB_PORT = int(self.__config['port'])
|
||||
|
||||
try:
|
||||
redis_pool = redis.ConnectionPool(host=self.__DB_HOST, port= self.__DB_PORT, password= self.__DB_PASS, db= db_idx)
|
||||
self.__DB_CONN = redis.Redis(connection_pool= redis_pool)
|
||||
return self.__DB_CONN
|
||||
except :
|
||||
self.__DB_ERR = public.get_error_info()
|
||||
return False
|
||||
|
||||
|
||||
def set_host(self,host,port,name,username,password,prefix = ''):
|
||||
self.__DB_HOST = host
|
||||
self.__DB_PORT = int(port)
|
||||
self.__DB_NAME = name
|
||||
if self.__DB_NAME: self.__DB_NAME = str(self.__DB_NAME)
|
||||
self.__DB_USER = str(username)
|
||||
self._USER = str(username)
|
||||
self.__DB_PASS = str(password)
|
||||
self.__DB_PREFIX = prefix
|
||||
self.__DB_CLOUD = 1
|
||||
return self
|
||||
|
||||
|
||||
#获取配置项
|
||||
def get_options(self,get = None):
|
||||
|
||||
result = {}
|
||||
redis_conf = public.readFile("{}/redis/redis.conf".format(public.get_setup_path()))
|
||||
if not redis_conf: return False
|
||||
|
||||
keys = ["bind","port","timeout","maxclients","databases","requirepass","maxmemory"]
|
||||
for k in keys:
|
||||
v = ""
|
||||
rep = "\n%s\\s+(.+)" % k
|
||||
group = re.search(rep,redis_conf)
|
||||
if not group:
|
||||
if k == "maxmemory":
|
||||
v = "0"
|
||||
if k == "maxclients":
|
||||
v = "10000"
|
||||
if k == "requirepass":
|
||||
v = ""
|
||||
else:
|
||||
if k == "maxmemory":
|
||||
v = int(group.group(1)) / 1024 / 1024
|
||||
else:
|
||||
v = group.group(1)
|
||||
result[k] = v
|
||||
return result
|
||||
|
||||
|
||||
|
||||
class main(databaseBase):
|
||||
|
||||
_db_max = 16 #最大redis数据库
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def GetCloudServer(self,args):
|
||||
'''
|
||||
@name 获取远程服务器列表
|
||||
@author hwliang<2021-01-10>
|
||||
@return list
|
||||
'''
|
||||
return self.GetBaseCloudServer(args)
|
||||
# return public.return_message(0, 0, self.GetBaseCloudServer(args))
|
||||
|
||||
|
||||
def AddCloudServer(self,args):
|
||||
'''
|
||||
@添加远程数据库
|
||||
'''
|
||||
return self.AddBaseCloudServer(args)
|
||||
|
||||
def RemoveCloudServer(self,args):
|
||||
'''
|
||||
@删除远程数据库
|
||||
'''
|
||||
return self.RemoveBaseCloudServer(args)
|
||||
|
||||
def ModifyCloudServer(self,args):
|
||||
'''
|
||||
@修改远程数据库
|
||||
'''
|
||||
return self.ModifyBaseCloudServer(args)
|
||||
|
||||
def get_obj_by_sid(self,sid = 0,conn_config = None):
|
||||
"""
|
||||
@取mssql数据库对像 By sid
|
||||
@sid 数据库分类,0:本地
|
||||
"""
|
||||
if type(sid) == str:
|
||||
try:
|
||||
sid = int(sid)
|
||||
except :sid = 0
|
||||
|
||||
if sid:
|
||||
if not conn_config: conn_config = public.M('database_servers').where("id=?" ,sid).find()
|
||||
db_obj = panelRedisDB()
|
||||
|
||||
try:
|
||||
db_obj = db_obj.set_host(conn_config['db_host'],conn_config['db_port'],None,conn_config['db_user'],conn_config['db_password'])
|
||||
except Exception as e:
|
||||
raise public.PanelError(e)
|
||||
else:
|
||||
db_obj = panelRedisDB()
|
||||
return db_obj
|
||||
|
||||
|
||||
|
||||
def get_list(self,args):
|
||||
"""
|
||||
@获取数据库列表
|
||||
@sql_type = redis
|
||||
"""
|
||||
result = []
|
||||
self.sid = args.get('sid/d',0)
|
||||
for x in range(0,self._db_max):
|
||||
|
||||
data = {}
|
||||
data['id'] = x
|
||||
data['name'] = 'DB{}'.format(x)
|
||||
|
||||
|
||||
try:
|
||||
redis_obj = self.get_obj_by_sid(self.sid).redis_conn(x)
|
||||
|
||||
data['keynum'] = redis_obj.dbsize()
|
||||
if data['keynum'] > 0:
|
||||
result.append(data)
|
||||
except :pass
|
||||
|
||||
#result = sorted(result,key= lambda x:x['keynum'],reverse=True)
|
||||
return result
|
||||
|
||||
|
||||
def set_redis_val(self,args):
|
||||
"""
|
||||
@设置或修改指定值
|
||||
"""
|
||||
|
||||
self.sid = args.get('sid/d',0)
|
||||
if not 'name' in args or not 'val' in args:
|
||||
return public.returnMsg(False, public.lang("Parameter passing error."));
|
||||
|
||||
endtime = 0
|
||||
if 'endtime' in args : endtime = int(args.endtime)
|
||||
|
||||
redis_obj = self.get_obj_by_sid(self.sid).redis_conn(args.db_idx)
|
||||
if endtime:
|
||||
redis_obj.set(args.name, args.val, endtime)
|
||||
else:
|
||||
redis_obj.set(args.name, args.val)
|
||||
public.set_module_logs('linux_redis','set_redis_val',1)
|
||||
return public.returnMsg(True, public.lang("Operation is successful."));
|
||||
|
||||
def del_redis_val(self,args):
|
||||
"""
|
||||
@删除key值
|
||||
"""
|
||||
self.sid = args.get('sid/d',0)
|
||||
if not 'key' in args:
|
||||
return public.returnMsg(False, public.lang("Parameter passing error."));
|
||||
|
||||
redis_obj = self.get_obj_by_sid(self.sid).redis_conn(args.db_idx)
|
||||
redis_obj.delete(args.key)
|
||||
|
||||
return public.returnMsg(True, public.lang("Operation is successful."));
|
||||
|
||||
|
||||
def clear_flushdb(self,args):
|
||||
"""
|
||||
清空数据库
|
||||
@ids 清空数据库列表,不传则清空所有
|
||||
"""
|
||||
self.sid = args.get('sid/d',0)
|
||||
ids = json.loads(args.ids)
|
||||
#ids = []
|
||||
if len(ids) == 0:
|
||||
for x in range(0,self._db_max):
|
||||
ids.append(x)
|
||||
|
||||
for x in ids:
|
||||
redis_obj = self.get_obj_by_sid(self.sid).redis_conn(x)
|
||||
redis_obj.flushdb()
|
||||
|
||||
return public.returnMsg(True, public.lang("Operation is successful."));
|
||||
|
||||
def get_db_keylist(self,args):
|
||||
"""
|
||||
@获取指定数据库key集合
|
||||
"""
|
||||
|
||||
search = '*'
|
||||
if 'search' in args: search = "*" + args.search+"*"
|
||||
db_idx = args.db_idx
|
||||
self.sid = args.get('sid/d',0)
|
||||
|
||||
redis_obj = self.get_obj_by_sid(self.sid).redis_conn(db_idx)
|
||||
try:
|
||||
keylist = sorted(redis_obj.keys(search))
|
||||
except :
|
||||
keylist = []
|
||||
|
||||
|
||||
info = {'p':1,'row':10,'count':len(keylist)}
|
||||
|
||||
if hasattr(args,'limit'): info['row'] = int(args.limit)
|
||||
if hasattr(args,'p'): info['p'] = int(args['p'])
|
||||
|
||||
import page
|
||||
#实例化分页类
|
||||
page = page.Page();
|
||||
|
||||
info['uri'] = args
|
||||
info['return_js'] = ''
|
||||
if hasattr(args,'tojs'): info['return_js'] = args.tojs
|
||||
|
||||
slist = keylist[(info['p']-1) * info['row']:info['p'] * info['row']]
|
||||
|
||||
rdata = {}
|
||||
rdata['page'] = page.GetPage(info,'1,2,3,4,5,8')
|
||||
rdata['where'] = ''
|
||||
rdata['data'] = []
|
||||
|
||||
idx = 0
|
||||
for key in slist:
|
||||
item = {}
|
||||
try:
|
||||
item['name'] = key.decode()
|
||||
except:
|
||||
item['name'] = str(key)
|
||||
|
||||
item['endtime'] = redis_obj.ttl(key)
|
||||
if item['endtime'] == -1: item['endtime'] = 0
|
||||
|
||||
item['type'] = redis_obj.type(key).decode()
|
||||
|
||||
if item['type'] == 'string':
|
||||
try:
|
||||
item['val'] = redis_obj.get(key).decode()
|
||||
except:
|
||||
item['val'] = str(redis_obj.get(key))
|
||||
elif item['type'] == 'hash':
|
||||
item['val'] = str(redis_obj.hgetall(key))
|
||||
elif item['type'] == 'list':
|
||||
item['val'] = str(redis_obj.lrange(key, 0, -1))
|
||||
elif item['type'] == 'set':
|
||||
item['val'] = str(redis_obj.smembers(key))
|
||||
elif item['type'] == 'zset':
|
||||
item['val'] = str(redis_obj.zrange(key, 0, 1, withscores=True))
|
||||
else:
|
||||
item['val'] = ''
|
||||
try:
|
||||
item['len'] = redis_obj.strlen(key)
|
||||
except:
|
||||
item['len'] = len(item['val'])
|
||||
item['val'] = public.xsssec(item['val'])
|
||||
item['name'] = public.xsssec(item['name'])
|
||||
rdata['data'].append(item)
|
||||
idx += 1
|
||||
return rdata
|
||||
|
||||
|
||||
def ToBackup(self,args):
|
||||
"""
|
||||
@备份数据库
|
||||
"""
|
||||
|
||||
self.sid = args.get('sid/d',0)
|
||||
|
||||
redis_obj = self.get_obj_by_sid(self.sid).redis_conn(0)
|
||||
redis_obj.save()
|
||||
|
||||
src_path = '{}/dump.rdb'.format(redis_obj.config_get()['dir'])
|
||||
if not os.path.exists(src_path):
|
||||
return public.returnMsg(False, public.lang("Backup error"));
|
||||
|
||||
backup_path = session['config']['backup_path'] + '/database/redis/'
|
||||
if not os.path.exists(backup_path): os.makedirs(backup_path)
|
||||
|
||||
fileName = backup_path + str(self.sid) + '_db_' + time.strftime('%Y%m%d_%H%M%S',time.localtime()) +'.rdb'
|
||||
|
||||
shutil.copyfile(src_path,fileName)
|
||||
if not os.path.exists(fileName):
|
||||
return public.returnMsg(False, public.lang("Backup error"));
|
||||
|
||||
return public.returnMsg(True, public.lang("Backup Succeeded!"))
|
||||
|
||||
def DelBackup(self,args):
|
||||
"""
|
||||
@删除备份文件
|
||||
"""
|
||||
file = args.file
|
||||
if os.path.exists(file): os.remove(file)
|
||||
|
||||
return public.returnMsg(True, public.lang("Delete successfully!"));
|
||||
|
||||
def InputSql(self,get):
|
||||
"""
|
||||
@导入数据库
|
||||
"""
|
||||
file = get.file
|
||||
self.sid = get.get('sid/d',0)
|
||||
|
||||
redis_obj = self.get_obj_by_sid(self.sid).redis_conn(0)
|
||||
|
||||
rpath = redis_obj.config_get()['dir']
|
||||
dst_path = '{}/dump.rdb'.format(rpath)
|
||||
public.ExecShell("/etc/init.d/redis stop")
|
||||
if os.path.exists(dst_path): os.remove(dst_path)
|
||||
shutil.copy2(file, dst_path)
|
||||
public.ExecShell("chown redis.redis {dump} && chmod 644 {dump}".format(dump=dst_path))
|
||||
# self.restart_services()
|
||||
public.ExecShell("/etc/init.d/redis start")
|
||||
if os.path.exists(dst_path):
|
||||
return public.returnMsg(True, public.lang("Restore Successful."))
|
||||
return public.returnMsg(False, public.lang("Restore failure."))
|
||||
|
||||
|
||||
def get_backup_list(self,get):
|
||||
"""
|
||||
@获取备份文件列表
|
||||
"""
|
||||
search = ''
|
||||
if hasattr(get,'search'): search = get['search'].strip().lower();
|
||||
|
||||
|
||||
nlist = []
|
||||
cloud_list = {}
|
||||
for x in self.GetCloudServer({'type':'redis'}):
|
||||
cloud_list['id-' + str(x['id'])] = x
|
||||
|
||||
path = session['config']['backup_path'] + '/database/redis/'
|
||||
if not os.path.exists(path): os.makedirs(path)
|
||||
for name in os.listdir(path):
|
||||
if search:
|
||||
if name.lower().find(search) == -1: continue;
|
||||
|
||||
arrs = name.split('_')
|
||||
|
||||
filepath = '{}/{}'.format(path,name).replace('//','/')
|
||||
stat = os.stat(filepath)
|
||||
|
||||
item = {}
|
||||
item['name'] = name
|
||||
item['filepath'] = filepath
|
||||
item['size'] = stat.st_size
|
||||
item['mtime'] = int(stat.st_mtime)
|
||||
item['sid'] = arrs[0]
|
||||
item['conn_config'] = cloud_list['id-' + str(arrs[0])]
|
||||
|
||||
nlist.append(item)
|
||||
if hasattr(get, 'sort'):
|
||||
nlist = sorted(nlist, key=lambda data: data['mtime'], reverse=get["sort"] == "desc")
|
||||
return nlist
|
||||
|
||||
|
||||
|
||||
def restart_services(self):
|
||||
"""
|
||||
@重启服务
|
||||
"""
|
||||
public.ExecShell('net stop redis')
|
||||
public.ExecShell('net start redis')
|
||||
return True
|
||||
|
||||
|
||||
def check_cloud_database_status(self,conn_config):
|
||||
"""
|
||||
@检测远程数据库是否连接
|
||||
@conn_config 远程数据库配置,包含host port pwd等信息
|
||||
"""
|
||||
try:
|
||||
|
||||
sql_obj = panelRedisDB().set_host(conn_config['db_host'],conn_config['db_port'],conn_config['db_name'],conn_config['db_user'],conn_config['db_password'])
|
||||
keynum = sql_obj.redis_conn(0).dbsize()
|
||||
return True
|
||||
except Exception as ex:
|
||||
|
||||
return public.returnMsg(False,ex)
|
||||
22
class/databaseModel/sqliteModel.py
Normal file
22
class/databaseModel/sqliteModel.py
Normal file
@@ -0,0 +1,22 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# YakPanel
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 YakPanel(www.yakpanel.com) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: hwliang <hwl@yakpanel.com>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# sqlite模型
|
||||
#------------------------------
|
||||
import os,sys,re,json,shutil,psutil,time
|
||||
from databaseModel.base import databaseBase
|
||||
import public
|
||||
|
||||
|
||||
class main(databaseBase):
|
||||
|
||||
def get_list(self,args):
|
||||
|
||||
return []
|
||||
498
class/databaseModel/sqlserverModel.py
Normal file
498
class/databaseModel/sqlserverModel.py
Normal file
@@ -0,0 +1,498 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# YakPanel
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 YakPanel(www.yakpanel.com) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: hwliang <hwl@yakpanel.com>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# sqlite模型
|
||||
#------------------------------
|
||||
import os,re,json,time
|
||||
from databaseModel.base import databaseBase
|
||||
import public,panelMssql
|
||||
try:
|
||||
from YakPanel import session
|
||||
except :pass
|
||||
|
||||
|
||||
class main(databaseBase):
|
||||
|
||||
def get_list(self,args):
|
||||
"""
|
||||
@获取数据库列表
|
||||
@sql_type = sqlserver
|
||||
"""
|
||||
return self.get_base_list(args, sql_type = 'sqlserver')
|
||||
|
||||
|
||||
def get_mssql_obj_by_sid(self,sid = 0,conn_config = None):
|
||||
"""
|
||||
@取mssql数据库对像 By sid
|
||||
@sid 数据库分类,0:本地
|
||||
"""
|
||||
if type(sid) == str:
|
||||
try:
|
||||
sid = int(sid)
|
||||
except :sid = 0
|
||||
|
||||
if sid:
|
||||
if not conn_config: conn_config = public.M('database_servers').where("id=?" ,sid).find()
|
||||
db_obj = panelMssql.panelMssql()
|
||||
|
||||
try:
|
||||
db_obj = db_obj.set_host(conn_config['db_host'],conn_config['db_port'],None,conn_config['db_user'],conn_config['db_password'])
|
||||
except Exception as e:
|
||||
raise public.PanelError(e)
|
||||
else:
|
||||
db_obj = panelMssql.panelMssql()
|
||||
return db_obj
|
||||
|
||||
def get_mssql_obj(self,db_name):
|
||||
"""
|
||||
@取mssql数据库对象
|
||||
@db_name 数据库名称
|
||||
"""
|
||||
is_cloud_db = False
|
||||
if db_name:
|
||||
db_find = public.M('databases').where("name=?" ,db_name).find()
|
||||
if db_find['sid']:
|
||||
return self.get_mssql_obj_by_sid(db_find['sid'])
|
||||
is_cloud_db = db_find['db_type'] in ['1',1]
|
||||
|
||||
if is_cloud_db:
|
||||
|
||||
db_obj = panelMssql.panelMssql()
|
||||
conn_config = json.loads(db_find['conn_config'])
|
||||
try:
|
||||
db_obj = db_obj.set_host(conn_config['db_host'],conn_config['db_port'],conn_config['db_name'],conn_config['db_user'],conn_config['db_password'])
|
||||
except Exception as e:
|
||||
raise public.PanelError(e)
|
||||
else:
|
||||
db_obj = panelMssql.panelMssql()
|
||||
return db_obj
|
||||
|
||||
def GetCloudServer(self,args):
|
||||
'''
|
||||
@name 获取远程服务器列表
|
||||
@author hwliang<2021-01-10>
|
||||
@return list
|
||||
'''
|
||||
return self.GetBaseCloudServer(args)
|
||||
|
||||
|
||||
def AddCloudServer(self,args):
|
||||
'''
|
||||
@添加远程数据库
|
||||
'''
|
||||
|
||||
|
||||
return self.AddBaseCloudServer(args)
|
||||
|
||||
def RemoveCloudServer(self,args):
|
||||
'''
|
||||
@删除远程数据库
|
||||
'''
|
||||
return self.RemoveBaseCloudServer(args)
|
||||
|
||||
def ModifyCloudServer(self,args):
|
||||
'''
|
||||
@修改远程数据库
|
||||
'''
|
||||
return self.ModifyBaseCloudServer(args)
|
||||
|
||||
def AddDatabase(self,args):
|
||||
"""
|
||||
@添加数据库
|
||||
|
||||
"""
|
||||
res = self.add_base_database(args)
|
||||
if not res['status']:
|
||||
return res
|
||||
|
||||
data_name = res['data_name']
|
||||
username = res['username']
|
||||
password = res['data_pwd']
|
||||
|
||||
if re.match(r"^\d+",data_name):
|
||||
return public.returnMsg(False, public.lang("SQLServer databases cannot start with numbers!"))
|
||||
|
||||
reg_count = 0
|
||||
regs = ['[a-z]','[A-Z]',r'\W','[0-9]']
|
||||
for x in regs:
|
||||
if re.search(x,password): reg_count += 1
|
||||
|
||||
if len(password) < 8 or len(password) >128 or reg_count < 3 :
|
||||
return public.returnMsg(False, public.lang("SQLServer password complexity policy does not match, should be 8-128 characters, and contain any 3 of them in upper case, lower case, digits, special symbols!"))
|
||||
|
||||
try:
|
||||
self.sid = int(args['sid'])
|
||||
except :
|
||||
self.sid = 0
|
||||
|
||||
dtype = 'SQLServer'
|
||||
#添加SQLServer
|
||||
mssql_obj = self.get_mssql_obj_by_sid(self.sid)
|
||||
result = mssql_obj.execute("CREATE DATABASE %s" % data_name)
|
||||
isError = self.IsSqlError(result)
|
||||
if isError != None: return isError
|
||||
|
||||
mssql_obj.execute("DROP LOGIN %s" % username)
|
||||
|
||||
#添加用户
|
||||
self.__CreateUsers(data_name,username,password,'127.0.0.1')
|
||||
|
||||
if not hasattr(args,'ps'): args['ps'] = public.getMsg('INPUT_PS');
|
||||
addTime = time.strftime('%Y-%m-%d %X',time.localtime())
|
||||
|
||||
pid = 0
|
||||
if hasattr(args,'pid'): pid = args.pid
|
||||
|
||||
if hasattr(args,'contact'):
|
||||
site = public.M('sites').where("id=?",(args.contact,)).field('id,name').find()
|
||||
if site:
|
||||
pid = int(args.contact)
|
||||
args['ps'] = site['name']
|
||||
|
||||
db_type = 0
|
||||
if self.sid: db_type = 2
|
||||
|
||||
public.set_module_logs('linux_sqlserver','AddDatabase',1)
|
||||
#添加入SQLITE
|
||||
public.M('databases').add('pid,sid,db_type,name,username,password,accept,ps,addtime,type',(pid,self.sid,db_type,data_name,username,password,'127.0.0.1',args['ps'],addTime,dtype))
|
||||
public.WriteLog("TYPE_DATABASE", 'DATABASE_ADD_SUCCESS',(data_name,))
|
||||
return public.returnMsg(True, public.lang("Added successfully!"))
|
||||
|
||||
def DeleteDatabase(self,args):
|
||||
"""
|
||||
@删除数据库
|
||||
"""
|
||||
|
||||
id = args['id']
|
||||
find = public.M('databases').where("id=?",(id,)).field('id,pid,name,username,password,type,accept,ps,addtime,sid,db_type').find();
|
||||
if not find: return public.returnMsg(False, public.lang("The specified database does not exist."))
|
||||
|
||||
name = args['name']
|
||||
username = find['username'];
|
||||
|
||||
mssql_obj = self.get_mssql_obj_by_sid(find['sid'])
|
||||
mssql_obj.execute("ALTER DATABASE %s SET SINGLE_USER with ROLLBACK IMMEDIATE" % name)
|
||||
result = mssql_obj.execute("DROP DATABASE %s" % name)
|
||||
|
||||
if self.get_database_size_by_id(find['sid']):
|
||||
isError = self.IsSqlError(result)
|
||||
if isError != None: return isError
|
||||
|
||||
mssql_obj.execute("DROP LOGIN %s" % username)
|
||||
|
||||
#删除SQLITE
|
||||
public.M('databases').where("id=?",(id,)).delete()
|
||||
public.WriteLog("TYPE_DATABASE", 'DATABASE_DEL_SUCCESS',(name,))
|
||||
return public.returnMsg(True, public.lang("Delete successfully!"))
|
||||
|
||||
|
||||
|
||||
def ToBackup(self,args):
|
||||
"""
|
||||
@备份数据库 id 数据库id
|
||||
"""
|
||||
id = args['id']
|
||||
find = public.M('databases').where("id=?",(id,)).find()
|
||||
if not find: return public.returnMsg(False, public.lang("Database does not exist!"))
|
||||
|
||||
self.CheckBackupPath(args);
|
||||
|
||||
fileName = find['name'] + '_' + time.strftime('%Y%m%d_%H%M%S',time.localtime()) + '.bak'
|
||||
backupName = session['config']['backup_path'] + '/database/sqlserver/' + fileName
|
||||
|
||||
mssql_obj = self.get_mssql_obj_by_sid(find['sid'])
|
||||
|
||||
if not int(find['sid']):
|
||||
ret = mssql_obj.execute("backup database %s To disk='%s'" % (find['name'],backupName))
|
||||
isError=self.IsSqlError(ret)
|
||||
if isError != None: return isError
|
||||
else:
|
||||
#远程数据库
|
||||
return public.returnMsg(False, public.lang("Operation failed. Remote database cannot be backed up."));
|
||||
|
||||
if not os.path.exists(backupName):
|
||||
return public.returnMsg(False, public.lang("Backup error"));
|
||||
|
||||
public.M('backup').add('type,name,pid,filename,size,addtime',(1,fileName,id,backupName,0,time.strftime('%Y-%m-%d %X',time.localtime())))
|
||||
public.WriteLog("TYPE_DATABASE", "DATABASE_BACKUP_SUCCESS",(find['name'],))
|
||||
|
||||
if os.path.getsize(backupName) < 2048:
|
||||
return public.returnMsg(True, public.lang("The backup file size is smaller than 2Kb. Check the backup integrity."))
|
||||
else:
|
||||
return public.returnMsg(True, public.lang("Backup Succeeded!"))
|
||||
|
||||
def DelBackup(self,args):
|
||||
"""
|
||||
@删除备份文件
|
||||
"""
|
||||
return self.delete_base_backup(args)
|
||||
|
||||
|
||||
#导入
|
||||
def InputSql(self,get):
|
||||
|
||||
name = get.name
|
||||
file = get.file
|
||||
|
||||
find = public.M('databases').where("name=?",(name,)).find()
|
||||
if not find: return public.returnMsg(False, public.lang("Database does not exist!"))
|
||||
|
||||
tmp = file.split('.')
|
||||
exts = ['sql','zip','bak']
|
||||
ext = tmp[len(tmp) -1]
|
||||
if ext not in exts:
|
||||
return public.returnMsg(False, public.lang("Select sql、gz、zip file!"))
|
||||
|
||||
backupPath = session['config']['backup_path'] + '/database'
|
||||
|
||||
if ext == 'zip':
|
||||
try:
|
||||
fname = os.path.basename(file).replace('.zip','')
|
||||
dst_path = backupPath + '/' +fname
|
||||
if not os.path.exists(dst_path): os.makedirs(dst_path)
|
||||
|
||||
public.unzip(file,dst_path)
|
||||
for x in os.listdir(dst_path):
|
||||
if x.find('bak') >= 0 or x.find('sql') >= 0:
|
||||
file = dst_path + '/' + x
|
||||
break
|
||||
except :
|
||||
return public.returnMsg(False, public.lang("The import failed because the file is not a valid ZIP file."))
|
||||
|
||||
mssql_obj = self.get_mssql_obj_by_sid(find['sid'])
|
||||
data = mssql_obj.query("use %s ;select filename from sysfiles" % find['name'])
|
||||
|
||||
isError = self.IsSqlError(data)
|
||||
if isError != None: return isError
|
||||
if type(data) == str: return public.returnMsg(False,data)
|
||||
|
||||
mssql_obj.execute("ALTER DATABASE %s SET OFFLINE WITH ROLLBACK IMMEDIATE" % (find['name']))
|
||||
mssql_obj.execute("use master;restore database %s from disk='%s' with replace, MOVE N'%s' TO N'%s',MOVE N'%s_Log' TO N'%s' " % (find['name'],file,find['name'],data[0][0],find['name'],data[1][0]))
|
||||
mssql_obj.execute("ALTER DATABASE %s SET ONLINE" % (find['name']))
|
||||
|
||||
public.WriteLog("TYPE_DATABASE", 'Description Succeeded in importing database [{}]'.format(name))
|
||||
return public.returnMsg(True, public.lang("Successfully imported database!"));
|
||||
|
||||
|
||||
#同步数据库到服务器
|
||||
def SyncToDatabases(self,get):
|
||||
type = int(get['type'])
|
||||
n = 0
|
||||
sql = public.M('databases')
|
||||
if type == 0:
|
||||
data = sql.field('id,name,username,password,accept,type,sid,db_type').where('type=?',('SQLServer',)).select()
|
||||
|
||||
for value in data:
|
||||
if value['db_type'] in ['1',1]:
|
||||
continue # 跳过远程数据库
|
||||
result = self.ToDataBase(value)
|
||||
if result == 1: n +=1
|
||||
else:
|
||||
import json
|
||||
data = json.loads(get.ids)
|
||||
for value in data:
|
||||
find = sql.where("id=?",(value,)).field('id,name,username,password,sid,db_type,accept,type').find()
|
||||
result = self.ToDataBase(find)
|
||||
if result == 1: n +=1
|
||||
|
||||
if n == 1:
|
||||
return public.returnMsg(True, public.lang("Synchronization succeeded"))
|
||||
elif n == 0:
|
||||
return public.returnMsg(False, public.lang("Sync failed"))
|
||||
|
||||
return public.returnMsg(True,'Database sync success',(str(n),))
|
||||
|
||||
#添加到服务器
|
||||
def ToDataBase(self,find):
|
||||
if find['username'] == 'bt_default': return 0
|
||||
if len(find['password']) < 3 :
|
||||
find['username'] = find['name']
|
||||
find['password'] = public.md5(str(time.time()) + find['name'])[0:10]
|
||||
public.M('databases').where("id=?",(find['id'],)).save('password,username',(find['password'],find['username']))
|
||||
|
||||
self.sid = find['sid']
|
||||
mssql_obj = self.get_mssql_obj_by_sid(self.sid)
|
||||
result = mssql_obj.execute("CREATE DATABASE %s" % find['name'])
|
||||
isError = self.IsSqlError(result)
|
||||
if isError != None and not 'already exists' in result: return -1
|
||||
|
||||
self.__CreateUsers(find['name'],find['username'],find['password'],'127.0.0.1')
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
#从服务器获取数据库
|
||||
def SyncGetDatabases(self,get):
|
||||
|
||||
n = 0;s = 0;
|
||||
db_type = 0
|
||||
self.sid = get.get('sid/d',0)
|
||||
if self.sid: db_type = 2
|
||||
|
||||
mssql_obj = self.get_mssql_obj_by_sid(self.sid)
|
||||
|
||||
data = mssql_obj.query('SELECT name FROM MASTER.DBO.SYSDATABASES ORDER BY name')
|
||||
isError = self.IsSqlError(data)
|
||||
if isError != None: return isError
|
||||
if type(data) == str: return public.returnMsg(False,data)
|
||||
|
||||
sql = public.M('databases')
|
||||
nameArr = ['information_schema','performance_schema','mysql','sys','master','model','msdb','tempdb','ReportServerTempDB','YueMiao','ReportServer']
|
||||
for item in data:
|
||||
dbname = item[0]
|
||||
if sql.where("name=?",(dbname,)).count(): continue
|
||||
if not dbname in nameArr:
|
||||
if sql.table('databases').add('name,username,password,accept,ps,addtime,type,sid,db_type',(dbname,dbname,'','',public.getMsg('INPUT_PS'),time.strftime('%Y-%m-%d %X',time.localtime()),'SQLServer',self.sid,db_type)): n +=1
|
||||
|
||||
return public.returnMsg(True,'Database success',(str(n),))
|
||||
|
||||
def ResDatabasePassword(self,args):
|
||||
"""
|
||||
@修改用户密码
|
||||
"""
|
||||
id = args['id']
|
||||
username = args['name'].strip()
|
||||
newpassword = public.trim(args['password'])
|
||||
|
||||
try:
|
||||
if not newpassword:
|
||||
return public.returnMsg(False, public.lang("The password of database [' + username + '] cannot be empty."));
|
||||
if len(re.search(r"^[\w@\.]+$", newpassword).groups()) > 0:
|
||||
return public.returnMsg(False, public.lang("The database password cannot be empty or contain special characters"))
|
||||
except :
|
||||
return public.returnMsg(False, public.lang("The database password cannot be empty or contain special characters"))
|
||||
|
||||
find = public.M('databases').where("id=?",(id,)).field('id,pid,name,username,password,type,accept,ps,addtime,sid').find();
|
||||
if not find: return public.returnMsg(False, public.lang("Modify the failure,The specified database does not exist."));
|
||||
|
||||
mssql_obj = self.get_mssql_obj_by_sid(find['sid'])
|
||||
mssql_obj.execute("EXEC sp_password NULL, '%s', '%s'" % (newpassword,username))
|
||||
|
||||
#修改SQLITE
|
||||
public.M('databases').where("id=?",(id,)).setField('password',newpassword)
|
||||
|
||||
public.WriteLog("TYPE_DATABASE",'Database password success',(find['name'],))
|
||||
return public.returnMsg(True,'Database password success',(find['name'],))
|
||||
|
||||
|
||||
def get_root_pwd(self,args):
|
||||
"""
|
||||
@获取sa密码
|
||||
"""
|
||||
mssql_obj = panelMssql.panelMssql()
|
||||
ret = mssql_obj.get_sql_name()
|
||||
if not ret : return public.returnMsg(False, public.lang("The SQL Server is not installed or started. Install or start it first"))
|
||||
|
||||
sa_path = '{}/data/sa.pl'.format(public.get_panel_path())
|
||||
if os.path.exists(sa_path):
|
||||
password = public.readFile(sa_path)
|
||||
return public.returnMsg(True,password)
|
||||
return public.returnMsg(True, public.lang(""))
|
||||
|
||||
|
||||
def set_root_pwd(self,args):
|
||||
"""
|
||||
@设置sa密码
|
||||
"""
|
||||
password = public.trim(args['password'])
|
||||
try:
|
||||
if not password:
|
||||
return public.returnMsg(False, public.lang("The password of database [' + username + '] cannot be empty."))
|
||||
if len(re.search(r"^[\w@\.]+$", password).groups()) > 0:
|
||||
return public.returnMsg(False, public.lang("saThe password cannot be empty or have special symbols"))
|
||||
except :
|
||||
return public.returnMsg(False, public.lang("saThe password cannot be empty or have special symbols"))
|
||||
|
||||
mssql_obj = panelMssql.panelMssql()
|
||||
result = mssql_obj.execute("EXEC sp_password NULL, '%s', 'sa'" % password)
|
||||
|
||||
isError = self.IsSqlError(result)
|
||||
if isError != None: return isError
|
||||
|
||||
public.writeFile('data/sa.pl',password)
|
||||
session['config']['mssql_sa'] = password
|
||||
return public.returnMsg(True, public.lang("The password of sa is changed successfully."))
|
||||
|
||||
|
||||
|
||||
def get_database_size_by_id(self,args):
|
||||
"""
|
||||
@获取数据库尺寸(批量删除验证)
|
||||
@args json/int 数据库id
|
||||
"""
|
||||
total = 0
|
||||
db_id = args
|
||||
if not isinstance(args,int): db_id = args['db_id']
|
||||
|
||||
try:
|
||||
name = public.M('databases').where('id=?',db_id).getField('name')
|
||||
mssql_obj = self.get_mssql_obj(name)
|
||||
tables = mssql_obj.query("select name,size,type from sys.master_files where type=0 and name = '{}'".format(name))
|
||||
|
||||
total = tables[0][1]
|
||||
if not total: total = 0
|
||||
except :pass
|
||||
|
||||
return total
|
||||
|
||||
def check_del_data(self,args):
|
||||
"""
|
||||
@删除数据库前置检测
|
||||
"""
|
||||
return self.check_base_del_data(args)
|
||||
|
||||
#本地创建数据库
|
||||
def __CreateUsers(self,data_name,username,password,address):
|
||||
"""
|
||||
@创建数据库用户
|
||||
"""
|
||||
mssql_obj = self.get_mssql_obj_by_sid(self.sid)
|
||||
mssql_obj.execute("use %s create login %s with password ='%s' , default_database = %s" % (data_name,username,password,data_name))
|
||||
mssql_obj.execute("use %s create user %s for login %s with default_schema=dbo" % (data_name,username,username))
|
||||
mssql_obj.execute("use %s exec sp_addrolemember 'db_owner','%s'" % (data_name,data_name))
|
||||
mssql_obj.execute("ALTER DATABASE %s SET MULTI_USER" % data_name)
|
||||
|
||||
|
||||
#检测备份目录并赋值权限(MSSQL需要Authenticated Users)
|
||||
def CheckBackupPath(self,get):
|
||||
backupFile = session['config']['backup_path'] + '/database/sqlserver'
|
||||
if not os.path.exists(backupFile):
|
||||
os.makedirs(backupFile)
|
||||
get.filename = backupFile
|
||||
get.user = 'Authenticated Users'
|
||||
get.access = 2032127
|
||||
import files
|
||||
files.files().SetFileAccess(get)
|
||||
|
||||
def check_cloud_database_status(self,conn_config):
|
||||
"""
|
||||
@检测远程数据库是否连接
|
||||
@conn_config 远程数据库配置,包含host port pwd等信息
|
||||
"""
|
||||
try:
|
||||
|
||||
import panelMssql
|
||||
if not 'db_name' in conn_config: conn_config['db_name'] = None
|
||||
sql_obj = panelMssql.panelMssql().set_host(conn_config['db_host'],conn_config['db_port'],conn_config['db_name'],conn_config['db_user'],conn_config['db_password'])
|
||||
data = sql_obj.query("SELECT name FROM MASTER.DBO.SYSDATABASES ORDER BY name")
|
||||
|
||||
isError = self.IsSqlError(data)
|
||||
if isError != None: return isError
|
||||
if type(data) == str:
|
||||
return public.returnMsg(False,data)
|
||||
|
||||
if not conn_config['db_name']: return True
|
||||
for i in data:
|
||||
if i[0] == conn_config['db_name']:
|
||||
return True
|
||||
return public.returnMsg(False, public.lang("The specified database does not exist!"))
|
||||
except Exception as ex:
|
||||
|
||||
return public.returnMsg(False,ex)
|
||||
Reference in New Issue
Block a user