pull/632/head
Mr Chen 6 months ago
parent 98fbaa099f
commit 4c1e2a206d
  1. 10
      web/admin/site/ssl.py
  2. 4
      web/admin/site/ssl_acme.py
  3. 116
      web/static/app/site.js
  4. 103
      web/utils/site.py

@ -39,12 +39,20 @@ def get_cert_list():
return MwSites.instance().getCertList()
# 获取证书配置
# 获取DNSAPI
@blueprint.route('/get_dnsapi', endpoint='get_dnsapi', methods=['GET','POST'])
@panel_login_required
def get_dnsapi():
return MwSites.instance().getDnsapi()
# 设置DNSAPI
@blueprint.route('/set_dnsapi', endpoint='set_dnsapi', methods=['GET','POST'])
@panel_login_required
def set_dnsapi():
type = request.form.get('type', '')
data = request.form.get('data')
return MwSites.instance().setDnsapi(type,data)

@ -42,7 +42,9 @@ def create_acme():
force = request.form.get('force', '')
renew = request.form.get('renew', '')
email = request.form.get('email', '')
return MwSites.instance().createAcme(site_name, domains,force,renew,email)
apply_type = request.form.get('apply_type', 'file')
dnspai = request.form.get('dnspai','')
return MwSites.instance().createAcme(site_name, domains,force,renew,apply_type,dnspai, email)

@ -2036,16 +2036,20 @@ function renewSSL(type,id,siteName){
});
}
function fileCheck(){
$('#dnsapi_option').css('display','none');
}
function dnsCheck(){
$('#dnsapi_option').css('display','block');
}
function renderDnsapiHtml(data){
console.log(data);
var fields = data.data;
var fields_html = '';
for (var d in fields) {
fields_html += "<span class='tname'>"+d+"</span>\
<div class='info-r'>\
<input name='"+d+"' class='bt-input-text mr5' style='width:100%;' value='"+fields[d]+"' type='text'>\
</div>";
}
layer.open({
type: 1,
area: '500px',
@ -2058,20 +2062,13 @@ function renderDnsapiHtml(data){
<div class='line'>\
<span class='tname'>DNSAPI类型</span>\
<div class='info-r'>\
<select class='bt-input-text mr5' name='type' style='width:100%;'>\
<select class='bt-input-text mr5' name='type_name' style='width:100%;'>\
<option name='cf'>"+data['name']+"</option>\
</select>\
</div>\
</div>\
<div class='line' id='dnsapi_option'>\
<span class='tname'>CF_Key</span>\
<div class='info-r'>\
<input name='v1' class='bt-input-text mr5' style='width:100%;' placeholder='请输入对应值' type='text'>\
</div>\
<span class='tname'>CF_Email</span>\
<div class='info-r'>\
<input name='v2' class='bt-input-text mr5' style='width:100%;' placeholder='请输入对应值' type='text'>\
</div>\
"+fields_html+"\
</div>\
<div class='line'>\
<div>\
@ -2081,17 +2078,29 @@ function renderDnsapiHtml(data){
</div>\
</div>\
</form>",
success:function(){
},
yes:function(index) {
yes:function(index,l) {
var type_name = $('select[name="type_name"]').val();
var data_field = {};
for (var d in fields) {
data_field[d] = $('input[name="'+d+'"]').val();
}
$.post('/site/set_dnsapi', {'type':type_name,'data':JSON.stringify(data_field)}, function(rdata){
showMsg(rdata.msg, function(){
if (rdata.status){
layer.close(index);
renderDnsapi();
}
},{icon:rdata.status?1:2});
},'json');
}
});
}
function renderDnsapi(){
$('#dnsapi_set').css('display', 'none');
$.post('/site/get_dnsapi', {}, function(data){
var dnsapi_option = '';
for (var i = 0; i < data.length; i++) {
@ -2099,7 +2108,6 @@ function renderDnsapi(){
}
$('#dnsapi_option select').html(dnsapi_option);
$('#dnsapi_option select').on('change',function(){
var val = $(this).val();
var index = $('#dnsapi_option option:selected').attr('index');
@ -2107,8 +2115,10 @@ function renderDnsapi(){
$('#dnsapi_option button').css('display','none');
} else {
$('#dnsapi_option button').css('display','inline-block');
if (!(data[index]['title'].indexOf('[')>0)){
renderDnsapiHtml(data[index]);
}
}
renderDnsapiHtml(data[index]);
});
$('#dnsapi_set').on('click', function(){
@ -2124,21 +2134,27 @@ function opSSLAcme(type, id, siteName, callback){
<div class="line mtb10">\
<span class="tname text-center">验证方式</span>\
<div style="margin-top:7px;display:inline-block">\
<input type="radio" name="dns_type" onclick="fileCheck()" id="check_file" checked="checked"/>\
<input type="radio" name="apply_type" value="file" id="check_file" checked="checked"/>\
<label class="mr20" for="check_file" style="font-weight:normal">文件验证</label></label>\
<input type="radio" name="dns_type" onclick="dnsCheck()" id="check_dns"/>\
<input type="radio" name="apply_type" value="dns" id="check_dns"/>\
<label class="mr20" for="check_dns" style="font-weight:normal">DNS验证</label></label>\
</div>\
</div>\
<div class="line mtb10" id="dnsapi_option" style="display:none;">\
<span class="tname text-center"></span>\
<span class="tname text-center" style="line-height: 42px;">选择DNS接口</span>\
<div style="margin-top:7px;display:inline-block">\
<select class="bt-input-text mr20">\
<select name="dnspai" class="bt-input-text mr20">\
<option value="none">手动解析</option>\
</select>\
<button id="dnsapi_set" class="btn btn-default btn-sm btn-title" style="display:none;">配置</button>\
</div>\
</div>\
<div class="check_message line" id="wildcard_domain_block" style="display:none;">\
<div style="margin-left:100px">\
<input type="checkbox" name="wildcard_domain" id="wildcard_domain" checked="checked">\
<label class="mr20" for="wildcard_domain" style="font-weight:normal">自动组合泛域名</label>\
</div>\
</div>\
<div class="check_message line">\
<div style="margin-left:100px">\
<input type="checkbox" name="checkDomain" id="checkDomain" checked="">\
@ -2167,6 +2183,18 @@ function opSSLAcme(type, id, siteName, callback){
$(".tab-con").html(acme);
$('input[name="apply_type"]').on('change', function(){
var val = $(this).val();
if (val == 'file'){
$('#dnsapi_option').css('display','none');
$('#wildcard_domain_block').css('display','none');
} else {
$('#dnsapi_option').css('display','block');
$('#wildcard_domain_block').css('display','block');
}
});
renderDnsapi();
$.post('/site/get_ssl','site_name='+siteName+'&ssl_type=acme', function(data){
@ -2346,7 +2374,7 @@ function opSSLLet(type, id, siteName, callback){
</div>\
</div>\
<div class="line mtb10">\
<span class="tname text-center">管理员邮箱</span>\
<span class="tname text-center">邮箱</span>\
<input class="bt-input-text" style="width:240px;" type="text" name="admin_email" />\
</div>\
<div class="line mtb10">\
@ -2512,19 +2540,31 @@ function newSSL(siteName, id, domains){
function newAcmeSSL(siteName, id, domains){
showSpeedWindow('正在由ACME申请...', 'site.get_acme_logs', function(layers,index){
var force = '';
var email = $("input[name='admin_email']").val();
var apply_type = $('input[name="apply_type"]:checked').val();
var pdata = {};
pdata['siteName'] = siteName;
pdata['domains'] = domains;
pdata['email'] = email;
pdata['apply_type'] = apply_type;
if($("#checkDomain").prop("checked")){
force = '&force=true';
pdata['force'] = 'true';
}
var email = $("input[name='admin_email']").val();
$.post('/site/create_acme','siteName='+siteName+'&domains='+domains+'&email='+email + force,function(rdata){
layer.close(index);
if(rdata.status){
showMsg(rdata.msg, function(){
if (apply_type == 'dns'){
pdata['dnspai'] = $('#dnsapi_option option:selected').val();
}
console.log(pdata);
$.post('/site/create_acme',pdata,function(rdata){
console.log(rdata);
showMsg(rdata.msg, function(){
layer.close(index);
if(rdata.status){
$(".tab-nav span:first-child").click();
},{icon:1}, 2000);
return;
}
layer.msg(rdata.msg,{icon:2,area:'500px',time:0,shade:0.3,shadeClose:true});
}
},{icon:rdata.status?1:2}, 3000);
},'json');
});
}

@ -1490,34 +1490,34 @@ location ^~ {from} {\n\
{"name":"dns_cf", "title":'cloudflare', 'key':'CF_Key:CF_Email'},
{"name":"dns_dp", "title":'dnspod/国内', 'key':'DP_Id:DP_Key'},
{"name":"dns_dpi", "title":'dnspod/国际', 'key':'DPI_Id:DPI_Key'},
{"name":"dns_gd", "title":'GoDaddy', 'key':'GD_Key:GD_Secret'},
{"name":"dns_pdns", "title":'PowerDNS', 'key':'PDNS_Url:PDNS_ServerId:PDNS_Token:PDNS_Ttl'},
{"name":"dns_lua", "title":'LuaDNS', 'key':'LUA_Key:LUA_Email'},
{"name":"dns_me", "title":'DNSMadeEasy', 'key':'ME_Key:ME_Secret'},
{"name":"dns_aws", "title":'Amazon Route53', 'key':'AWS_ACCESS_KEY_ID:AWS_SECRET_ACCESS_KEY'},
{"name":"dns_ispconfig", "title":'ISPConfig', 'key':'ISPC_User:ISPC_Password:ISPC_Api:ISPC_Api_Insecure'},
{"name":"dns_ad", "title":'Alwaysdata', 'key':'AD_API_KEY'},
{"name":"dns_linode_v4", "title":'Linode', 'key':'LINODE_V4_API_KEY'},
{"name":"dns_freedns", "title":'FreeDNS', 'key':'FREEDNS_User:FREEDNS_Password'},
{"name":"dns_cyon", "title":'cyon.ch', 'key':'CY_Username:CY_Password:CY_OTP_Secret'},
{"name":"dns_gandi_livedns", "title":'LiveDNS', 'key':'GANDI_LIVEDNS_TOKEN'},
{"name":"dns_knot", "title":'Knot', 'key':'KNOT_SERVER:KNOT_KEY'},
{"name":"dns_dgon", "title":'DigitalOcean', 'key':'DO_API_KEY'},
{"name":"dns_cloudns", "title":'ClouDNS.net', 'key':'CLOUDNS_SUB_AUTH_ID:CLOUDNS_AUTH_PASSWORD'},
{"name":"dns_namesilo", "title":'Namesilo', 'key':'Namesilo_Key'},
{"name":"dns_azure", "title":'Azure', 'key':'AZUREDNS_SUBSCRIPTIONID:AZUREDNS_TENANTID:AZUREDNS_APPID:AZUREDNS_CLIENTSECRET'},
{"name":"dns_selectel", "title":'selectel.com', 'key':'SL_Key'},
{"name":"dns_zonomi", "title":'zonomi.com', 'key':'ZM_Key'},
{"name":"dns_kinghost", "title":'KingHost', 'key':'KINGHOST_Username:KINGHOST_Password'},
{"name":"dns_zilore", "title":'Zilore', 'key':'Zilore_Key'},
{"name":"dns_gcloud", "title":'Google Cloud DNS', 'key':'CLOUDSDK_ACTIVE_CONFIG_NAME'},
{"name":"dns_mydnsjp", "title":'MyDNS.JP', 'key':'MYDNSJP_MasterID:MYDNSJP_Password'},
{"name":"dns_doapi", "title":'do.de', 'key':'DO_LETOKEN'},
{"name":"dns_online", "title":'Online', 'key':'ONLINE_API_KEY'},
{"name":"dns_cn", "title":'Core-Networks', 'key':'CN_User:CN_Password'},
{"name":"dns_ultra", "title":'UltraDNS', 'key':'ULTRA_USR:ULTRA_PWD'},
{"name":"dns_hetzner", "title":'Hetzner', 'key':'HETZNER_Token'},
{"name":"dns_ddnss", "title":'DDNSS.de', 'key':'DDNSS_Token'},
# {"name":"dns_gd", "title":'GoDaddy', 'key':'GD_Key:GD_Secret'},
# {"name":"dns_pdns", "title":'PowerDNS', 'key':'PDNS_Url:PDNS_ServerId:PDNS_Token:PDNS_Ttl'},
# {"name":"dns_lua", "title":'LuaDNS', 'key':'LUA_Key:LUA_Email'},
# {"name":"dns_me", "title":'DNSMadeEasy', 'key':'ME_Key:ME_Secret'},
# {"name":"dns_aws", "title":'Amazon Route53', 'key':'AWS_ACCESS_KEY_ID:AWS_SECRET_ACCESS_KEY'},
# {"name":"dns_ispconfig", "title":'ISPConfig', 'key':'ISPC_User:ISPC_Password:ISPC_Api:ISPC_Api_Insecure'},
# {"name":"dns_ad", "title":'Alwaysdata', 'key':'AD_API_KEY'},
# {"name":"dns_linode_v4", "title":'Linode', 'key':'LINODE_V4_API_KEY'},
# {"name":"dns_freedns", "title":'FreeDNS', 'key':'FREEDNS_User:FREEDNS_Password'},
# {"name":"dns_cyon", "title":'cyon.ch', 'key':'CY_Username:CY_Password:CY_OTP_Secret'},
# {"name":"dns_gandi_livedns", "title":'LiveDNS', 'key':'GANDI_LIVEDNS_TOKEN'},
# {"name":"dns_knot", "title":'Knot', 'key':'KNOT_SERVER:KNOT_KEY'},
# {"name":"dns_dgon", "title":'DigitalOcean', 'key':'DO_API_KEY'},
# {"name":"dns_cloudns", "title":'ClouDNS.net', 'key':'CLOUDNS_SUB_AUTH_ID:CLOUDNS_AUTH_PASSWORD'},
# {"name":"dns_namesilo", "title":'Namesilo', 'key':'Namesilo_Key'},
# {"name":"dns_azure", "title":'Azure', 'key':'AZUREDNS_SUBSCRIPTIONID:AZUREDNS_TENANTID:AZUREDNS_APPID:AZUREDNS_CLIENTSECRET'},
# {"name":"dns_selectel", "title":'selectel.com', 'key':'SL_Key'},
# {"name":"dns_zonomi", "title":'zonomi.com', 'key':'ZM_Key'},
# {"name":"dns_kinghost", "title":'KingHost', 'key':'KINGHOST_Username:KINGHOST_Password'},
# {"name":"dns_zilore", "title":'Zilore', 'key':'Zilore_Key'},
# {"name":"dns_gcloud", "title":'Google Cloud DNS', 'key':'CLOUDSDK_ACTIVE_CONFIG_NAME'},
# {"name":"dns_mydnsjp", "title":'MyDNS.JP', 'key':'MYDNSJP_MasterID:MYDNSJP_Password'},
# {"name":"dns_doapi", "title":'do.de', 'key':'DO_LETOKEN'},
# {"name":"dns_online", "title":'Online', 'key':'ONLINE_API_KEY'},
# {"name":"dns_cn", "title":'Core-Networks', 'key':'CN_User:CN_Password'},
# {"name":"dns_ultra", "title":'UltraDNS', 'key':'ULTRA_USR:ULTRA_PWD'},
# {"name":"dns_hetzner", "title":'Hetzner', 'key':'HETZNER_Token'},
# {"name":"dns_ddnss", "title":'DDNSS.de', 'key':'DDNSS_Token'},
];
for i in range(len(dnsapi_option)):
@ -1538,17 +1538,39 @@ location ^~ {from} {\n\
dnsapi_option[i]['data'] = t
return dnsapi_option
def createAcme(self, site_name, domains, force, renew, input_email):
domains = json.loads(domains)
def setDnsapi(self, type, data):
dnsapi_data = thisdb.getOptionByJson('dnsapi', default={})
dnsapi_data[type] = json.loads(data)
thisdb.setOption('dnsapi',json.dumps(dnsapi_data))
return mw.returnData(True, '设置成功!')
def acmeLogFile(self):
return mw.getPanelDir() + '/logs/acme.log'
def writeAcmeLog(self,msg):
log_file = self.acmeLogFile()
mw.writeFile(log_file, msg+"\n", "wb+")
return True
def createAcmeMultiDomin(self):
pass
def createAcmeFile(self):
pass
print(site_name,domains,input_email,renew,force)
email = thisdb.getOption('ssl_email', default='')
if input_email.strip() != '':
thisdb.setOption('ssl_email', input_email)
email = input_email
def createAcmeDns(self):
pass
if not len(domains):
def createAcme(self, site_name, domains,force,renew, apply_type, dnspai, email):
domains = json.loads(domains)
if len(domains) < 1:
return mw.returnData(False, '请选择域名')
if email.strip() != '':
thisdb.setOption('ssl_email', email)
print(site_name, domains,force,renew,apply_type, dnspai, email)
file = self.getHostConf(site_name)
if os.path.exists(file):
@ -1622,11 +1644,12 @@ location ^~ {from} {\n\
if domainCount == 0:
return mw.returnData(False, '请选择域名(不包括IP地址与泛域名)!')
log_file = mw.getPanelDir() + '/logs/acme.log'
mw.writeFile(log_file, "开始ACME申请...\n", "wb+")
self.writeAcmeLog('开始ACME申请...')
log_file = self.acmeLogFile()
cmd = 'export ACCOUNT_EMAIL=' + email + ' && ' + execStr + ' >> ' + log_file
# print(domains)
# print(cmd)
print(domains)
print(cmd)
return mw.returnData(False, '测试中!')
result = mw.execShell(cmd)
src_path = mw.getAcmeDomainDir(domains[0])

Loading…
Cancel
Save