From 951aef1b722e243f87bd8e562afdaa917b9156b6 Mon Sep 17 00:00:00 2001 From: Bohung Date: Mon, 19 Apr 2021 09:29:53 +0800 Subject: [PATCH] Add cert setting. --- .../admin/site_panel_controller.rb | 88 ++++++++-- app/models/site_cert.rb | 49 ++++++ app/models/site_construct.rb | 154 +++++++++++++++--- .../admin/site_panel/_cert_form.html.erb | 17 ++ .../admin/site_panel/_certs_table.html.erb | 51 ++++++ app/views/admin/site_panel/_form.html.erb | 28 +++- .../site_panel/_server_manager_index.html.erb | 32 ++-- .../site_panel/_simple_form_file.html.erb | 23 +++ .../site_panel/_sites_list_table.html.erb | 61 ++++++- .../admin/site_panel/cert_management.html.erb | 25 +++ app/views/admin/site_panel/edit_cert.html.erb | 3 + .../site_panel/get_certs_for_site.html.erb | 22 +++ .../see_detail_for_created_site.html.erb | 103 +++++++++++- .../admin/site_panel/upload_cert.html.erb | 3 + config/locales/en.yml | 16 +- config/locales/zh_tw.yml | 16 +- config/routes.rb | 14 +- lib/client_management/engine.rb | 17 +- lib/tasks/add_cert_ver_for_site.rake | 2 +- lib/tasks/change_site_cert.rake | 58 +++++++ lib/tasks/change_site_server_name.rake | 27 ++- lib/tasks/copy_site.rake | 20 +-- lib/tasks/create_site.rake | 20 +-- lib/tasks/detect_sites.rake | 35 +++- 24 files changed, 772 insertions(+), 112 deletions(-) create mode 100644 app/models/site_cert.rb create mode 100644 app/views/admin/site_panel/_cert_form.html.erb create mode 100644 app/views/admin/site_panel/_certs_table.html.erb create mode 100644 app/views/admin/site_panel/_simple_form_file.html.erb create mode 100644 app/views/admin/site_panel/cert_management.html.erb create mode 100644 app/views/admin/site_panel/edit_cert.html.erb create mode 100644 app/views/admin/site_panel/get_certs_for_site.html.erb create mode 100644 app/views/admin/site_panel/upload_cert.html.erb create mode 100644 lib/tasks/change_site_cert.rake diff --git a/app/controllers/admin/site_panel_controller.rb b/app/controllers/admin/site_panel_controller.rb index cbc022d..75ff142 100644 --- a/app/controllers/admin/site_panel_controller.rb +++ b/app/controllers/admin/site_panel_controller.rb @@ -1,10 +1,57 @@ class Admin::SitePanelController < OrbitAdminController - def initialize super @app_title = "client_management" end - + def upload_cert + @site_cert = SiteCert.new + end + def edit_cert + @site_cert = SiteCert.find(params[:site_panel_id]) + end + def update_cert + @site_cert = SiteCert.find(params[:site_panel_id]) + @site_cert.update_attributes(site_cert_params) + redirect_to cert_management_admin_site_panel_index_path + end + def create_cert + @site_cert = SiteCert.create(site_cert_params) + redirect_to cert_management_admin_site_panel_index_path + end + def destroy_cert + @site_cert = SiteCert.find(params[:site_panel_id]) + @site_cert.destroy + redirect_to cert_management_admin_site_panel_index_path + end + def get_certs_for_site + site_construct = SiteConstruct.find(params[:id]) rescue nil + domain_name = site_construct.domain_name rescue "" + domain_names = domain_name.split(" ").select{|s| s.present?} + domain_names_count = domain_names.count + (0...domain_names_count).each do |i| + domain_names << domain_names[i].sub(/\w+\./,'\\*.') + end + if domain_names.count != 0 + domain_name_search_text = "(" + domain_names.join("|") + ")" + else + domain_name_search_text = "" + end + @site_certs = SiteCert.all.where(:is_valid=>true,:domain_names=>/\A#{domain_name_search_text}/) + @site_certs = SiteCert.all + if site_construct + @enable_cert_id = site_construct.site_cert_id + end + render :layout => false + end + def cert_management + @site_certs = SiteCert.all.page(params[:page]).per(10) + @filter_fields = {} + params[:keywords] = params[:keywords].to_s.gsub("*","\\*") + @site_certs = search_data(@site_certs,[:domain_names]) + if request.xhr? + render :partial => "certs_table" + end + end def update_cert_setting site_params = params.require('site').permit! if !site_params['cert_ver_file_content'].blank? @@ -52,8 +99,12 @@ class Admin::SitePanelController < OrbitAdminController SiteServer.find(params[:id]).destroy redirect_to admin_site_panel_server_manager_path elsif params[:type] == 'detect_sites' + extra_text = "" + if params[:key].present? + extra_text = "[#{params[:key]}]" + end Thread.new do - system("bundle exec rake create_site:detect_sites") + system("bundle exec rake create_site:detect_sites#{extra_text}") end render :json => {"success"=>true} elsif params[:type] == 'see_infos' @@ -95,7 +146,7 @@ class Admin::SitePanelController < OrbitAdminController password = site_server.password site_name = site_construct.site_name domain_name = site_construct.domain_name - port = site_construct.port + port = site_construct.get_port db_name = site_construct.db_name path = site_construct.path site_construct_id = site_construct.id.to_s @@ -122,7 +173,7 @@ class Admin::SitePanelController < OrbitAdminController password = site_server.password site_name = site_construct.site_name domain_name = site_construct.domain_name - port = site_construct.port + port = site_construct.get_port db_name = site_construct.db_name path = site_construct.path site_construct_id = params[:id] @@ -154,12 +205,23 @@ class Admin::SitePanelController < OrbitAdminController @site = SiteConstruct.find(params[:id]) render 'see_detail_for_created_site' and return elsif params[:type] == 'change_server_name' - cmd = "bundle exec rake create_site:change_site_server_name[#{params[:id]},'#{params[:site_construct][:domain_name]}']" - system(cmd) - redirect_to :back and return + site_construct = SiteConstruct.find(params[:id]) + 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..."]) + Thread.new do + Bundler.with_clean_env{system(cmd)} + end + redirect_to admin_site_panel_edit_site_path(:id=>params[:id],:type=>'detail',:status=>'changing') and return elsif params[:type] == 'delete_from_list' SiteConstruct.find(params[:id]).destroy redirect_to :back and return + elsif params[:type] == 'select_cert' + @site_construct = SiteConstruct.find(params[:id]) + @site_construct.update(:site_cert_id=>BSON::ObjectId(params[:site_cert_id])) + Thread.new do + system("bundle exec rake create_site:change_site_cert[#{params[:id]}]") + end else Thread.new do if params[:id].blank? && !params[:server_names].blank? @@ -181,7 +243,7 @@ class Admin::SitePanelController < OrbitAdminController @site_servers = SiteServer.all.with_categories(filters("category")) @sites = (params[:server_name].blank? ? @sites : @sites.where(:server_type=>params[:server_name])) @sites = @sites.any_in(:server_type => @site_servers.map{|s| s.server_name}) - @sites = search_data(@sites,[:domain_name,:site_name,:school_name,:status]).page(params[:page].to_i).per(10) + @sites = search_data(@sites,[:domain_name,:site_name,:school_name,:status,:port]).page(params[:page].to_i).per(10) if (params[:filters][:site_mode].present? rescue false) site_modes = params[:filters][:site_mode] if site_modes.include?("development") @@ -202,11 +264,13 @@ class Admin::SitePanelController < OrbitAdminController end end private - + def site_cert_params + site_cert_params = params.require(:site_cert).permit! rescue {} + end def site_construct_params - site_construct_params = params.require(:site_construct).permit! + site_construct_params = params.require(:site_construct).permit! rescue {} end def site_server_params - params.require(:site_server).permit! + params.require(:site_server).permit! rescue {} end end \ No newline at end of file diff --git a/app/models/site_cert.rb b/app/models/site_cert.rb new file mode 100644 index 0000000..56672e5 --- /dev/null +++ b/app/models/site_cert.rb @@ -0,0 +1,49 @@ +class SiteCert + include Mongoid::Document + include Mongoid::Timestamps + mount_uploader :cert_file, AssetUploader #Public key + mount_uploader :ca_bundle, AssetUploader + mount_uploader :private_key, AssetUploader + field :is_valid , type: Boolean ,default: false + field :domain_names , type: Array ,default: [] + field :source_paths , type: Array ,default: [] + field :start_date , type: DateTime + field :end_date , type: DateTime + has_many :site_constructs, :autosave => true + after_save :change_data + def upload_date + self.created_at.strftime("%Y/%m/%d %H:%M") rescue "" + end + def display_domain_names + self.domain_names.join("
").html_safe rescue "" + end + def generate_file_link(field_name) + f = self.send(field_name) + file_name = self[field_name] + "#{file_name}".html_safe + end + def display_start_date + self.start_date.strftime("%Y-%m-%d") rescue "" + end + def display_end_date + 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 + end +end \ No newline at end of file diff --git a/app/models/site_construct.rb b/app/models/site_construct.rb index ccb1ec3..cc2eee7 100644 --- a/app/models/site_construct.rb +++ b/app/models/site_construct.rb @@ -11,7 +11,7 @@ class SiteConstruct field :domain_name field :nginx_file field :db_name - field :port, type: String, :default => "80" + field :port, type: Array, :default => ["80"] field :path field :site_type field :school_name @@ -25,39 +25,155 @@ class SiteConstruct field :cert_ver_added_text field :cert_ver_file_content field :cert_ver_location_path + belongs_to :site_cert after_initialize do |record| - if record.status.nil? - record.status = "" - record.save + unless record.new_record? + save_flag = false + if record.status.nil? + record.status = "" + save_flag = true + end + if record.infos.nil? + record.infos = [] + save_flag = true + end + if record.nginx_file.nil? + record.nginx_file = "/etc/nginx/orbit_sites/"+record.site_name.to_s + save_flag = true + end + if record.path.nil? + dir_path = ((record.site_type == "School" && !record.school_name.blank?) ? "school_sites/#{record.school_name}" : "orbit_sites") + record.path = "/home/rulingcom/#{dir_path}" + save_flag = true + end + if record["port"].class == String + record["port"] = Array(record["port"]) + save_flag = true + end + if save_flag && !@skip_callback + @skip_callback = true + record.save(:validate=>false) + end + @skip_callback = false end - if record.infos.nil? - record.infos = [] - record.save + end + def generate_nginx_text(old_nginx_text="") + sock_text = 'upstream '+self.get_site_name+'_sock {\n'+ + ' server unix:'+self.full_site_path+'/tmp/unicorn.sock;\n'+ + '}\n' + all_ports = self.port.uniq + server_blocks = [] + if old_nginx_text.present? + all_blocks = parse_nginx_text_to_server_blocks(old_nginx_text,true) + server_blocks = all_blocks.select{|s| s.match(/\A[\s\r\n]*server\s*{/)} + upstream_block = all_blocks.select{|s| s.match(/\A[\s\r\n]*upstream/)}.first rescue nil + if upstream_block.present? + sock_text = upstream_block + '\n' + end end - if record.nginx_file.nil? - record.nginx_file = "/etc/nginx/orbit_sites/"+record.site_name.to_s - record.save + nginx_text = sock_text + all_ports.map.with_index{|port,i| + if server_blocks[i].present? + generate_server_block(port,server_blocks[i]) + else + generate_server_block(port,server_blocks[0]) + end + }.join('\n') + end + def parse_nginx_text_to_server_blocks(nginx_text,get_all_blocks=false) + num = 1 + nginx_text_tmp = nginx_text.gsub(/({|})/m){|ff| res = ff;((ff == '{') ? (res = ff * num;num = num + 1) : (num = num - 1;res = ff * num;)); res} + end_indices = nginx_text_tmp.enum_for(:scan,/^(?:}+\s?)+/m).map { Regexp.last_match.offset(0).first + 1 } + start_index = 0 + all_blocks = end_indices.map{|i| res = nginx_text_tmp[start_index..i];start_index = i + 1;res} + all_blocks = all_blocks.map{|s| s.gsub(/[{}]+/){|ff| ff[0]}.strip} + server_blocks = all_blocks.select{|s| s.match(/\A[\s\r\n]*server\s*{/)} + if get_all_blocks + all_blocks + else + server_blocks end - if record.path.nil? - dir_path = ((record.site_type == "School" && !record.school_name.blank?) ? "school_sites/#{record.school_name}" : "orbit_sites") - record.path = "/home/rulingcom/#{dir_path}" + end + def generate_server_block(port,old_server_block="") + if port.blank? + port = "80" + else + port = port.to_s end + port_text = port + if port.to_i == 443 + if self.site_cert.nil? + return "" + end + port_text += " ssl" + end + if old_server_block.present? + new_server_block = old_server_block.gsub(/(listen\s+)[^;]+/){|ff| "#{$1}#{port_text}"} + domain_name = self.domain_name + new_server_block = new_server_block.gsub(/(server_name\s+)[^;]+/m){|ff| "#{$1}#{domain_name}"} + new_server_block = new_server_block.gsub(/\s*ssl_certificate[^;]+;/,'') + if port == "443" + new_server_block = new_server_block.gsub(/(listen\s+)[^;]+;/){|ff| ff + "\n\n ssl_certificate #{self.cert_file_remote_store_path};\\n\\n ssl_certificate_key #{self.private_key_remote_store_path};\\n\\n"} + end + new_server_block = new_server_block.gsub(/\n{3,}/,'\n\n') + else + 'server {\n'+ + ' listen '+port_text+';\n\n'+ + (port == "443" ? " ssl_certificate #{self.cert_file_remote_store_path};\\n\\n ssl_certificate_key #{self.private_key_remote_store_path};\\n\\n" : '')+ + ' root '+self.full_site_path+'/public;\n\n'+ + ' server_name '+self.domain_name+';\n\n'+ + ' client_max_body_size 500m;\n\n'+ + ' location / {\n'+ + ' try_files \$uri \$uri/index.html \$uri.html @app;\n'+ + ' }\n\n'+ + ' location @app {\n'+ + ' proxy_redirect off;\n'+ + ' proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\n'+ + ' proxy_set_header Host \$http_host;\n'+ + ' proxy_connect_timeout 360;\n'+ + ' proxy_pass http://'+self.get_site_name+'_sock;\n'+ + ' }\n'+ + '}' + end + end + def display_port + self.port.map{|port| "#{port}"}.join("
").html_safe + end + def get_host_with_port(port) + self.domain_name.split().first + end + def get_port(idx=0) + self.port[idx] rescue "80" + end + def full_site_path + return "#{self.get_path}/#{self.get_site_name}" + end + def cert_file_remote_store_path + site_cert = self.site_cert + "#{self.full_site_path}/ssl_certs/#{site_cert.id}/#{site_cert["cert_file"]}" + end + def private_key_remote_store_path + site_cert = self.site_cert + "#{self.full_site_path}/ssl_certs/#{site_cert.id}/#{site_cert["private_key"]}" + end + def get_path + return self.path.to_s.gsub(" ","\\ ") end def get_site_name - return self.site_name.gsub(" ","\\ ") + return self.site_name.to_s.gsub(" ","\\ ") end - def get_domain_name + def get_domain_name(port=nil) scheme = "" extra_port = "" - if self.port == "443" + port = self.get_port if port.nil? + if port == "443" scheme = "https://" else scheme = "http://" - if self.port != "80" - extra_port = ":#{self.port}" + if port != "80" + extra_port = ":#{port}" end end - return (scheme + self.domain_name + extra_port) + return (scheme + self.domain_name.split(" ").first + extra_port) end def site_server SiteServer.where(server_name: self.server_type).first diff --git a/app/views/admin/site_panel/_cert_form.html.erb b/app/views/admin/site_panel/_cert_form.html.erb new file mode 100644 index 0000000..a3e8ade --- /dev/null +++ b/app/views/admin/site_panel/_cert_form.html.erb @@ -0,0 +1,17 @@ +
+ +
+ +
+ +
+ + <%=render :partial => "simple_form_file",:locals=>{:f=>f,:field_name=>'cert_file'}%> + <%=render :partial => "simple_form_file",:locals=>{:f=>f,:field_name=>'ca_bundle'}%> + <%=render :partial => "simple_form_file",:locals=>{:f=>f,:field_name=>'private_key'}%> +
+
+
+ <%= f.submit t('submit'), class: 'btn btn-primary' %> +
+
\ No newline at end of file diff --git a/app/views/admin/site_panel/_certs_table.html.erb b/app/views/admin/site_panel/_certs_table.html.erb new file mode 100644 index 0000000..677874c --- /dev/null +++ b/app/views/admin/site_panel/_certs_table.html.erb @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + <% @site_certs.each do |site_cert| %> + + + + + + + + + + + + <% end %> + +
<%=t('client_management.upload_date')%><%=t('client_management.status')%><%=t('client_management.start_date')%><%=t('client_management.end_date')%><%=t('client_management.domain_name')%><%=t('client_management.cert_file')%><%=t('client_management.ca_bundle')%><%=t('client_management.private_key')%><%=t('client_management.action')%>
<%=site_cert.upload_date %><%=site_cert.display_start_date %><%=site_cert.display_end_date %><%=site_cert.display_domain_names %><%=site_cert.generate_file_link('cert_file')%><%=site_cert.generate_file_link('ca_bundle')%><%=site_cert.generate_file_link('private_key')%> + <%= 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")} %> +
+
+ + <%=t('client_management.upload_cert')%> +
+ \ No newline at end of file diff --git a/app/views/admin/site_panel/_form.html.erb b/app/views/admin/site_panel/_form.html.erb index 77346e6..f22cb16 100644 --- a/app/views/admin/site_panel/_form.html.erb +++ b/app/views/admin/site_panel/_form.html.erb @@ -103,7 +103,12 @@
<%= f.label :port ,"Port Number", :class => "control-label muted" %>
- <%= f.number_field :port, :min => 1, :id => "port", :value => 80 %> +
+ <%= number_field_tag("#{f.object_name}[port][]",f.object.port.first, :min => 1, :id => nil) %> +
+
+
+
@@ -120,6 +125,18 @@ + \ 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 794775b..b012601 100644 --- a/app/views/admin/site_panel/_server_manager_index.html.erb +++ b/app/views/admin/site_panel/_server_manager_index.html.erb @@ -25,6 +25,7 @@ "><%=t(:edit)%> ';}"><%=t(:remove)%> "><%= t('client_management.see_sites') %> + Detect sites <% end %> @@ -32,9 +33,10 @@
- See infos + See detect infos + See exec infos "><%=t(:add)%> - Detect sites + Detect sites Exec commands
\ 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 8732775..1ea5c42 100644 --- a/app/views/admin/site_panel/_sites_list_table.html.erb +++ b/app/views/admin/site_panel/_sites_list_table.html.erb @@ -15,15 +15,15 @@ <%=site.server_type%> <% site.domain_name.split(" ").each_with_index do |domain_name,i| %> - <% domain_link = ((site.port.to_s == "443") ? "https" : "http") + '://' + domain_name + ((site.port.to_s != '80' && site.port.to_s != '443') ? ':'+site.port.to_s : '') %> + <% domain_link = ((site.get_port.to_s == "443") ? "https" : "http") + '://' + domain_name + ((site.get_port.to_s != '80' && site.get_port.to_s != '443') ? ':'+site.get_port.to_s : '') %> <% if i!=0 %>
<% end %> - <%= link_to domain_name, domain_link, :title => "open #{domain_link} to new window", :target=>"_blank" %> + <%= link_to domain_name, domain_link, :title => "Open #{domain_link} in new window", :target=>"_blank" %> <% end %> - <%=site.port%> + <%=site.display_port%> <%= (site.status.blank? ? "not yet create" : status_relation[site.status]) %> site.domain_name})%>" class="btn btn-primary see_infos" data-id="<%=site.id.to_s%>"><%=t('client_management.see_logs')%> @@ -54,17 +54,20 @@ <%= form_for site, as: 'site', url: "/#{I18n.locale}/admin/site_panel/update_cert_setting",method: "post" do |f| %>
CSR txt path:  - <%= f.text_field 'cert_ver_location_path',style: 'width: calc(100% - 8em);margin: 0;' %> + <%= f.text_field 'cert_ver_location_path',style: 'width: calc(100% - 8em);margin: 0;',:id=>nil %>
CSR txt content:  - <%= f.text_area 'cert_ver_file_content',class: 'ckeditor',value: site.cert_ver_file_content.to_s.gsub("\n",'
') %> + <%= f.text_area 'cert_ver_file_content',class: 'ckeditor',value: site.cert_ver_file_content.to_s.gsub("\n",'
'),:id=>nil %>
- <%= f.hidden_field 'id' %> + <%= f.hidden_field 'id',:id=>nil %> <%= f.submit 'edit',class: 'btn btn-primary' %> <% end %> <% end %> + <% if site.status != "" %> + <%=t('client_management.https_setting')%> + <% end %> <% end %> @@ -112,15 +115,19 @@ }); if(new_params_text[new_params_text.length -1] == "&") new_params_text = new_params_text.substr(0,new_params_text.length - 1) - if(params["id"] == id){ + if(params["id"] == id || window.refresh_flag){ close_info = true; window.location.href = window.location.href.replace(window.location.search,new_params_text); } + }else if(status == "changing"){ + window.refresh_flag = true } $(".see_infos[data-id="+id+"]").parent().siblings(".site_status").html(status_text); //msg_end.scrollIntoView(); timeout_id = window.setTimeout(see_infos(id),1000); } + }).fail(function() { + window.location.reload(); }) }else{ window.clearTimeout(timeout_id); @@ -130,7 +137,7 @@ close_info = true; window.clearTimeout(timeout_id); close_info = false; - var id = $(item).attr("data-id"); + var id = $(item).data("id"); if($("#dialog-confirm").length == 0){ $("#main-wrap").before("
"+ "
"+see_infos(id)+"
"+ @@ -160,6 +167,8 @@ var item = this; $.post("<%= admin_site_panel_create_site_path %>",{'id': id}).done(function(){ show_infos_dialog(item); + }).fail(function() { + window.location.reload(); }) }); $('.recreate_site').click(function(){ @@ -172,6 +181,8 @@ var item = this; $.post("<%= admin_site_panel_create_site_path %>",{'id': id}).done(function(){ show_infos_dialog(item); + }).fail(function() { + window.location.reload(); }) } } @@ -224,6 +235,40 @@ } } }); + $(".https_setting").click(function(){ + var id = $(this).data("id"); + var item = this; + if($("#https_setting-dialog-confirm").length == 0){ + $("#main-wrap").before("
" + +"
"+ + "
"); + } + $('#https_setting_area').attr('data-id',id); + $.get("<%=get_certs_for_site_admin_site_panel_index_path%>",{id: id}).done(function(html){ + $('#https_setting_area').html(html); + $( "#https_setting-dialog-confirm" ).dialog({ + resizable: true, + minHeight: 300, + maxHeight: 400, + modal: true, + width: '80%', + close: function(){$( this ).dialog( "close" );}, + buttons: { + "<%= t(:submit) %>": function(){ + var site_cert_id = $('#https_setting_area input: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}).done(function(response){ + console.log(response); + show_infos_dialog(item); + }); + } + $( this ).dialog( "close" ); + }, + } + }); + }) + }) $('.close_site').click(function(){ var item = this; $.post("<%=admin_site_panel_edit_site_path%>",{'id':$(this).attr("data-id"),'type':'close'}).done(function(){ diff --git a/app/views/admin/site_panel/cert_management.html.erb b/app/views/admin/site_panel/cert_management.html.erb new file mode 100644 index 0000000..c1cc8ac --- /dev/null +++ b/app/views/admin/site_panel/cert_management.html.erb @@ -0,0 +1,25 @@ +<%= javascript_include_tag "lib/jquery-ui-1.12.1/jquery-ui" %> +<%= stylesheet_link_tag "lib/jquery-ui-1.12.1/jquery-ui" %> +<% content_for :page_specific_javascript do %> + <%= javascript_include_tag "lib/module-area" %> +<% end %> +<% content_for :page_specific_css do %> + <%= stylesheet_link_tag "lib/main-forms" %> + <%= stylesheet_link_tag "lib/main-list" %> + <%= stylesheet_link_tag "lib/pageslide" %> + +<% end %> +<% if !params[:id].blank? %> +
+
+
+
+<% end %> +<%= render :partial => "sites_list_filter", :locals =>{:fields => @filter_fields, :search_dom_id=>"index_table", :quick_new=>false} %> + + <%= render :partial=>'certs_table' %> + \ No newline at end of file diff --git a/app/views/admin/site_panel/edit_cert.html.erb b/app/views/admin/site_panel/edit_cert.html.erb new file mode 100644 index 0000000..b703c89 --- /dev/null +++ b/app/views/admin/site_panel/edit_cert.html.erb @@ -0,0 +1,3 @@ +<%= form_for @site_cert ,:url=>{:action=>"update_cert"},:method=>:post, :html => {:class=>"form-horizontal main-forms"} do |f|%> + <%= render :partial => 'cert_form',:locals=>{:f=>f} %> +<% end %> \ No newline at end of file diff --git a/app/views/admin/site_panel/get_certs_for_site.html.erb b/app/views/admin/site_panel/get_certs_for_site.html.erb new file mode 100644 index 0000000..f0e91a9 --- /dev/null +++ b/app/views/admin/site_panel/get_certs_for_site.html.erb @@ -0,0 +1,22 @@ +<% if @site_certs.count == 0 %> + <%= link_to t('client_management.upload_cert'),upload_cert_admin_site_panel_index_path, :target=>"_blank" %> +<% else %> + + + + + + + + + <% @site_certs.each do |site_cert| %> + + + + + + + <% end %> + +
<%=t('client_management.upload_date')%><%=t('client_management.start_date')%>/<%=t('client_management.end_date')%><%=t('client_management.domain_name')%>
<%=radio_button_tag("site_cert",site_cert.id,site_cert.id == @enable_cert_id)%><%=site_cert.upload_date %><%=site_cert.display_start_date %> / <%=site_cert.display_end_date %><%=site_cert.display_domain_names %>
+<% end %> \ No newline at end of file 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 d407e0d..6c80f36 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 @@ -1,3 +1,5 @@ +<%= javascript_include_tag "lib/jquery-ui-1.12.1/jquery-ui" %> +<%= stylesheet_link_tag "lib/jquery-ui-1.12.1/jquery-ui" %>
">
@@ -23,7 +25,22 @@
-
<%=@site.port%>
+
+
+ <%= number_field_tag("site_construct[port][]",@site.get_port, :min => 1, :id => nil) %> +
+
+
+ <% @site.port[1..-1].each do |port| %> +
+ X + <%= number_field_tag("site_construct[port][]",port, :min => 1, :id => nil) %> +
+
+ <% end %> +
+ +
@@ -56,11 +73,84 @@ <%= hidden_field_tag 'id',@site.id %> <%= hidden_field_tag 'type','change_server_name' %> <%=t(:back)%> - + " class="btn btn-primary btn-danger">
+<% if params[:status] == "changing" %> + +<% end %> + \ No newline at end of file diff --git a/app/views/admin/site_panel/upload_cert.html.erb b/app/views/admin/site_panel/upload_cert.html.erb new file mode 100644 index 0000000..432aab4 --- /dev/null +++ b/app/views/admin/site_panel/upload_cert.html.erb @@ -0,0 +1,3 @@ +<%= form_for @site_cert ,:url=>{:action=>"create_cert"},:method=>:post, :html => {:class=>"form-horizontal main-forms"} do |f|%> + <%= render :partial => 'cert_form',:locals=>{:f=>f} %> +<% end %> \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 1eed249..dc7f2b0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3,8 +3,22 @@ en: client_management: Client Management restful_actions: server_manager: Server Manager - site_list: Site List + sites_list: Site List + upload_cert: Upload Cert + cert_management: Cert Management client_management: + start_date: Start Date + end_date: End Date + change_setting: Change Setting + upload_cert: Upload Cert + https_setting: https Setting + change_file: Change File + select_file: Select File + upload_date: Upload date + private_key: Private key + cert_file: Public key + ca_bundle: Ca Bundle + cert_management: Cert Management development: Development production: Production site_mode: Site mode diff --git a/config/locales/zh_tw.yml b/config/locales/zh_tw.yml index 5059ea1..cbce610 100644 --- a/config/locales/zh_tw.yml +++ b/config/locales/zh_tw.yml @@ -3,8 +3,22 @@ zh_tw: client_management: 網站管理系統 restful_actions: server_manager: 伺服器管理 - site_list: 網站列表 + sites_list: 網站列表 + upload_cert: 上傳憑證 + cert_management: 憑證管理 client_management: + start_date: 開始日期 + end_date: 結束日期 + change_setting: 變更設定 + upload_cert: 上傳憑證 + https_setting: https設定 + change_file: 更換檔案 + select_file: 選擇檔案 + upload_date: 上傳日期 + private_key: 私鑰(Private key,key檔案) + cert_file: 憑證檔案(Public key,crt檔案) + ca_bundle: 中繼憑證(Ca Bundle,crt檔案) + cert_management: 憑證管理 development: 開發者模式 production: 產品模式 site_mode: 網站模式 diff --git a/config/routes.rb b/config/routes.rb index 2e548c1..0f53110 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -49,7 +49,19 @@ Rails.application.routes.draw do get "site_panel/edit_server_info" => "site_panel#edit_server_info" post "site_panel/edit_server_info" => "site_panel#edit_server_info" post "site_panel/update_cert_setting" => "site_panel#update_cert_setting" - resources :site_panel + resources :site_panel do + delete 'destroy_cert' + get 'edit_cert' + post 'update_cert' + patch 'update_cert' + collection do + get 'cert_management' + get 'upload_cert' + get 'get_certs_for_site' + post 'create_cert' + patch 'create_cert' + end + end end diff --git a/lib/client_management/engine.rb b/lib/client_management/engine.rb index 2cb09dc..207a64c 100644 --- a/lib/client_management/engine.rb +++ b/lib/client_management/engine.rb @@ -20,37 +20,42 @@ module ClientManagement :link_path=>"admin_client_managements_path" , :priority=>1, :active_for_action=>{'admin/client_managements'=>"index"}, - :available_for => 'users' + :available_for => 'admin' context_link 'client_management.completed_requests', :link_path=>"completed_requests_admin_client_managements_path" , :priority=>1, :active_for_action=>{'admin/client_managements'=>"completed_requests"}, - :available_for => 'users' + :available_for => 'admin' context_link 'client_management.contracts', :link_path=>"contracts_admin_client_managements_path" , :priority=>1, :active_for_action=>{'admin/client_managements'=>"contracts"}, - :available_for => 'users' + :available_for => 'admin' + context_link 'client_management.cert_management', + :link_path=>"cert_management_admin_site_panel_index_path" , + :priority=>1, + :active_for_action=>{'admin/site_panel'=>"cert_management"}, + :available_for => 'admin' context_link 'client_management.create_site', :link_path=>"admin_site_panel_path" , :priority=>1, :active_for_action=>{'admin/site_panel'=>"index"}, - :available_for => 'users' + :available_for => 'admin' context_link 'client_management.sites_list', :link_path=>"admin_site_panel_sites_list_path" , :priority=>1, :active_for_action=>{'admin/site_panel'=>"sites_list"}, - :available_for => 'users' + :available_for => 'admin' context_link 'client_management.server_manager', :link_path=>"admin_site_panel_server_manager_path" , :priority=>1, :active_for_action=>{'admin/site_panel'=>"server_manager"}, - :available_for => 'users' + :available_for => 'admin' end end end diff --git a/lib/tasks/add_cert_ver_for_site.rake b/lib/tasks/add_cert_ver_for_site.rake index 4463364..1e5d3cc 100644 --- a/lib/tasks/add_cert_ver_for_site.rake +++ b/lib/tasks/add_cert_ver_for_site.rake @@ -20,7 +20,7 @@ namespace :create_site do file_path = "#{site_construct.path}/#{site_construct.site_name}/tmp/#{file_name}" site_construct.cert_ver_added_text = " location #{location_path}{#add_by_site_module\n alias #{file_path};\n }" site_construct.save - server_array = nginx_config.scan(/^[ \t]*server[ \t]*{(?:(?!server[ \t]*{).)+}/m) + server_array = site_construct.parse_nginx_text_to_server_blocks(nginx_config) server_array.each do |server| tmp = server[0...-1] + site_construct.cert_ver_added_text + "\n}" nginx_config = nginx_config.sub(server,tmp) diff --git a/lib/tasks/change_site_cert.rake b/lib/tasks/change_site_cert.rake new file mode 100644 index 0000000..e06b86b --- /dev/null +++ b/lib/tasks/change_site_cert.rake @@ -0,0 +1,58 @@ +require 'net/ssh' +require 'pathname' +require 'json' +namespace :create_site do + desc "Change Site Cert" + task :change_site_cert,[:id] => :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") + if !site_server.nil? && !@site_cert.nil? + @password = site_server.password + Net::SSH.start(site_server.ip , site_server.account , password: site_server.password) do |ssh| + 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) + puts nginx_file_content + exec_ssh_command_by_sudo(ssh,"service nginx restart") + update_infos("Finish!") + @site_construct.update(:status=>"finish") + end + else + update_infos("Cert not found!") + @site_construct.update(:status=>"error") + end + rescue => e + puts [e,e.backtrace] + update_infos(e.to_s) + @site_construct.update(:status=>"error") + end + end + def exec_command_by_user(session,command) + output = session.exec!(command) + return output[0...-1].gsub(/^\n[\n]+/,'') + end + def exec_ssh_command_by_sudo(session,command) + output = session.exec!("echo '#{@password}' | sudo -S #{command}") + if output.include?("sudo:") && output.include?("command not found") + output = session.exec!(command) + end + return output + 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 e565a4b..dcf25d8 100644 --- a/lib/tasks/change_site_server_name.rake +++ b/lib/tasks/change_site_server_name.rake @@ -1,24 +1,35 @@ require 'net/ssh' require 'pathname' +require 'json' namespace :create_site do desc "Change Site Server Name" - task :change_site_server_name,[:id,:server_name] => :environment do |task,args| + task :change_site_server_name,[:id,:server_name,:port] => :environment do |task,args| begin - site_construct = SiteConstruct.find(args.id) - site_server = site_construct.site_server + @site_construct = SiteConstruct.find(args.id) + site_server = @site_construct.site_server if !site_server.nil? @password = site_server.password + update_infos("Starting change domain name and ports.") Net::SSH.start(site_server.ip , site_server.account , password: site_server.password) do |ssh| - nginx_file_content = exec_command_by_user(ssh,"cat #{site_construct.nginx_file}") - nginx_file_content = nginx_file_content.gsub(/^[ \t]*server_name[ \t]+.*;/," server_name #{args.server_name};") - puts nginx_file_content - cmd = "x='#{nginx_file_content}'; echo '#{@password}' | sudo -S sh -c \"echo '$x' > #{site_construct.nginx_file}\"" + @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!") + @site_construct.update(:status=>'finish') end - site_construct.update(:domain_name=>args.server_name) end rescue => e + update_infos(e.to_s) + @site_construct.update(:status=>'error') puts [e,e.backtrace] end end diff --git a/lib/tasks/copy_site.rake b/lib/tasks/copy_site.rake index 5cd8011..3aba242 100644 --- a/lib/tasks/copy_site.rake +++ b/lib/tasks/copy_site.rake @@ -32,25 +32,7 @@ namespace :create_site do end Net::SSH.start(args.ip , args.user , password: args.password) do |ssh| update_infos("setting nginx for #{args.site_name}") - nginx_setting_texts = ('upstream '+@site_construct.get_site_name+'_sock {\n'+ - ' server unix:'+args.path+'/'+@site_construct.get_site_name+'/tmp/unicorn.sock;\n'+ - '}\n'+ - 'server {\n'+ - ' listen '+args.port+';\n\n'+ - ' root '+args.path+'/'+@site_construct.get_site_name+'/public;\n\n'+ - 'server_name '+args.domain_name+';\n\n'+ - ' client_max_body_size 500m;\n\n'+ - ' location / {\n'+ - ' try_files \$uri \$uri/index.html \$uri.html @app;\n'+ - ' }\n\n'+ - ' location @app {\n'+ - ' proxy_redirect off;\n'+ - ' proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\n'+ - ' proxy_set_header Host \$http_host;\n'+ - ' proxy_connect_timeout 360;\n'+ - 'proxy_pass http://'+@site_construct.get_site_name+'_sock;\n'+ - ' }\n'+ - '}') + nginx_setting_texts = @site_construct.generate_nginx_text exec_ssh_command_by_sudo_for_create(ssh,"touch /etc/nginx/orbit_sites/#{@site_construct.get_site_name}") exec_ssh_command_by_sudo_for_create(ssh,"sh -c \"echo '#{nginx_setting_texts}' > /etc/nginx/orbit_sites/#{@site_construct.get_site_name}\"") update_infos("restarting nginx") diff --git a/lib/tasks/create_site.rake b/lib/tasks/create_site.rake index bc43017..d4f5cff 100644 --- a/lib/tasks/create_site.rake +++ b/lib/tasks/create_site.rake @@ -31,25 +31,7 @@ namespace :create_site do end Net::SSH.start(args.ip , args.user , password: args.password) do |ssh| update_infos("setting nginx for #{args.site_name}") - nginx_setting_texts = ('upstream '+@site_construct.get_site_name+'_sock {\n'+ - ' server unix:'+args.path+'/'+@site_construct.get_site_name+'/tmp/unicorn.sock;\n'+ - '}\n'+ - 'server {\n'+ - ' listen '+args.port+';\n\n'+ - ' root '+args.path+'/'+@site_construct.get_site_name+'/public;\n\n'+ - 'server_name '+args.domain_name+';\n\n'+ - ' client_max_body_size 500m;\n\n'+ - ' location / {\n'+ - ' try_files \$uri \$uri/index.html \$uri.html @app;\n'+ - ' }\n\n'+ - ' location @app {\n'+ - ' proxy_redirect off;\n'+ - ' proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\n'+ - ' proxy_set_header Host \$http_host;\n'+ - ' proxy_connect_timeout 360;\n'+ - 'proxy_pass http://'+@site_construct.get_site_name+'_sock;\n'+ - ' }\n'+ - '}') + nginx_setting_texts = @site_construct.generate_nginx_text exec_ssh_command_by_sudo_for_create(ssh,"touch /etc/nginx/orbit_sites/#{@site_construct.get_site_name}") exec_ssh_command_by_sudo_for_create(ssh,"sh -c \"echo '#{nginx_setting_texts}' > /etc/nginx/orbit_sites/#{@site_construct.get_site_name}\"") update_infos("restarting nginx") diff --git a/lib/tasks/detect_sites.rake b/lib/tasks/detect_sites.rake index c694d5e..d62bc25 100644 --- a/lib/tasks/detect_sites.rake +++ b/lib/tasks/detect_sites.rake @@ -1,10 +1,12 @@ require 'net/ssh' require 'pathname' +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 if @thread.nil? begin @@ -47,6 +49,8 @@ namespace :create_site do server_name_list << server_name_for_site end server_name = server_name_list.join(' ') + nginx_file_content = exec_ssh_command_by_sudo_and_see_output(ssh,"cat #{nginx_file}",false) + nginx_file_content = nginx_file_content.join('\n') if nginx_file_content.class == Array site_path = Pathname.new(exec_ssh_command_by_sudo(ssh,"echo `grep root #{nginx_file} | grep -v -e '#.*root'`").to_s.split("\n").first.to_s.strip.split("root").last.to_s.gsub(";","").strip).dirname.to_s if site_path.present? && exec_ssh_command_by_sudo(ssh,"ls #{site_path}").split.length != 0 && exec_ssh_command_by_sudo(ssh,"ls #{site_path}/Gemfile").include?("No such file or directory") SiteConstruct.where(:server_type => @site_server.server_name , :domain_name=>server_name).destroy @@ -55,7 +59,7 @@ namespace :create_site do path = Pathname.new(site_path).dirname.to_s site_name = Pathname.new(site_path).basename.to_s server_type = @site_server.server_name - port = exec_ssh_command_by_sudo(ssh,"echo `grep 'listen' #{nginx_file} | grep -v -e '#.*listen'`").split("\n").first.strip.split("listen").last.strip.split(";").first.split.select{|p| p.strip == p.strip.to_i.to_s}.first.strip rescue "80" + port = exec_ssh_command_by_sudo_and_see_output(ssh,"grep 'listen' #{nginx_file} | grep -v -e '#.*listen'",false).flat_map{|s| s.split(/(\r\n|\n)/)}.map{|s| s.match(/listen\s+(\d+)/)[1] rescue nil}.select{|s| s.present?}.uniq db_name = exec_ssh_command_by_sudo(ssh,"echo `cat #{site_path}/config/mongoid.yml | grep 'database'`").split("database:").last.strip db_name = site_name.gsub("-","_") if db_name.include?("No such file or directory") unicorn_sock_path = exec_ssh_command_by_sudo(ssh,"echo `grep 'server unix' #{nginx_file} | grep -v -e '#.*server unix'`").strip.split("server unix").last.strip.split(":").last.strip rescue (site_path+"/tmp/unicorn.sock") @@ -77,13 +81,13 @@ namespace :create_site do status = "closed" end end - site_constructs = SiteConstruct.where(:server_type => server_type , :domain_name.in => [server_name,*server_name_list]).to_a + site_constructs = SiteConstruct.where(:server_type => server_type , :nginx_file=>nginx_file).to_a site_construct = site_constructs[0] Array(site_constructs[1..-1]).each do |s| s.destroy end cert_ver_added_text = exec_command_by_user(ssh,"cat #{nginx_file}").scan(/[ \t]*location(?:(?!location.*{).)+{#add_by_site_module.*}/m)[0] - update_thread_infos("Detect #{server_name}".html_safe) + update_thread_infos("Detect #{server_name}".html_safe) if site_construct.nil? site_construct = SiteConstruct.create(:server_type=>server_type,:site_name=>site_name,:domain_name=>server_name,:nginx_file=>nginx_file,:db_name=>db_name,:port=>port,:path=>path,:site_type=>site_type,:school_name=>school_name,:user_id=>User.first.id,:status=>status,:cert_ver_added_text=>cert_ver_added_text) else @@ -103,6 +107,31 @@ 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 '' + site_cert = nil + if crt_file_path.present? || private_key_path.present? + site_cert = site_construct.site_cert + 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.save + site_construct.update(:site_cert=>site_cert) + end + end end end end