parent
10b6a4ec25
commit
2f1888f568
|
@ -246,19 +246,31 @@ class Admin::SitePanelController < OrbitAdminController
|
|||
SiteConstruct.find(params[:id]).destroy
|
||||
redirect_to :back and return
|
||||
elsif params[:type] == 'select_cert'
|
||||
if !params[:is_server]
|
||||
@site_construct = SiteConstruct.find(params[:id])
|
||||
@site_construct.update(:redirect_to_https=>params[:redirect_to_https])
|
||||
is_certbot = true
|
||||
if params[:site_cert_id] != "certbot"
|
||||
is_certbot = false
|
||||
@site_construct.update(:site_cert_id=>BSON::ObjectId(params[:site_cert_id]))
|
||||
is_certbot = true
|
||||
if params[:server_names]
|
||||
is_certbot = false
|
||||
Thread.new do
|
||||
last_idx = params[:server_names].count
|
||||
params[:server_names].each_with_index do |server_name, i|
|
||||
ss = SiteServer.where(:server_name=>server_name).first
|
||||
next if ss.nil?
|
||||
system("bundle exec rake create_site:change_site_cert[#{ss.id.to_s},#{is_certbot},true,#{params[:site_cert_id]},#{params[:redirect_to_https]}#{i == (last_idx -1) ? ',true' : ''}}]")
|
||||
end
|
||||
end
|
||||
else
|
||||
is_certbot = true
|
||||
end
|
||||
Thread.new do
|
||||
system("bundle exec rake create_site:change_site_cert[#{params[:id]},#{is_certbot},#{params[:is_server]}]")
|
||||
if !params[:is_server]
|
||||
@site_construct = SiteConstruct.find(params[:id])
|
||||
@site_construct.update(:redirect_to_https=>params[:redirect_to_https])
|
||||
if params[:site_cert_id] != "certbot"
|
||||
is_certbot = false
|
||||
@site_construct.update(:site_cert_id=>BSON::ObjectId(params[:site_cert_id]))
|
||||
end
|
||||
else
|
||||
is_certbot = true
|
||||
end
|
||||
Thread.new do
|
||||
system("bundle exec rake create_site:change_site_cert[#{params[:id]},#{is_certbot},#{params[:is_server]}]")
|
||||
end
|
||||
end
|
||||
else
|
||||
Thread.new do
|
||||
|
|
|
@ -82,12 +82,12 @@ class ClientManagementsController < CPanelController
|
|||
|
||||
def site_tickets
|
||||
if params[:category].present? && params[:keyword].present?
|
||||
regex = Regexp.new(".*" + params[:keyword] + ".*", "i")
|
||||
regex = ::Regexp.new(".*" + params[:keyword] + ".*", "i")
|
||||
@tickets = @site.tickets.where(:category_id => params[:category], :subject => regex).order_by([:status, :desc],[:created_at, :desc]).page(params[:page]).per(10)
|
||||
elsif params[:category].present?
|
||||
@tickets = @site.tickets.where(:category_id => params[:category]).order_by([:status, :desc],[:created_at, :desc]).page(params[:page]).per(10)
|
||||
elsif params[:keyword].present?
|
||||
regex = Regexp.new(".*" + params[:keyword] + ".*", "i")
|
||||
regex = ::Regexp.new(".*" + params[:keyword] + ".*", "i")
|
||||
@tickets = @site.tickets.where(:subject => regex).order_by([:status, :desc],[:created_at, :desc]).page(params[:page]).per(10)
|
||||
else
|
||||
@tickets = @site.tickets.order_by([:status, :desc],[:created_at, :desc]).page(params[:page]).per(10)
|
||||
|
|
|
@ -34,7 +34,7 @@ class SiteCert
|
|||
cert_file_md5 = `openssl x509 -noout -modulus -in #{self.cert_file.file.file} | openssl md5`
|
||||
private_key_md5 = `openssl rsa -noout -modulus -in #{self.private_key.file.file} | openssl md5`
|
||||
is_valid = (cert_file_md5 == private_key_md5)
|
||||
domain_names = `openssl x509 -text < #{self.cert_file.file.file} | grep 'DNS:' | sed 's/\s*DNS:\([a-z0-9.\-]*\)[,\s]\?/\1 /g'`.split('DNS:').map{|s| s.strip}.select{|s| s.present?} rescue []
|
||||
domain_names = `openssl x509 -text < #{self.cert_file.file.file} | grep 'DNS:' | sed 's/\s*DNS:\([a-z0-9.\-]*\)[,\s]\?/\1 /g'`.split('DNS:').map{|s| s.sub(',','').strip}.select{|s| s.present?} rescue []
|
||||
if domain_names.blank?
|
||||
self.is_valid = false
|
||||
@skip_callback = true
|
||||
|
@ -53,4 +53,13 @@ class SiteCert
|
|||
false
|
||||
end
|
||||
end
|
||||
def valid_domain_names(site_names)
|
||||
site_names = site_names.split(" ").map{|s| s.strip}
|
||||
valid_site_names = []
|
||||
self.domain_names.each do |d|
|
||||
regx = ::Regexp.new("\\A"+d.gsub('.',"\\.").gsub('*','[^\\.]+').sub(',','').strip)
|
||||
valid_site_names += site_names.select{|s| !(s.match(regx).nil?)}
|
||||
end
|
||||
return valid_site_names
|
||||
end
|
||||
end
|
|
@ -83,7 +83,7 @@ class SiteConstruct
|
|||
}.join('\n')
|
||||
end
|
||||
def match_exact_index(text,match_character,level=1)
|
||||
text.enum_for(:scan,/(?:[^#{match_character}])#{match_character}{#{level}}(?!#{match_character})/m).map { offset_index=Regexp.last_match.to_s.index(match_character);Regexp.last_match.offset(0).first + offset_index}
|
||||
text.enum_for(:scan,/(?:[^#{match_character}])#{match_character}{#{level}}(?!#{match_character})/m).map { offset_index=::Regexp.last_match.to_s.index(match_character);::Regexp.last_match.offset(0).first + offset_index}
|
||||
end
|
||||
def parse_nginx_text_to_server_blocks(nginx_text,get_all_blocks=false,level=1)
|
||||
num = 1
|
||||
|
@ -231,7 +231,7 @@ class SiteConstruct
|
|||
domain_names = domain_name.strip().split(" ")
|
||||
if default_domain_idx == -1
|
||||
site_server.default_domain_names.each do |default_domain_name|
|
||||
default_domain_name = Regexp.new("\\A"+default_domain_name.gsub(".","\\.").gsub("*","[^.]*"))
|
||||
default_domain_name = ::Regexp.new("\\A"+default_domain_name.gsub(".","\\.").gsub("*","[^.]*"))
|
||||
custom_default_domain_name = domain_names.select{|n| n.match(default_domain_name) }.first
|
||||
break if custom_default_domain_name.present?
|
||||
end
|
||||
|
|
|
@ -42,12 +42,12 @@ class SiteServer
|
|||
add_default_domains = self.default_domain_names - self.default_domain_names_was.to_a
|
||||
check_domains += removed_default_domains
|
||||
check_domains += add_default_domains
|
||||
check_domains = check_domains.map{|domain| Regexp.new("(\\A|\\s)"+domain.gsub(".","\\.").gsub("*","[^.]*") + "($|\\s)")}
|
||||
check_domains = check_domains.map{|domain| ::Regexp.new("(\\A|\\s)"+domain.gsub(".","\\.").gsub("*","[^.]*") + "($|\\s)")}
|
||||
tmp_site_constructs = tmp_site_constructs.where(:domain_name.in=>check_domains)
|
||||
need_change = true
|
||||
elsif need_change
|
||||
check_domains = self.default_domain_names
|
||||
check_domains = check_domains.map{|domain| Regexp.new("(\\A|\\s)"+domain.gsub(".","\\.").gsub("*","[^.]*") + "($|\\s)")}
|
||||
check_domains = check_domains.map{|domain| ::Regexp.new("(\\A|\\s)"+domain.gsub(".","\\.").gsub("*","[^.]*") + "($|\\s)")}
|
||||
tmp_site_constructs = tmp_site_constructs.where(:domain_name.in=>check_domains)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
<td><%=site_cert.generate_file_link('ca_bundle')%></td>
|
||||
<td><%=site_cert.generate_file_link('private_key')%></td>
|
||||
<td>
|
||||
<%= link_to t("client_management.batch_install"),"#",:class=>"btn btn-success btn-small batch_install_cert",:data=>{:id=>site_cert.id.to_s} %>
|
||||
<%= link_to t(:edit),admin_site_panel_edit_cert_path(site_cert.id),:class=>"btn btn-primary btn-small" %>
|
||||
<%= link_to t(:delete_),admin_site_panel_destroy_cert_path(site_cert.id),:class=>"btn btn-danger btn-small",:data=>{:method=>"delete",:confirm=>t("client_management.confirm_delete")} %>
|
||||
</td>
|
||||
|
@ -49,3 +50,107 @@
|
|||
font-size: 2em;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
var close_info = false;
|
||||
var timeout_id;
|
||||
var cert_id;
|
||||
var status_relation = {"starting":"<span style=\"color: skyblue;\">starting</span>","execing":"<span style=\"color: skyblue;\">execing</span>","detecting":"<span style=\"color: skyblue;\">detecting</span>","error":"<span style=\"color: red;\">error</span>","finish": "<span style=\"color: darkseagreen;\">finish</span>","closed":"<span style=\"color: red;\">closed</span>"};
|
||||
$(".batch_install_cert").off('click').on('click',function(){
|
||||
cert_id = $(this).data("id");
|
||||
$.post("<%=admin_site_panel_edit_server_info_path%>",{"type":"get_server_names"}).done(function(server_names){
|
||||
var server_names = Array.isArray(server_names) ? server_names : [];
|
||||
show_exec_commands_block(server_names);
|
||||
})
|
||||
});
|
||||
function show_exec_commands_block(server_names){
|
||||
if($("#batch_install_cert-dialog-confirm").length == 0){
|
||||
$("#main-wrap").before("<div id='batch_install_cert-dialog-confirm' title='Select servers need to install this cert'>"+
|
||||
"<div style='clear: both;'></div><div class='control-group'><label style='font-size: 1.2em; font-weight: bold;'><%= check_box_tag("redirect_to_https",1,(@site_construct.redirect_to_https rescue false)).gsub('"',"'").html_safe %><%=t("client_management.redirect_to_https")%></label></div><div id='server_names_block'></div></div>");
|
||||
};
|
||||
$( "#batch_install_cert-dialog-confirm" ).dialog({
|
||||
resizable: true,
|
||||
minHeight: 300,
|
||||
maxHeight: 400,
|
||||
modal: true,
|
||||
width: '80%',
|
||||
open: function(){
|
||||
$(this).parent().css("top",$(document).height() - $(window).height() + "px");
|
||||
},
|
||||
close: function(){$( this ).dialog( "close" );},
|
||||
buttons: {
|
||||
"<%= t(:submit) %>": function(){$( this ).dialog( "close" );exec_commands()},
|
||||
}
|
||||
});
|
||||
$("#server_names_block").html($.map(server_names,function(server_name){
|
||||
return "<input style='float: left;' class='server_name_checkbox' type='checkbox' id='server_name_"+server_name+"'><label style='float: left;' for='server_name_"+server_name+"'>"+server_name+"</label>"
|
||||
}))
|
||||
}
|
||||
function exec_commands(){
|
||||
var server_names = [];
|
||||
var $els = $(".server_name_checkbox");
|
||||
for(var i = 0; i < $els.length; i++){
|
||||
if($els.eq(i).prop("checked")){
|
||||
console.log($els.eq(i));
|
||||
server_names.push($("label[for='"+$els.eq(i).attr('id')+"']").text().trim());
|
||||
}
|
||||
}
|
||||
var redirect_to_https = ($('#batch_install_cert-dialog-confirm [name="redirect_to_https"]:checked').length != 0);
|
||||
$.post("<%=admin_site_panel_edit_site_path%>",{'server_names':server_names,'type':'select_cert', 'is_server': true, 'site_cert_id': cert_id, 'redirect_to_https': redirect_to_https}).done(function(){
|
||||
show_infos_dialog("batch_install_certs");
|
||||
});
|
||||
}
|
||||
function see_infos(key){
|
||||
key = key || "";
|
||||
if(!close_info){
|
||||
var request = $.post("<%=admin_site_panel_edit_server_info_path%>",{"type":'see_infos',"key":key});
|
||||
request.done(function(data){
|
||||
var infos = request.responseJSON.infos;
|
||||
var status = request.responseJSON.status;
|
||||
if($("#info_texts").length == 0)
|
||||
return infos.join("<br>")
|
||||
else{
|
||||
if(status == "")
|
||||
var status_text = "not yet create";
|
||||
else
|
||||
var status_text = status_relation[status];
|
||||
if(!status_text){
|
||||
status_text = "<span style=\"color: skyblue;\">"+status+"</span>";
|
||||
}
|
||||
$("#info_texts").html(status_text+"<div style='clear:both;'></div>"+infos.join("<br>"));
|
||||
msg_end.scrollIntoView();
|
||||
timeout_id = window.setTimeout(see_infos(key),1000);
|
||||
}
|
||||
})
|
||||
}else{
|
||||
window.clearTimeout(timeout_id);
|
||||
}
|
||||
};
|
||||
function show_infos_dialog(key){
|
||||
key = key || "";
|
||||
close_info = true;
|
||||
window.clearTimeout(timeout_id);
|
||||
close_info = false;
|
||||
if($("#dialog-confirm").length == 0){
|
||||
$("#main-wrap").before("<div id='dialog-confirm' title='site infos'>"+
|
||||
"<div style='clear:both;'></div><div id='info_texts'>"+see_infos(key)+"</div><div id='msg_end' style='height:0px; overflow:hidden'></div>"+
|
||||
"</div>");
|
||||
}else{
|
||||
see_infos(key);
|
||||
};
|
||||
$( "#dialog-confirm" ).dialog({
|
||||
resizable: true,
|
||||
minHeight: 100,
|
||||
maxHeight: 400,
|
||||
width: '80%',
|
||||
modal: true,
|
||||
open: function(){
|
||||
$(this).parent().css("top",$(document).height() - $(window).height() + "px");
|
||||
},
|
||||
close: function(){close_info = true;},
|
||||
buttons: {
|
||||
"<%= t('client_management.confirm') %>": function(){$( this ).dialog( "close" );close_info = true;},
|
||||
"stop update": function(){close_info = true;}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
|
@ -210,7 +210,7 @@
|
|||
$(".install_certbot_certs").off("click").on("click",function(){
|
||||
var id = $(this).data("id");
|
||||
$.post("<%=admin_site_panel_edit_site_path%>",{'id': id,'type':'select_cert', 'is_server': true}).done(function(response){
|
||||
show_infos_dialog("install_certbot_certs");
|
||||
show_infos_dialog("batch_install_certs");
|
||||
});
|
||||
})
|
||||
})
|
||||
|
|
|
@ -7,6 +7,7 @@ en:
|
|||
upload_cert: Upload Cert
|
||||
cert_management: Cert Management
|
||||
client_management:
|
||||
batch_install: Batch Install
|
||||
install_certbot_certificates_in_batches: Install certbot certificates in batches
|
||||
update_nginx_settings: "Update nginx settings"
|
||||
set_to_default_domain_name: "Set to default domain name"
|
||||
|
|
|
@ -7,6 +7,7 @@ zh_tw:
|
|||
upload_cert: 上傳憑證
|
||||
cert_management: 憑證管理
|
||||
client_management:
|
||||
batch_install: 批次安裝
|
||||
install_certbot_certificates_in_batches: 批次安裝certbot憑證
|
||||
update_nginx_settings: "修改nginx設定"
|
||||
set_to_default_domain_name: "設定為預設的domain name"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Rails.application.routes.draw do
|
||||
|
||||
locales = Site.find_by(site_active: true).in_use_locales rescue I18n.available_locales
|
||||
scope "(:locale)", locale: Regexp.new(locales.join("|")) do
|
||||
scope "(:locale)", locale: ::Regexp.new(locales.join("|")) do
|
||||
namespace :admin do
|
||||
# get "client_managements/completed_requests", to: 'client_managements#completed_requests'
|
||||
# get "client_managements/contracts", to: 'client_managements#contracts'
|
||||
|
|
|
@ -3,23 +3,24 @@ require 'pathname'
|
|||
require 'json'
|
||||
namespace :create_site do
|
||||
desc "Change Site Cert"
|
||||
task :change_site_cert,[:id,:is_certbot,:id_is_server] => :environment do |task,args|
|
||||
task :change_site_cert,[:id,:is_certbot,:id_is_server,:cert_id,:redirect_to_https,:exec_finish] => :environment do |task,args|
|
||||
begin
|
||||
site_server = nil
|
||||
site_constructs = []
|
||||
@is_multithread = false
|
||||
@thread = nil
|
||||
@default_cert = args.cert_id ? SiteCert.find(args.cert_id) : nil
|
||||
if args.id_is_server
|
||||
site_server = SiteServer.find(args.id)
|
||||
site_constructs = site_server.site_constructs.to_a
|
||||
@is_multithread = true
|
||||
Multithread.where(:key=>'install_certbot_certs').each{|thread| thread.destroy if (thread.status["status"] == "error" || thread.status["status"] == "finish")}
|
||||
Multithread.where(:key=>'install_certbot_certs').destroy
|
||||
@thread = Multithread.where(:key=>'install_certbot_certs').first
|
||||
Multithread.where(:key=>'batch_install_certs').each{|thread| thread.destroy if (thread.status["status"] == "error" || thread.status["status"] == "finish")}
|
||||
Multithread.where(:key=>'batch_install_certs').destroy
|
||||
@thread = Multithread.where(:key=>'batch_install_certs').first
|
||||
if @thread.nil?
|
||||
@thread = Multithread.create(:key=>'install_certbot_certs',:status=>{"infos"=>[],"status"=>"execing"})
|
||||
@thread = Multithread.create(:key=>'batch_install_certs',:status=>{"infos"=>[],"status"=>"execing"})
|
||||
else
|
||||
return false
|
||||
return false if @default_cert.nil?
|
||||
end
|
||||
else
|
||||
@site_construct = SiteConstruct.find(args.id)
|
||||
|
@ -31,6 +32,7 @@ namespace :create_site do
|
|||
if !site_server.nil?
|
||||
@password = site_server.password
|
||||
Net::SSH.start(site_server.ip , site_server.account , password: site_server.password) do |ssh|
|
||||
redirect_to_https = args.redirect_to_https ? true : (@site_construct.redirect_to_https rescue false)
|
||||
if tmp_is_certbot || (@site_cert.is_certbot rescue false)
|
||||
domain_names = site_constructs.flat_map{|site_construct| site_construct.domain_name.strip.split(" ")}.select{|d| d.present? && d.match(/^[\d\.]+$/).nil?}
|
||||
domain_names = domain_names.select{|d| `dig #{d} +short`.split("\n").select{|s| s.strip == site_server.ip}.count != 0}
|
||||
|
@ -41,7 +43,6 @@ namespace :create_site do
|
|||
if site_constructs.count > 1
|
||||
auto_update_infos("Generating single cert for multiple domain names...")
|
||||
end
|
||||
redirect_to_https = (@site_construct.redirect_to_https rescue false)
|
||||
exec_ssh_command_by_sudo_and_see_output(ssh,"sudo -p 'sudo password:' #{certbot_path} --nginx #{domain_names.map{|d| "-d " + d}.join(" ")} -n --#{redirect_to_https ? 'redirect' : 'no-redirect'}",true,false)
|
||||
site_constructs.each do |site_construct|
|
||||
@site_construct = site_construct
|
||||
|
@ -73,7 +74,7 @@ namespace :create_site do
|
|||
site_construct.update(:site_cert=>site_cert)
|
||||
end
|
||||
all_ports = (site_construct.port + ["443"]).uniq
|
||||
site_construct.update(:port=> all_ports )
|
||||
site_construct.update(:port=> all_ports, :status=>'finish' )
|
||||
auto_update_infos("Finish installing cert with certbot in #{site_construct.site_name} !")
|
||||
else
|
||||
auto_update_infos("Certbot generate cert failed!")
|
||||
|
@ -89,13 +90,19 @@ namespace :create_site do
|
|||
end
|
||||
else
|
||||
site_constructs.each do |site_construct|
|
||||
@site_cert = @site_construct.site_cert
|
||||
@site_cert = @default_cert || @site_construct.site_cert
|
||||
next if @site_cert.nil?
|
||||
is_certbot = tmp_is_certbot || (@site_cert.is_certbot rescue false)
|
||||
@site_construct = site_construct
|
||||
@site_cert.change_data
|
||||
if @site_cert.is_valid
|
||||
valid_domain_names = @site_cert.valid_domain_names(@site_construct.domain_name)
|
||||
next if valid_domain_names.count == 0
|
||||
if @default_cert
|
||||
@site_construct.update(:site_cert=>@default_cert,:redirect_to_https=>redirect_to_https)
|
||||
end
|
||||
auto_update_infos("Copying Cert to #{@site_construct.server_type}...")
|
||||
auto_update_infos("Installing Cert on #{valid_domain_names.join(" , ")}")
|
||||
cert_file_content = [(@site_cert.cert_file.file.read.strip rescue ""),(@site_cert.ca_bundle.file.read.strip rescue "")].join("\n").strip
|
||||
private_key_content = @site_cert.private_key.file.read
|
||||
cert_file_store_path = @site_construct.cert_file_remote_store_path
|
||||
|
@ -108,7 +115,7 @@ namespace :create_site do
|
|||
auto_update_infos("Setting Cert...")
|
||||
nginx_file_content = exec_command_by_user(ssh,"cat #{@site_construct.nginx_file}")
|
||||
all_ports = (@site_construct.port + ["443"]).uniq
|
||||
@site_construct.update(:port=> all_ports )
|
||||
@site_construct.update(:port=> all_ports,:status=>'finish' )
|
||||
nginx_file_content = @site_construct.generate_nginx_text(nginx_file_content)
|
||||
cmd = "x='#{nginx_file_content}'; echo '#{@password}' | sudo -S sh -c \"echo '$x' > #{@site_construct.nginx_file}\""
|
||||
exec_command_by_user(ssh,cmd)
|
||||
|
@ -116,11 +123,13 @@ namespace :create_site do
|
|||
end
|
||||
end
|
||||
exec_ssh_command_by_sudo(ssh,"service nginx restart")
|
||||
auto_update_infos("Finish!")
|
||||
if @is_multithread
|
||||
@thread.update(:status=>@thread.status.merge({"status"=>"finish"}))
|
||||
else
|
||||
@site_construct.update(:status=>"finish")
|
||||
if @default_cert.nil? || args.exec_finish
|
||||
auto_update_infos("Finish!")
|
||||
if @is_multithread
|
||||
@thread.update(:status=>@thread.status.merge({"status"=>"finish"}))
|
||||
else
|
||||
@site_construct.update(:status=>"finish")
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
|
@ -130,7 +139,11 @@ namespace :create_site do
|
|||
rescue => e
|
||||
puts [e,e.backtrace]
|
||||
auto_update_infos(e.to_s)
|
||||
@site_construct.update(:status=>"error")
|
||||
if @is_multithread
|
||||
@thread.update(:status=>@thread.status.merge({"status"=>"error"}))
|
||||
else
|
||||
@site_construct.update(:status=>"error")
|
||||
end
|
||||
end
|
||||
end
|
||||
def exec_command_by_user(session,command)
|
||||
|
|
Loading…
Reference in New Issue