Files
yakpanel-core/class/databaseModel/redisModel.py

429 lines
13 KiB
Python
Raw Normal View History

2026-04-07 02:04:22 +05:30
#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)