diff --git a/web/admin/site/dir.py b/web/admin/site/dir.py
index 6156e71de..5cc7d15a7 100644
--- a/web/admin/site/dir.py
+++ b/web/admin/site/dir.py
@@ -15,8 +15,6 @@ from flask import Blueprint, render_template
from flask import request
from admin.user_login_check import panel_login_required
-
-from utils.plugin import plugin as MwPlugin
from utils.site import sites as MwSites
import core.mw as mw
@@ -74,10 +72,3 @@ def del_dir_bind():
return MwSites.instance().delDirBinding(binding_id)
-
-
-
-
-
-
-
diff --git a/web/admin/site/site.py b/web/admin/site/site.py
index 2fe533c98..051d0f9bd 100644
--- a/web/admin/site/site.py
+++ b/web/admin/site/site.py
@@ -53,6 +53,25 @@ def add():
port = request.form.get('port', '')
return MwSites.instance().add(webname, port, ps, path, version)
+# 添加站点 - 域名
+@blueprint.route('/add_domain', endpoint='add_domain',methods=['POST'])
+@panel_login_required
+def add_domain():
+ domain = request.form.get('domain', '')
+ site_name = request.form.get('site_name', '')
+ site_id = request.form.get('id', '')
+ return MwSites.instance().addDomain(site_id, site_name, domain)
+
+# 删除站点 - 域名
+@blueprint.route('/del_domain', endpoint='del_domain',methods=['POST'])
+@panel_login_required
+def del_domain():
+ site_name = request.form.get('site_name', '')
+ site_id = request.form.get('id', '')
+ domain = request.form.get('domain', '')
+ port = request.form.get('port', '')
+ return MwSites.instance().delDomain(site_id, site_name, domain, port)
+
# 站点删除
@blueprint.route('/delete', endpoint='delete',methods=['POST'])
@panel_login_required
diff --git a/web/static/app/site.js b/web/static/app/site.js
index 11e432136..50c8eeb13 100755
--- a/web/static/app/site.js
+++ b/web/static/app/site.js
@@ -691,7 +691,7 @@ function checkDomain() {
* @param {Int} id 网站ID
* @param {String} webname 主域名
*/
-function domainAdd(id, webname,type) {
+function domainAdd(id, webname, type) {
var Domain = $("#newdomain").val().split("\n");
var domainlist = '';
@@ -706,7 +706,7 @@ function domainAdd(id, webname,type) {
domainlist = domainlist.substring(0,domainlist.length-1);
var loadT = layer.load();
- var data = "domain=" + domainlist + "&webname=" + webname + "&id=" + id;
+ var data = "domain=" + domainlist + "&site_name=" + webname + "&id=" + id;
$.post('/site/add_domain', data, function(retuls) {
layer.close(loadT);
domainEdit(id, webname, retuls.msg, retuls.status);
@@ -726,10 +726,9 @@ function delDomain(wid, wname, domain, port,type) {
layer.msg(lan.site.domain_last_cannot);
}
layer.confirm(lan.site.domain_del_confirm,{icon:3,closeBtn:2}, function(index) {
- var url = "/site/del_domain"
- var data = "id=" + wid + "&webname=" + wname + "&domain=" + domain + "&port=" + port;
- var loadT = layer.msg(lan.public.the_del,{time:0,icon:16});
- $.post(url,data, function(ret) {
+ var data = "id=" + wid + "&site_name=" + wname + "&domain=" + domain + "&port=" + port;
+ var loadT = layer.msg('您真的要从站点中删除这个域名吗?',{time:0,icon:16});
+ $.post('/site/del_domain', data, function(ret) {
layer.close(loadT);
layer.msg(ret.msg,{icon:ret.status?1:2})
if(type == 1){
@@ -2039,7 +2038,6 @@ function renewSSL(type,id,siteName){
function renderDnsapiHtml(data){
-
var fields = data.data;
var fields_html = '';
diff --git a/web/thisdb/domain.py b/web/thisdb/domain.py
index bdf3e47d2..e78995cfb 100644
--- a/web/thisdb/domain.py
+++ b/web/thisdb/domain.py
@@ -16,6 +16,10 @@ def getDomainCountByName(name):
# .debug(True)
return mw.M('domain').where("name=?", (name,)).count()
+def getDomainCountBySiteId(site_id):
+ # .debug(True)
+ return mw.M('domain').where("pid=?", (site_id,)).count()
+
def addDomain(pid, name, port):
now_time = mw.getDateFromNow()
insert_data = {
diff --git a/web/thisdb/sites.py b/web/thisdb/sites.py
index 487b54897..20c316012 100644
--- a/web/thisdb/sites.py
+++ b/web/thisdb/sites.py
@@ -14,10 +14,19 @@ from .option import getOption
__FIELD = 'id,name,path,status,ps,edate,type_id,add_time,update_time'
+def checkSitesDomainIsExist(domain, port):
+ nums = mw.M('domain').where("name=? AND port=?", (domain, port,)).count()
+ if nums>0:
+ return True
+
+ nums = mw.M('binding').where("name=? AND port=?", (domain, port,)).count()
+ if nums>0:
+ return True
+ return False
+
def getSitesCount():
return mw.M('sites').count()
-
def getSitesById(site_id):
return mw.M('sites').field(__FIELD).where("id=?", (site_id,)).find()
diff --git a/web/utils/site.py b/web/utils/site.py
index 2fb0df438..501a28f66 100644
--- a/web/utils/site.py
+++ b/web/utils/site.py
@@ -62,6 +62,25 @@ class sites(object):
if not os.path.exists(self.sslLetsDir):
mw.execShell("mkdir -p " + self.sslLetsDir +" && chmod -R 755 " + self.sslLetsDir)
+
+ def runHook(self, hook_name, func_name):
+ # 站点操作Hook
+ hook_cfg = thisdb.getOptionByJson('hook_site_cb',type='hook',default=[])
+ hook_num = len(hook_cfg)
+ if hook_num == 0:
+ return
+
+ from utils.plugin import plugin as MwPlugin
+ pa = MwPlugin.instance()
+
+ for x in range(hook_num):
+ hook_data = hook_cfg[x]
+ if func_name in hook_data:
+ app_name = hook_data["name"]
+ run_func = hook_data[func_name]['func']
+ pa.run(app_name, run_func)
+ return True
+
# 域名编码转换
def toPunycode(self, domain):
if sys.version_info[0] == 2:
@@ -198,6 +217,99 @@ class sites(object):
# return mw.returnData(False, '开发中!')
return mw.returnData(True, '添加成功')
+ def nginxAddDomain(self, site_name, domain, port):
+ file = self.getHostConf(site_name)
+ conf = mw.readFile(file)
+ if not conf:
+ return
+
+ # 添加域名
+ rep = r"server_name\s*(.*);"
+ tmp = re.search(rep, conf).group()
+ domains = tmp.split(' ')
+ if not mw.inArray(domains, domain):
+ newServerName = tmp.replace(';', ' ' + domain + ';')
+ conf = conf.replace(tmp, newServerName)
+
+ # 添加端口
+ rep = r"listen\s+([0-9]+)\s*[default_server]*\s*;"
+ tmp = re.findall(rep, conf)
+ if not mw.inArray(tmp, port):
+ listen = re.search(rep, conf).group()
+ conf = conf.replace(
+ listen, listen + "\n\tlisten " + port + ';')
+ # 保存配置文件
+ mw.writeFile(file, conf)
+ return True
+
+ def addDomain(self, site_id, site_name, domain):
+ isError = mw.checkWebConfig()
+ if isError != True:
+ msg = 'ERROR: 检测到配置文件有错误,请先排除后再操作
' + isError.replace("\n", '
') + ''
+ return mw.returnData(False, msg)
+
+ domains = domain.split(',')
+ for d in domains:
+ if d == '':
+ continue
+ d = d.split(':')
+ name = self.toPunycode(d[0])
+ port = '80'
+ if len(d) == 2:
+ port = d[1]
+
+ if not mw.checkPort(port):
+ return mw.returnData(False, '端口范围不合法!')
+
+ reg = r"^([\w\-\*]{1,100}\.){1,4}([\w\-]{1,24}|[\w\-]{1,24}\.[\w\-]{1,24})$"
+ if not re.match(reg, name):
+ return mw.returnData(False, '域名格式不正确!')
+
+ if thisdb.checkSitesDomainIsExist(name, port):
+ return mw.returnData(False, '您添加的域名[{}:{}],已使用。请仔细检查!'.format(name, port))
+
+ self.nginxAddDomain(site_name, name, port)
+
+ msg = mw.getInfo('网站[{1}]添加域名[{2}]成功!', (site_name, name))
+ mw.writeLog('网站管理', msg)
+ thisdb.addDomain(site_id, name, port)
+
+ mw.restartWeb()
+ self.runHook('site_cb', 'add')
+ return mw.returnData(True, '域名添加成功!')
+
+ def delDomain(self, site_id, site_name, domain, port):
+ domain_nums = thisdb.getDomainCountBySiteId(site_id)
+ if domain_nums == 1:
+ return mw.returnData(False, '最后一个域名不能删除!')
+
+ info = mw.M('domain').field('id,name').where("pid=? AND name=? AND port=?",(site_id, domain, port)).find()
+
+ file = self.getHostConf(site_name)
+ conf = mw.readFile(file)
+ if conf:
+ # 删除域名
+ rep = r"server_name\s+(.+);"
+ tmp = re.search(rep, conf).group()
+ newServerName = tmp.replace(' ' + domain + ';', ';')
+ newServerName = newServerName.replace(' ' + domain + ' ', ' ')
+ conf = conf.replace(tmp, newServerName)
+
+ # 删除端口
+ rep = r"listen\s+([0-9]+);"
+ tmp = re.findall(rep, conf)
+ port_nums = mw.M('domain').where('pid=? AND port=?', (site_id, port)).count()
+ if mw.inArray(tmp, port) == True and port_nums < 2:
+ rep = r"\n*\s+listen\s+" + port + ";"
+ conf = re.sub(rep, '', conf)
+ # 保存配置
+ mw.writeFile(file, conf)
+
+ thisdb.deleteDomainId(info['id'])
+ msg = mw.getInfo('网站[{1}]删除域名[{2}:{3}]成功!', (site_name, domain, port))
+ mw.writeLog('网站管理', msg)
+ mw.restartWeb()
+ return mw.returnData(True, '站点删除成功!')
def deleteALlLogs(self, webname):
assLogPath = mw.getLogsDir() + '/' + webname + '.log'
@@ -1687,6 +1799,15 @@ location ^~ {from} {\n\
mw.restartWeb()
return mw.returnData(True, '证书已更新!', result)
+ def getDnsapiExportVar(self, data):
+ def_var = ''
+ for k in data:
+ def_var += 'export '+k+'="'+data[k]+'"\n'
+ return def_var
+
+ def getDomainRootName(self, domain):
+ pass
+
def createAcmeDns(self, site_name, domains, force, renew, dnspai):
dnsapi_option = thisdb.getOptionByJson('dnsapi', default={})
if not dnspai in dnsapi_option:
@@ -1697,9 +1818,15 @@ location ^~ {from} {\n\
if dnsapi_data[k] == '':
return mw.returnData(False, k+'为空!')
+ cmd = self.getDnsapiExportVar(dnsapi_data)
+
+ for d in domains:
+ print(d)
+ cmd += 'acme.sh --issue --dns '+str(dnspai)+' -d '+d+' -d "*.'+d+'" --force'
print(dnsapi_data)
print(domains)
+ print(cmd)
return mw.returnData(False, '测试中!')
def createAcme(self, site_name, domains,force,renew, apply_type, dnspai, email):