#coding: utf-8 # +------------------------------------------------------------------- # | YakPanel # +------------------------------------------------------------------- # | Copyright (c) 2015-2020 YakPanel(https://www.yakpanel.com) All rights reserved. # +------------------------------------------------------------------- # | Author: 沐落 # | Author: lx # +------------------------------------------------------------------- import sys,os,time,psutil,re panelPath = "/www/server/panel" os.chdir(panelPath) sys.path.insert(0, "class/") import public,time,panelPush,public try: from YakPanel import cache except : from cachelib import SimpleCache cache = SimpleCache() class panel_push: __push = None pids = None def __init__(self): self.__push = panelPush.panelPush() #-----------------------------------------------------------start 添加推送 ------------------------------------------------------ def get_version_info(self,get): """ 获取版本信息 """ data = {} data['ps'] = '' data['version'] = '1.2' data['date'] = '2022-09-20' data['author'] = 'YakPanel' data['help'] = 'https://www.yakpanel.com/forum' return data #名取PID def getPid(self,pname): try: if not self.pids: self.pids = psutil.pids() for pid in self.pids: if psutil.Process(pid).name() == pname: return True return False except: return True #检测指定进程是否存活 def checkProcess(self,pid): try: if not self.pids: self.pids = psutil.pids() if int(pid) in self.pids: return True return False except: return False #检查是否启动 def check_run(self,name): if name == "php-fpm": status = False base_path = "/www/server/php" if not os.path.exists(base_path): return status for p in os.listdir(base_path): pid_file = os.path.join(base_path, p, "var/run/php-fpm.pid") if os.path.exists(pid_file): php_pid = int(public.readFile(pid_file)) status = self.checkProcess(php_pid) if status: return status return status elif name == 'nginx': status = False if os.path.exists('/etc/init.d/nginx'): pidf = '/www/server/nginx/logs/nginx.pid' if os.path.exists(pidf): try: pid = public.readFile(pidf) status = self.checkProcess(pid) except: pass return status elif name == 'apache': status = False if os.path.exists('/etc/init.d/httpd'): pidf = '/www/server/apache/logs/httpd.pid' if os.path.exists(pidf): pid = public.readFile(pidf) status = self.checkProcess(pid) return status elif name == 'mysql': res = public.ExecShell("service mysqld status") if res and not re.search(r"not\s+running", res[0]): return True return False elif name == 'tomcat': status = False if os.path.exists('/www/server/tomcat/logs/catalina-daemon.pid'): if self.getPid('jsvc'): status = True if not status: if self.getPid('java'): status = True return status elif name == 'pure-ftpd': pidf = '/var/run/pure-ftpd.pid' status = False if os.path.exists(pidf): pid = public.readFile(pidf) status = self.checkProcess(pid) return status elif name == 'redis': status = False pidf = '/www/server/redis/redis.pid' if os.path.exists(pidf): pid = public.readFile(pidf) status = self.checkProcess(pid) return status elif name == 'memcached': status = False pidf = '/var/run/memcached.pid' if os.path.exists(pidf): pid = public.readFile(pidf) status = self.checkProcess(pid) return status return True def get_server_status(self, server_name): status = self.check_run(server_name) if status: return 1 return 0 """ @获取推送模块配置 """ def get_module_config(self,get): data = [] item = self.__push.format_push_data(push = ["mail",'dingding','weixin',"feishu"],project = 'ssl',type = 'ssl') item['cycle'] = 30 item['title'] = 'SSL到期提醒' item['helps'] = ['SSL到期提醒一天只发送一次','证书夹内【剩余天数不足30天】的所有证书.'] data.append(item) item = self.__push.format_push_data(push = ["mail",'dingding','weixin',"feishu"],project = 'endtime',type = 'endtime') item['cycle'] = 5 item['title'] = '专业版/企业版到期提醒' item['helps'] = [''] data.append(item) services = ['nginx','apache',"pure-ftpd",'mysql','php-fpm','memcached','redis'] channels = ['mail', 'dingding','weixin','sms',"feishu"] for x in services: item = {} item['project'] = x item['title'] = '{}服务停止通知'.format(x) if x == 'other': item['title'] = '自定义服务停止通知' else: ser_name = self.__get_service_name(x) if self.get_server_status(ser_name) == -1: continue item['type'] = 'services' item['keys'] = [] item['interval'] = 300 for x in ['stop']: item['keys'].append({'key':x,'val':'停止'}) item['push'] = channels item['helps'] = ['部分服务停止可能会造成业务中断.','短信推送需提前购买,如需帮助请联系 [YakPanel 社区]'] data.append(item) import json public.writeFile('data/push/config/panel_push.json',json.dumps(data)) return data def get_push_cycle(self,data): """ @获取执行周期 """ result = {} for skey in data: result[skey] = data[skey] m_cycle =[] m_type = data[skey]['type'] if m_type in ['endtime','ssl']: m_cycle.append('剩余{}天时,每天1次'.format(data[skey]['cycle'])) elif m_type in ['services']: m_cycle.append('服务停止时,每{}秒1次'.format(data[skey]['interval'])) if len(m_cycle) > 0: result[skey]['m_cycle'] = ''.join(m_cycle) return result #-----------------------------------------------------------end 添加推送 ------------------------------------------------------ """ @获取服务真实名称 """ def __get_service_name(self,name): slist = {"FTP服务端":'pure-ftpd'} if name in slist: name = slist[name] return name """ @获取推送栏目 """ def get_total(self): return True; def get_push_data(self,data,total): if data['type'] == 'services': ser_name = data['project'] ser_name = self.__get_service_name(ser_name) status = self.get_server_status(ser_name) if status > 0: return public.returnMsg(False, public.lang("状态正常,跳过.")) else: if status == 0: return self.__get_service_result(data) return public.returnMsg(False, public.lang("服务未安装,跳过.")) elif data['type'] in ['ssl']: if time.time() < data['index'] + 86400: return public.returnMsg(False, public.lang("一天推送一次,跳过.")) import panelSSL ssl = panelSSL.panelSSL() clist = [] for x in ssl.GetCertList(None): timeArray = time.strptime(x['notAfter'], "%Y-%m-%d") endtime = time.mktime(timeArray) day = int((endtime - time.time()) / 86400) if day > data['cycle']: continue clist.append(x) return self.__get_ssl_result(data,clist) elif data['type'] in ['endtime']: if time.time() < data['index'] + 86400: return public.returnMsg(False, public.lang("一天推送一次,跳过.")) from pluginAuth import Plugin softs = Plugin(False).get_plugin_list(True) if softs['pro'] == 0: return public.returnMsg(False, public.lang("永久专业版,跳过.")) if softs['ltd'] == -2 and softs['pro'] == -2: pass else: pro_data = {} if softs['ltd'] > 0: pro_data['endtime'] = softs['ltd'] pro_data['name'] = "Linux企业版" pro_data['affect'] = '全部企业版插件' elif softs['pro'] > 0: pro_data['endtime'] = softs['pro'] pro_data['name'] = "Linux专业版" pro_data['affect'] = '全部专业版插件' pro_data['day'] = int((pro_data['endtime'] - time.time()) / 86400) if pro_data['day'] <= data['cycle']: return self.__get_ltd_result(data,pro_data) return public.returnMsg(False, public.lang("未达到阈值,跳过.")) """ @企业版到期提醒 """ def __get_ltd_result(self,data,pro_data): result = {'index':time.time()} for m_module in data['module'].split(','): result[m_module] = self.__push.format_msg_data() newline = "" if m_module in ['dingding','weixin',"feishu","mail"]: if m_module in ["mail"]: newline="
" result[m_module]["title"] = "YakPanel 业务到期提醒" else: newline = "\n\n" result[m_module]['msg'] = "".join(( "#### YakPanel 业务到期提醒"+newline, ">服务器 :"+ public.GetLocalIp() + newline, ">剩余天数:"+ str(pro_data['day'] + 1) +" 天"+newline, ">到期产品:"+ pro_data['name'] +newline, ">到期时间:"+ public.format_date(times =pro_data['endtime']) +newline, ">影响业务:"+ pro_data['affect'] +newline, ">通知时间:" + public.format_date() + newline)) return result """ @ssl到期返回 """ def __get_ssl_result(self,data,clist): if len(clist) == 0: return public.returnMsg(False, public.lang("未找到到期证书,跳过.")) result = {'index':time.time() } for m_module in data['module'].split(','): result[m_module] = self.__push.format_msg_data() newline = "" if m_module in ['dingding','weixin',"feishu","mail"]: if m_module in ["mail"]: newline="
" result[m_module]["title"] = "YakPanel SSL到期提醒" else: newline = "\n\n" p_msg = ""; for x in clist: p_msg+= " 到期:{} 域名:{}".format(x['notAfter'],x['subject']) + newline result[m_module]['msg'] ="".join(( "#### YakPanel SSL到期提醒" + newline, ">服务器 :"+ public.GetLocalIp() +newline, ">检测时间:" + public.format_date() +newline, ">About to expire: "+ str(len(clist)) +" "+newline, p_msg)) return result """ @服务停止返回 """ def __get_service_result(self,data): s_idx = int(time.time()) if s_idx < data['index'] + data['interval']: return public.returnMsg(False, public.lang("The interval is not reached, skip.")) result = {'index':s_idx} for m_module in data['module'].split(','): result[m_module] = self.__push.format_msg_data() newline = "" if m_module in ['dingding','weixin',"feishu","mail"]: if m_module in ["mail"]: newline="
" result[m_module]["title"] = "堡塔服务停止告警" else: newline = "\n\n" result[m_module]['msg'] = "".join(( "#### 堡塔服务停止告警" + newline, ">服务器 :"+ public.GetLocalIp() +newline + " ", ">Type of service: "+ data["project"] +newline + " ", ">Service state: 已停止"+newline+" ", ">检测时间:"+ public.format_date())) elif m_module in ['sms']: result[m_module]['sm_type'] = 'servcies' result[m_module]['sm_args'] = { 'name':'{}'.format(public.GetConfigValue('title')), 'product':data["project"],'product1':data["project"]} return result