diff --git a/app/controllers/admin/site_panel_controller.rb b/app/controllers/admin/site_panel_controller.rb
index 63c2ff0..ec43533 100644
--- a/app/controllers/admin/site_panel_controller.rb
+++ b/app/controllers/admin/site_panel_controller.rb
@@ -134,6 +134,16 @@ class Admin::SitePanelController < OrbitAdminController
@site_server = SiteServer.find(params[:id])
end
end
+ def update_nginx_settings
+ extra_text = ""
+ if params[:key].present?
+ extra_text = "[#{params[:key].gsub(/[\(\)\[\]]/){|ff| "\\"+ff }}]"
+ end
+ Thread.new do
+ system("bundle exec rake create_site:update_multiple_nginx_setting#{extra_text}")
+ end
+ render :json => {"success"=>true}
+ end
def install_certbot
extra_text = ""
if params[:server_name].present?
@@ -224,6 +234,7 @@ class Admin::SitePanelController < OrbitAdminController
render 'see_detail_for_created_site' and return
elsif params[:type] == 'change_server_name'
site_construct = SiteConstruct.find(params[:id])
+ site_construct.update_attributes(update_site_params)
site_construct.update(:domain_name=>params[:site_construct][:domain_name])
cmd = "bundle exec rake create_site:change_site_server_name[#{params[:id]},'#{params[:site_construct][:domain_name]}','#{params[:site_construct][:port].to_a.join('////') }']"
site_construct.update(:status=>"execing",:infos=>["Execing change domain name task..."])
@@ -235,15 +246,19 @@ class Admin::SitePanelController < OrbitAdminController
SiteConstruct.find(params[:id]).destroy
redirect_to :back and return
elsif params[:type] == 'select_cert'
- @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]))
+ 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]))
+ end
+ else
+ is_certbot = true
end
Thread.new do
- system("bundle exec rake create_site:change_site_cert[#{params[:id]},#{is_certbot}]")
+ system("bundle exec rake create_site:change_site_cert[#{params[:id]},#{is_certbot},#{params[:is_server]}]")
end
else
Thread.new do
@@ -294,7 +309,11 @@ class Admin::SitePanelController < OrbitAdminController
site_construct_params = params.require(:site_construct).permit! rescue {}
end
def site_server_params
- params.require(:site_server).permit! rescue {}
+ server_params = params.require(:site_server).permit! rescue {}
+ if server_params[:default_domain_names].nil?
+ server_params[:default_domain_names] = []
+ end
+ server_params
end
def check_server_ability(site_num_add=0)
store_token = current_site.store_token
@@ -313,4 +332,8 @@ class Admin::SitePanelController < OrbitAdminController
@server_ability.update_attributes(site_num: site_num)
end
end
+ def update_site_params
+ site_params = params.require(:site_construct).permit!
+ site_params.except(:domain_name,:port)
+ end
end
\ No newline at end of file
diff --git a/app/models/site_cert.rb b/app/models/site_cert.rb
index 5cbb407..e2e25d0 100644
--- a/app/models/site_cert.rb
+++ b/app/models/site_cert.rb
@@ -30,21 +30,27 @@ class SiteCert
self.end_date.strftime("%Y-%m-%d") rescue ""
end
def change_data
- 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 []
- start_date_text = `openssl x509 -text < #{self.cert_file.file.file} -startdate -noout`.split('=').last.strip
- end_date_text = `openssl x509 -text < #{self.cert_file.file.file} -enddate -noout`.split('=').last.strip
- self.start_date = DateTime.parse(start_date_text) rescue nil
- self.end_date = DateTime.parse(end_date_text) rescue nil
- self.is_valid = is_valid
- self.domain_names = domain_names
- if !@skip_callback
- @skip_callback = true
- self.save(:validate=>false)
- end
- @skip_callback = false
- false
+ if !@skip_callback
+ 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 []
+ if domain_names.blank?
+ self.is_valid = false
+ @skip_callback = true
+ self.save(:validate=>false)
+ else
+ start_date_text = `openssl x509 -text < #{self.cert_file.file.file} -startdate -noout`.split('=').last.strip
+ end_date_text = `openssl x509 -text < #{self.cert_file.file.file} -enddate -noout`.split('=').last.strip
+ self.start_date = DateTime.parse(start_date_text) rescue nil
+ self.end_date = DateTime.parse(end_date_text) rescue nil
+ self.is_valid = is_valid
+ self.domain_names = domain_names
+ @skip_callback = true
+ self.save(:validate=>false)
+ end
+ @skip_callback = false
+ false
+ end
end
end
\ No newline at end of file
diff --git a/app/models/site_construct.rb b/app/models/site_construct.rb
index 36c17f7..58e20ad 100644
--- a/app/models/site_construct.rb
+++ b/app/models/site_construct.rb
@@ -5,6 +5,8 @@ class SiteConstruct
SiteServer.all.map{|s| s.server_name}
end
SITE_TYPES = ["School","Gravity"]
+ field :enable_redirect_default_domain, type: Integer, default: 0 #0 => use default, 1 => disable, 2 => enable
+ field :default_domain_idx, type: Integer, default: -1 #-1 present use default
field :rails_env, type: String, :default => "development"
field :server_type
field :site_name
@@ -104,6 +106,7 @@ class SiteConstruct
else
port = port.to_s
end
+ redirect_default_text = get_redirect_default_text(port)
port_text = port
if port.to_i == 443
if self.site_cert.nil?
@@ -118,12 +121,18 @@ class SiteConstruct
new_server_block = new_server_block.gsub(/\s*ssl_certificate[^;]+;/,'')
level_2_block = parse_nginx_text_to_server_blocks(old_server_block,true,2)
get_redirect_block = level_2_block.select{|t| t.match(/\s*return\s+30[12]\s+https:\/\/\$host\$request_uri\s*;/)}
+ get_redirect_to_default_block = level_2_block.select{|t| t.match(/\s*return\s+30[12]\s+http(s|):\/\/[^\$]+\$request_uri\s*;/)}
location_app_block = level_2_block.select{|t| t.match(/location\s+@app/)}
if get_redirect_block.count > 0
get_redirect_block.each do |redirect_block|
new_server_block = new_server_block.gsub(redirect_block,'')
end
end
+ if get_redirect_to_default_block.count > 0
+ get_redirect_to_default_block.each do |redirect_block|
+ new_server_block = new_server_block.gsub(redirect_block,'')
+ end
+ end
if location_app_block.count > 0
location_app_block = location_app_block.map do |app_block|
new_app_block = app_block.gsub(/proxy_set_header\s+X-Forwarded-Proto\s+https\s*;/,"")
@@ -144,6 +153,9 @@ class SiteConstruct
" }\n"}
end
end
+ if redirect_default_text.present?
+ new_server_block = new_server_block.sub(/\s*root/){|ff| redirect_default_text + ff}
+ end
new_server_block = new_server_block.gsub(/[ \t\s]+\n/,"\n\n").gsub(/\n{3,}/,'\n\n')
else
'server {\n'+
@@ -153,6 +165,7 @@ class SiteConstruct
((self.redirect_to_https && !self.site_cert.nil?) ? " if ($host ~ (#{self.site_cert.domain_names.map{|s| '^'+s.gsub('.','\.').gsub('*','[^.]*').gsub(',','')}.join('|')}) ) {\n"+
" return 301 https://$host$request_uri;\n"+
"}\n" : '') : '')+
+ redirect_default_text +
' root '+self.full_site_path+'/public;\n\n'+
' server_name '+self.domain_name+';\n\n'+
' client_max_body_size 500m;\n\n'+
@@ -213,4 +226,39 @@ class SiteConstruct
def site_server
SiteServer.where(server_name: self.server_type).first
end
+ def get_default_domain
+ custom_default_domain_name = ""
+ domain_names = domain_name.strip().split(" ")
+ if default_domain_idx == -1
+ custom_default_domain_name = site_server.default_domain_names.select do |default_domain_name|
+ default_domain_name = Regexp.new("\\A"+default_domain_name.gsub(".","\\.").gsub("*","[^.]*"))
+ domain_names.select{|n| n.match(default_domain_name) }.count != 0
+ end.first
+ else
+ custom_default_domain_name = domain_names[default_domain_idx]
+ end
+ custom_default_domain_name
+ end
+ def get_enable_redirect_default_domain
+ (self.enable_redirect_default_domain == 0 ? site_server.enable_redirect_default_domain : ((self.enable_redirect_default_domain - 1) == 1) rescue false)
+ end
+ def default_enable_redirect_default_domain
+ site_server.enable_redirect_default_domain rescue false
+ end
+ def get_redirect_default_text(port=80)
+ port = port.to_i
+ is_enable = get_enable_redirect_default_domain
+ scheme = (port == 443 ? "https" : "http")
+ port_text = ((port == 80 || port == 443 || port.blank?) ? "" : ":#{port}")
+ text = ""
+ if is_enable
+ default_domain = get_default_domain
+ if default_domain.present?
+ text = "\n\n if ($host !~* (^#{default_domain.gsub('.','\.')}$) ) {\n"+
+ " return 302 #{scheme}://#{default_domain}#{port_text}$request_uri;\n"+
+ " }\n\n"
+ end
+ end
+ text
+ end
end
\ No newline at end of file
diff --git a/app/models/site_server.rb b/app/models/site_server.rb
index 0fb31d1..16a43c9 100644
--- a/app/models/site_server.rb
+++ b/app/models/site_server.rb
@@ -5,6 +5,8 @@ class SiteServer
include OrbitTag::Taggable
include OrbitModel::Status
field :server_name , type: String ,default: ''
+ field :enable_redirect_default_domain, type: Boolean, default: false
+ field :default_domain_names, type: Array, default: []
field :domain_name , type: String ,default: ''
field :domain_names, type: Array, default: []
field :ip , type: String ,default: ''
@@ -12,6 +14,7 @@ class SiteServer
field :password , type: String ,default: ''
field :active , type: Boolean ,default: true
field :has_certbot, type: Boolean , default: false
+ field :need_update_site_ids, type: Array, default: []
def domain_names
if self.domain_name != ''
[self.domain_name]
@@ -19,9 +22,38 @@ class SiteServer
super
end
end
+ def site_constructs
+ SiteConstruct.where(server_type: self.server_name)
+ end
before_save do
if self.domain_name != '' && self.domain_names.length !=0
self.domain_name = ''
end
+ tmp_site_constructs = site_constructs
+ need_change = false
+ if self.enable_redirect_default_domain_changed?
+ tmp_site_constructs = tmp_site_constructs.where(:enable_redirect_default_domain.in=>[nil,0])
+ need_change = true
+ end
+ if (need_change || (!need_change && self.enable_redirect_default_domain))
+ if self.default_domain_names_changed?
+ check_domains = []
+ removed_default_domains = self.default_domain_names_was - self.default_domain_names
+ add_default_domains = self.default_domain_names - self.default_domain_names_was
+ check_domains += removed_default_domains
+ check_domains += add_default_domains
+ 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)")}
+ tmp_site_constructs = tmp_site_constructs.where(:domain_name.in=>check_domains)
+ end
+ end
+ if need_change
+ self.need_update_site_ids += tmp_site_constructs.pluck(:id)
+ self.need_update_site_ids = self.need_update_site_ids.uniq
+ end
end
end
\ No newline at end of file
diff --git a/app/views/admin/site_panel/_server_manager_index.html.erb b/app/views/admin/site_panel/_server_manager_index.html.erb
index 6fc86ff..e41ed75 100644
--- a/app/views/admin/site_panel/_server_manager_index.html.erb
+++ b/app/views/admin/site_panel/_server_manager_index.html.erb
@@ -40,6 +40,9 @@
<% if site_server.has_certbot%>
<%= t("client_management.alreay_install") %>
+ <% if site_server.active %>
+ " data-id="<%=site_server.id.to_s%>"><%= t("client_management.install_certbot_certificates_in_batches") %>
+ <% end %>
<% else %>
<%= t("client_management.not_install") %>
<% if site_server.active %>
@@ -48,6 +51,9 @@
<% end %>
|
+ <% if site_server.need_update_site_ids.count != 0 %>
+ <%=t("client_management.update_nginx_settings")%>
+ <% end %>
"><%=t(:edit)%>
';}"><%=t(:remove)%>
"><%= t('client_management.see_sites') %>
@@ -170,6 +176,14 @@
show_infos_dialog("detect_sites");
})
});
+ $(".update_nginx_settings").off('click').on('click',function(){
+ var key = $(this).data("key");
+ if( key == undefined)
+ key = "";
+ $.post("<%=admin_site_panel_update_nginx_settings_path%>",{"key":key}).done(function(){
+ show_infos_dialog("update_multiple_nginx_setting");
+ })
+ });
$("#exec_commands").off('click').on('click',function(){
//show_exec_commands_block(server_names)
$.post("<%=admin_site_panel_edit_server_info_path%>",{"type":"get_server_names"}).done(function(server_names){
@@ -193,5 +207,11 @@
show_infos_dialog("install_certbot");
})
})
+ $(".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");
+ });
+ })
})
\ No newline at end of file
diff --git a/app/views/admin/site_panel/_sites_list_table.html.erb b/app/views/admin/site_panel/_sites_list_table.html.erb
index 71946aa..4f9b814 100644
--- a/app/views/admin/site_panel/_sites_list_table.html.erb
+++ b/app/views/admin/site_panel/_sites_list_table.html.erb
@@ -261,9 +261,7 @@
var redirect_to_https = ($('#https_setting_area [name="redirect_to_https"]:checked').length != 0);
var site_cert_id = $('#https_setting_area [name="site_cert"]:checked').eq(0).val();
if(site_cert_id != undefined){
- console.log(site_cert_id);
$.post("<%=admin_site_panel_edit_site_path%>",{'id': id,'type':'select_cert','site_cert_id': site_cert_id,'redirect_to_https': redirect_to_https}).done(function(response){
- console.log(response);
show_infos_dialog(item);
});
}
diff --git a/app/views/admin/site_panel/edit_server_info.html.erb b/app/views/admin/site_panel/edit_server_info.html.erb
index e2606ba..4911ef9 100644
--- a/app/views/admin/site_panel/edit_server_info.html.erb
+++ b/app/views/admin/site_panel/edit_server_info.html.erb
@@ -15,6 +15,14 @@
tp2.append(tp3);
tp2.append('<%= delete_domain_button %>')
}
+ function add_default_domain(ele){
+ var tp=$(ele);
+ var tp2=tp.parents('.controls').eq(0).find('.group');
+ var tp3 = ')" title="*.example.com (<%=t("client_management.domain_hint")%>)">';
+ tp2.append(' ');
+ tp2.append(tp3);
+ tp2.append('<%= delete_domain_button %>')
+ }
function delete_domain(ele){
$(ele).prev('input').remove()
$(ele).prev('br').remove()
@@ -51,9 +59,9 @@
<% unless @site_server.new_record? %>
-
+
- <%= f.check_box :active %>
+ <%= f.check_box :active,:id=>"active_server" %>
<% end %>
@@ -87,6 +95,29 @@
%>
+
+
+
+ <%= f.check_box :enable_redirect_default_domain,:id=>"enable_redirect_default_domain" %>
+
+
+
+
+
+
+ <%
+ @site_server.default_domain_names.each_with_index do |domain_name,i| %>
+ <%= ' '.html_safe if i !=0 %>
+ <%= text_field_tag "site_server[default_domain_names][]",domain_name,{:id=>nil,:class=>"domain_name"} %>
+ <%= delete_domain_button %>
+ <% end %>
+
+ <%= f.button "#{t('add')} domain", class: 'btn btn-info',
+ :onclick=> "add_default_domain(this)",
+ :type => 'button'
+ %>
+
+
diff --git a/app/views/admin/site_panel/see_detail_for_created_site.html.erb b/app/views/admin/site_panel/see_detail_for_created_site.html.erb
index eba7828..6b0edbe 100644
--- a/app/views/admin/site_panel/see_detail_for_created_site.html.erb
+++ b/app/views/admin/site_panel/see_detail_for_created_site.html.erb
@@ -6,11 +6,20 @@
<%=@site.server_type%>
+
+
+
+ <% %>
+ <%= select_tag "site_construct[enable_redirect_default_domain]", options_for_select((0..2).to_a.collect{ |i| [I18n.t("client_management.option.#{i}") + (i == 0 ? ": #{@site.default_enable_redirect_default_domain ? I18n.t("client_management.option.2") : I18n.t("client_management.option.1")}" : ""), i.to_s] }, @site.enable_redirect_default_domain) ,:id=>"enable_redirect_default_domain" %>
+
+
+ <%= hidden_field_tag "site_construct[default_domain_idx]", "-1" %>
<% @site.domain_name.split(' ').each_with_index do |domain_name,i| %>
+ <%= check_box_tag "site_construct[default_domain_idx]", i, (@site.default_domain_idx == i), :class=>"default_domain_idx", :title=>t("client_management.set_to_default_domain_name") %>
<%= text_field_tag nil,domain_name,:class=>'domain_name',onchange: 'domain_name_change()',:oninput=>'replace_domain_input(this)' %>
<% if i != 0 %>
- <%=@site.path%>
+ <%=@site.full_site_path%>
@@ -168,12 +177,16 @@
var first_domain_group = $('.domain_group').first()
var clone_domain_group = $(first_domain_group).clone()
clone_domain_group.find('input[type="text"]').val('')
+ clone_domain_group.find('.default_domain_idx').val($(".default_domain_idx").length);
clone_domain_group.append("")
$('.domain_group').last().after(clone_domain_group)
})
function delete_domain(ele){
$('.domain_group').eq($(ele).parents('.domain_group').index('.domain_group')).remove()
domain_name_change()
+ $(".default_domain_idx").each(function(i,v){
+ $(v).val(i);
+ })
}
function replace_domain_input(ele){
var correct_val = $(ele).val().match(/([0-9]||[a-z]||[-_.])*/gi).join("");
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 782538d..8c4f7b3 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -7,6 +7,18 @@ en:
upload_cert: Upload Cert
cert_management: Cert Management
client_management:
+ 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"
+ domain_hint: "* only match one level url"
+ redirect_to_default_domain_name: Redirect to default domain_name
+ default_domain_names: Default domain names
+ disable: Disable
+ enable: Enable
+ option:
+ '0': Default
+ '1': Disable
+ '2': Enable
alreay_install: Alreay install
not_install: Not install
active: Active
diff --git a/config/locales/zh_tw.yml b/config/locales/zh_tw.yml
index 92a4290..db2db3d 100644
--- a/config/locales/zh_tw.yml
+++ b/config/locales/zh_tw.yml
@@ -7,6 +7,18 @@ zh_tw:
upload_cert: 上傳憑證
cert_management: 憑證管理
client_management:
+ install_certbot_certificates_in_batches: 批次安裝certbot憑證
+ update_nginx_settings: "修改nginx設定"
+ set_to_default_domain_name: "設定為預設的domain name"
+ domain_hint: "*僅能匹配一層的網址"
+ redirect_to_default_domain_name: 跳轉到預設的domain name
+ default_domain_names: 預設的domain names
+ disable: 關閉
+ enable: 開啟
+ option:
+ '0': 預設
+ '1': 關閉
+ '2': 開啟
alreay_install: 已安裝
not_install: 未安裝
active: 啟用
diff --git a/config/routes.rb b/config/routes.rb
index b3bc57f..a96a8dc 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -52,6 +52,7 @@ Rails.application.routes.draw do
post "site_panel/install_certbot" => "site_panel#install_certbot"
post "site_panel/update_cert_setting" => "site_panel#update_cert_setting"
+ post "site_panel/update_nginx_settings" => "site_panel#update_nginx_settings"
resources :site_panel do
delete 'destroy_cert'
get 'edit_cert'
diff --git a/lib/tasks/change_site_cert.rake b/lib/tasks/change_site_cert.rake
index e719179..0dafa4c 100644
--- a/lib/tasks/change_site_cert.rake
+++ b/lib/tasks/change_site_cert.rake
@@ -3,98 +3,133 @@ require 'pathname'
require 'json'
namespace :create_site do
desc "Change Site Cert"
- task :change_site_cert,[:id,:is_certbot] => :environment do |task,args|
+ task :change_site_cert,[:id,:is_certbot,:id_is_server] => :environment do |task,args|
begin
- @site_construct = SiteConstruct.find(args.id)
- @site_cert = @site_construct.site_cert
- site_server = @site_construct.site_server
- @site_construct.update(:infos=>[],:status=>"changing")
- is_certbot = (args.is_certbot == "true") || (@site_cert.is_certbot rescue false)
- if !site_server.nil? && (!@site_cert.nil? || is_certbot)
- @password = site_server.password
- Net::SSH.start(site_server.ip , site_server.account , password: site_server.password) do |ssh|
- if is_certbot
- domain_name = @site_construct.domain_name
- if domain_name.present?
- certbot_path = exec_ssh_command_by_sudo_and_see_output(ssh,"bash -l -c 'which certbot certbot-auto'",false,true).strip.split("\n")[0]
- if certbot_path.present?
- if @site_cert
- update_infos("Using certbot to change cert setting...")
- else
- update_infos("Using certbot to generate cert for #{domain_name}...")
- end
- redirect_to_https = @site_construct.redirect_to_https
- exec_ssh_command_by_sudo_and_see_output(ssh,"sudo -p 'sudo password:' #{certbot_path} --nginx -d #{domain_name} -n --#{redirect_to_https ? 'redirect' : 'no-redirect'}",true,false)
- nginx_file = @site_construct.nginx_file
- nginx_file_content = exec_ssh_command_by_sudo_and_see_output(ssh,"cat #{nginx_file}",false,true)
- crt_file_path = nginx_file_content.match(/ssl_certificate\s+(.*)/)[1].split(';').first rescue ''
- private_key_path = nginx_file_content.match(/ssl_certificate_key\s+(.*)/)[1].split(';').first rescue ''
- site_cert = @site_construct.site_cert
- if crt_file_path.present? && private_key_path.present?
- if site_cert.nil?
- site_cert = SiteCert.where(:source_paths=>[crt_file_path,private_key_path]).first
- site_cert = SiteCert.new if site_cert.nil?
- end
- if true #site_cert.source_paths.count == 0
- site_cert["cert_file"] = File.basename(crt_file_path)
- cert_file_store_path = site_cert.cert_file.file.file
- crt_file_content = exec_ssh_command_by_sudo_and_see_output(ssh,"cat #{crt_file_path}",false).select{|s| s.present?}.join("\n").strip.split(/(\r\n|\n)/).select{|s| s.present?}.join("\n")
- FileUtils.mkdir_p(File.dirname(cert_file_store_path)) unless Dir.exist?(File.dirname(cert_file_store_path))
- File.open(site_cert.cert_file.file.file,'w+'){|f| f.write(crt_file_content)}
- site_cert["private_key"] = File.basename(private_key_path)
- private_key_store_path = site_cert.private_key.file.file
- private_key_content = exec_ssh_command_by_sudo_and_see_output(ssh,"cat #{private_key_path}",false).select{|s| s.present?}.join("\n").strip.split(/(\r\n|\n)/).select{|s| s.present?}.join("\n")
- FileUtils.mkdir_p(File.dirname(private_key_store_path)) unless Dir.exist?(File.dirname(private_key_path))
- File.open(site_cert.private_key.file.file,'w+'){|f| f.write(private_key_content)}
- site_cert.source_paths = [crt_file_path,private_key_path]
- site_cert.is_certbot = private_key_path.include?("letsencrypt")
- site_cert.save
- @site_construct.update(:site_cert=>site_cert)
- end
- all_ports = (@site_construct.port + ["443"]).uniq
- @site_construct.update(:port=> all_ports )
- update_infos("Finish installing cert with certbot!")
- else
- update_infos("Certbot generate cert failed!")
- update_infos("Please check your domain dns setting(A record)!")
- @site_construct.update(:status=>"error")
- end
- else
- update_infos("Please install certbot first!")
- end
- else
- update_infos("Please set domain name first!")
- end
- else
- update_infos("Copying Cert to #{@site_construct.server_type}...")
- 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
- exec_ssh_command_by_sudo(ssh,"mkdir -p #{File.dirname(cert_file_store_path)}")
- exec_command_by_user(ssh,"x='#{cert_file_content}'; echo '#{@password}' | sudo -S sh -c \"echo '$x' > #{cert_file_store_path}\"")
- private_key_store_path = @site_construct.private_key_remote_store_path
- exec_ssh_command_by_sudo(ssh,"mkdir -p #{File.dirname(private_key_store_path)}")
- exec_command_by_user(ssh,"x='#{private_key_content}'; echo '#{@password}' | sudo -S sh -c \"echo '$x' > #{private_key_store_path}\"")
- update_infos("Finish copy.")
- 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 )
- 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)
- end
- exec_ssh_command_by_sudo(ssh,"service nginx restart")
- update_infos("Finish!")
- @site_construct.update(:status=>"finish")
+ site_server = nil
+ site_constructs = []
+ @is_multithread = false
+ @thread = 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
+ if @thread.nil?
+ @thread = Multithread.create(:key=>'install_certbot_certs',:status=>{"infos"=>[],"status"=>"execing"})
+ else
+ return false
end
else
- update_infos("Cert not found!")
+ @site_construct = SiteConstruct.find(args.id)
+ site_server = @site_construct.site_server
+ @site_construct.update(:infos=>[],:status=>"changing")
+ site_constructs << @site_construct
+ end
+ tmp_is_certbot = (args.is_certbot == "true")
+ if !site_server.nil?
+ @password = site_server.password
+ Net::SSH.start(site_server.ip , site_server.account , password: site_server.password) do |ssh|
+ 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`.strip == site_server.ip}
+ if domain_names.count != 0
+ certbot_path = exec_ssh_command_by_sudo_and_see_output(ssh,"bash -l -c 'which certbot certbot-auto'",false,true).strip.split("\n")[0]
+ if certbot_path.present?
+ auto_update_infos("Using certbot to update cert setting...")
+ 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
+ auto_update_infos("Checking cert for #{site_construct.site_name}...")
+ nginx_file = site_construct.nginx_file
+ nginx_file_content = exec_ssh_command_by_sudo_and_see_output(ssh,"cat #{nginx_file}",false,true)
+ crt_file_path = nginx_file_content.match(/(?<=!#|^)\s*ssl_certificate\s+(.*)/)[1].split(';').first rescue ''
+ private_key_path = nginx_file_content.match(/(?<=!#|^)\s*ssl_certificate_key\s+(.*)/)[1].split(';').first rescue ''
+ site_cert = site_construct.site_cert
+ if crt_file_path.present? && private_key_path.present?
+ if site_cert.nil? || !site_cert.is_certbot
+ site_cert = SiteCert.where(:source_paths=>[crt_file_path,private_key_path]).first
+ site_cert = SiteCert.new if site_cert.nil?
+ end
+ if true #site_cert.source_paths.count == 0
+ site_cert["cert_file"] = File.basename(crt_file_path)
+ cert_file_store_path = site_cert.cert_file.file.file
+ crt_file_content = exec_ssh_command_by_sudo_and_see_output(ssh,"cat #{crt_file_path}",false).select{|s| s.present?}.join("\n").strip.split(/(\r\n|\n)/).select{|s| s.present?}.join("\n")
+ FileUtils.mkdir_p(File.dirname(cert_file_store_path)) unless Dir.exist?(File.dirname(cert_file_store_path))
+ File.open(site_cert.cert_file.file.file,'w+'){|f| f.write(crt_file_content)}
+ site_cert["private_key"] = File.basename(private_key_path)
+ private_key_store_path = site_cert.private_key.file.file
+ private_key_content = exec_ssh_command_by_sudo_and_see_output(ssh,"cat #{private_key_path}",false).select{|s| s.present?}.join("\n").strip.split(/(\r\n|\n)/).select{|s| s.present?}.join("\n")
+ FileUtils.mkdir_p(File.dirname(private_key_store_path)) unless Dir.exist?(File.dirname(private_key_path))
+ File.open(site_cert.private_key.file.file,'w+'){|f| f.write(private_key_content)}
+ site_cert.source_paths = [crt_file_path,private_key_path]
+ site_cert.is_certbot = private_key_path.include?("letsencrypt")
+ site_cert.save
+ site_construct.update(:site_cert=>site_cert)
+ end
+ all_ports = (site_construct.port + ["443"]).uniq
+ site_construct.update(:port=> all_ports )
+ auto_update_infos("Finish installing cert with certbot in #{site_construct.site_name} !")
+ else
+ auto_update_infos("Certbot generate cert failed!")
+ auto_update_infos("Please check your domain dns setting(A record)!")
+ site_construct.update(:status=>"error")
+ end
+ end
+ else
+ auto_update_infos("Please install certbot first!")
+ end
+ else
+ auto_update_infos("Please set domain name first!")
+ end
+ else
+ site_constructs.each do |site_construct|
+ @site_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
+ auto_update_infos("Copying Cert to #{@site_construct.server_type}...")
+ 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
+ exec_ssh_command_by_sudo(ssh,"mkdir -p #{File.dirname(cert_file_store_path)}")
+ exec_command_by_user(ssh,"x='#{cert_file_content}'; echo '#{@password}' | sudo -S sh -c \"echo '$x' > #{cert_file_store_path}\"")
+ private_key_store_path = @site_construct.private_key_remote_store_path
+ exec_ssh_command_by_sudo(ssh,"mkdir -p #{File.dirname(private_key_store_path)}")
+ exec_command_by_user(ssh,"x='#{private_key_content}'; echo '#{@password}' | sudo -S sh -c \"echo '$x' > #{private_key_store_path}\"")
+ auto_update_infos("Finish copy.")
+ 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 )
+ 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)
+ end
+ 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")
+ end
+ end
+ else
+ auto_update_infos("Cert not found!")
@site_construct.update(:status=>"error")
end
rescue => e
puts [e,e.backtrace]
- update_infos(e.to_s)
+ auto_update_infos(e.to_s)
@site_construct.update(:status=>"error")
end
end
@@ -109,4 +144,14 @@ namespace :create_site do
end
return output
end
+ def auto_update_infos(info)
+ if @is_multithread
+ update_thread_infos(info)
+ if @site_construct
+ update_infos(info)
+ end
+ else
+ update_infos(info)
+ end
+ end
end
\ No newline at end of file
diff --git a/lib/tasks/change_site_server_name.rake b/lib/tasks/change_site_server_name.rake
index dcf25d8..e1a92b9 100644
--- a/lib/tasks/change_site_server_name.rake
+++ b/lib/tasks/change_site_server_name.rake
@@ -12,18 +12,11 @@ namespace :create_site do
update_infos("Starting change domain name and ports.")
Net::SSH.start(site_server.ip , site_server.account , password: site_server.password) do |ssh|
@site_construct.update(:domain_name=>args.server_name)
- update_infos("Reading setting file.")
- nginx_file_content = exec_command_by_user(ssh,"cat #{@site_construct.nginx_file}")
if args.port.present?
all_ports = args.port.split('////')
@site_construct.update(:port=> all_ports )
end
- nginx_file_content = @site_construct.generate_nginx_text(nginx_file_content)
- update_infos("Writing...")
- cmd = "x='#{nginx_file_content}'; echo '#{@password}' | sudo -S sh -c \"echo '$x' > #{@site_construct.nginx_file}\""
- exec_command_by_user(ssh,cmd)
- exec_ssh_command_by_sudo(ssh,"service nginx restart")
- update_infos("Finish!")
+ change_construct_nginx(ssh,@site_construct)
@site_construct.update(:status=>'finish')
end
end
@@ -33,6 +26,17 @@ namespace :create_site do
puts [e,e.backtrace]
end
end
+ def change_construct_nginx(ssh,site_construct,update_multithread=false)
+ @is_multithread = update_multithread
+ auto_update_infos("Reading setting file...")
+ nginx_file_content = exec_command_by_user(ssh,"cat #{site_construct.nginx_file}")
+ nginx_file_content = site_construct.generate_nginx_text(nginx_file_content)
+ auto_update_infos("Writing...")
+ cmd = "x='#{nginx_file_content}'; echo '#{@password}' | sudo -S sh -c \"echo '$x' > #{site_construct.nginx_file}\""
+ exec_command_by_user(ssh,cmd)
+ exec_ssh_command_by_sudo(ssh,"service nginx restart")
+ auto_update_infos("Finish!")
+ end
def exec_command_by_user(session,command)
output = session.exec!(command)
return output[0...-1].gsub(/^\n[\n]+/,'')
diff --git a/lib/tasks/detect_sites.rake b/lib/tasks/detect_sites.rake
index b3b60bf..4b8062c 100644
--- a/lib/tasks/detect_sites.rake
+++ b/lib/tasks/detect_sites.rake
@@ -4,7 +4,6 @@ require 'fileutils'
namespace :create_site do
desc "Detect sites"
task :detect_sites,[:detect_name] => :environment do |task,args|
- #Multithread.where(:key=>'detect_sites').destroy
Multithread.where(:key=>'detect_sites').each{|thread| thread.destroy if (thread.status["status"] == "error" || thread.status["status"] == "finish")}
Multithread.where(:key=>'detect_sites').destroy
@thread = Multithread.where(:key=>'detect_sites').first
@@ -122,8 +121,8 @@ namespace :create_site do
end
end
site_construct.update(:rails_env => rails_env)
- crt_file_path = nginx_file_content.match(/ssl_certificate\s+(.*)/)[1].split(';').first rescue ''
- private_key_path = nginx_file_content.match(/ssl_certificate_key\s+(.*)/)[1].split(';').first rescue ''
+ crt_file_path = nginx_file_content.match(/(?<=!#|^)\s*ssl_certificate\s+(.*)/)[1].split(';').first rescue ''
+ private_key_path = nginx_file_content.match(/(?<=!#|^)\s*ssl_certificate_key\s+(.*)/)[1].split(';').first rescue ''
site_cert = nil
if crt_file_path.present? || private_key_path.present?
site_cert = site_construct.site_cert
diff --git a/lib/tasks/update_multiple_nginx_setting.rake b/lib/tasks/update_multiple_nginx_setting.rake
new file mode 100644
index 0000000..6bac19b
--- /dev/null
+++ b/lib/tasks/update_multiple_nginx_setting.rake
@@ -0,0 +1,68 @@
+require 'net/ssh'
+require 'pathname'
+require 'fileutils'
+namespace :create_site do
+ desc "Update multiple nginx setting"
+ task :update_multiple_nginx_setting,[:server_name] => :environment do |task,args|
+ Multithread.where(:key=>'update_multiple_nginx_setting').each{|thread| thread.destroy if (thread.status["status"] == "error" || thread.status["status"] == "finish")}
+ Multithread.where(:key=>'update_multiple_nginx_setting').destroy
+ @thread = Multithread.where(:key=>'update_multiple_nginx_setting').first
+ @type = "exec_all"
+ if @thread.nil?
+ begin
+ @thread = Multithread.create(:key=>'update_multiple_nginx_setting',:status=>{"infos"=>[],"status"=>"execing"})
+ if( args.server_name.nil? rescue true)
+ site_servers = SiteServer.all.where(:active=>true).to_a
+ else
+ site_servers = SiteServer.where(:server_name=>args.server_name).to_a
+ end
+ site_servers.each do |site_server|
+ next if (site_server.need_update_site_ids.count == 0)
+ @site_server = site_server
+ update_thread_infos(""+@site_server.server_name+"")
+ @password = @site_server.password
+ begin
+ begin
+ Net::SSH.start(@site_server.ip , @site_server.account , password: @site_server.password) do |ssh|
+ end
+ rescue Net::SSH::HostKeyMismatch
+ system("ssh-keygen -f \"$HOME/.ssh/known_hosts\" -R #{@site_server.ip}")
+ rescue Errno::ENOTTY
+ system("ssh-add \"$HOME/.ssh/id_rsa\"")
+ rescue => e
+ update_thread_infos(e.to_s)
+ next
+ end
+ Net::SSH.start(@site_server.ip , @site_server.account , password: @site_server.password) do |ssh|
+ need_update_sites = SiteConstruct.where(:id.in=>@site_server.need_update_site_ids).to_a
+ need_update_sites.each do |site_construct|
+ update_thread_infos("Changing "+site_construct.site_name+" nginx...")
+ change_construct_nginx(ssh,site_construct,true)
+ end
+ @site_server.need_update_site_ids = []
+ @site_server.save
+ end
+ end
+ end
+ @thread.update(:status=>@thread.status.merge({"status"=>"finish"}))
+ rescue => e
+ puts [e,e.backtrace]
+ @thread.update(:status=>{"infos"=>@thread.status["infos"].push(e.to_s),"status"=>"error"})
+ end
+ end
+ end
+ def exec_ssh_command_by_sudo(session,command)
+ output = session.exec!("echo '#{@password}' | sudo -S #{command}")
+ # output = session.exec!("echo '#{@password}' | sudo -S -s #{command}")
+ if output.include?("sudo:") && output.include?("command not found")
+ output = session.exec!(command)
+ end
+ return output
+ end
+ def update_thread_infos(info)
+ puts info
+ @thread.status["infos"] = @thread.status["infos"].push(info)
+ @thread.save!
+ return @thread.status["infos"]
+ end
+end
\ No newline at end of file
|