add multiple domain name feature

This commit is contained in:
chiu 2021-02-18 00:59:11 +08:00
parent 9a6ebf3b65
commit a7bdee0b5b
9 changed files with 275 additions and 105 deletions

View File

@ -131,6 +131,10 @@ class Admin::SitePanelController < OrbitAdminController
elsif params[:type] == 'detail'
@site = SiteConstruct.find(params[:id])
render 'see_detail_for_created_site' and return
elsif params[:type] == 'change_server_name'
cmd = "rake create_site:change_site_server_name[#{params[:id]},'#{params[:site_construct][:domain_name]}']"
system(cmd)
redirect_to :back and return
elsif params[:type] == 'delete_from_list'
SiteConstruct.find(params[:id]).destroy
redirect_to :back and return

View File

@ -51,4 +51,7 @@ class SiteConstruct
end
return (scheme + self.domain_name + extra_port)
end
def site_server
SiteServer.where(server_name: self.server_type).first
end
end

View File

@ -39,10 +39,13 @@
<div class="control-group">
<%= f.label :root_domain ,"Root Domain", :class => "control-label muted" %>
<div class="controls">
<%= select_tag :root_domain,
options_for_select(SiteServer.first.domain_names.collect{ |u| [u, u] }),
:id => "root_domain" %>
<div class="controls" id="root_domain_group">
<div class="root_domain_group">
<%= select_tag :root_domain,
options_for_select(SiteServer.first.domain_names.collect{ |u| [u, u] }),
:class => "root_domain" %>
</div>
<%= button_tag 'add root domain',:type => 'button', :id => 'add_root_domain',class: 'btn btn-info',:style => 'margin-top: 1em;' %>
</div>
</div>
@ -72,7 +75,12 @@
<div class="control-group">
<%= f.label :domain_name ,"Domain Name", :class => "control-label muted" %>
<div class="controls">
<%= f.text_field :domain_name, :id => "domain_name",:disabled => 'disabled' %>
<div class="domain_group">
<input type="text" onchange="change_domain_input(this)">
<span class="root_domain_text"><%= SiteServer.first.domain_names[0] %></span>
<%= hidden_field_tag nil,nil, :class => "domain_name",:id=>nil %>
</div>
<%= f.hidden_field :domain_name %>
<!--<div class="hint">schoolname-deptname.pending.rulingcom.com eg: nctu-eed.pending.rulingcom.com</div>-->
</div>
</div>
@ -107,12 +115,29 @@
</fieldset>
<script type="text/javascript">
var domain_name_relations = {};
var pre_site_name = '';
<% SiteServer.all.each do |server_server| %>
domain_name_relations['<%= server_server.server_name %>'] = <%= server_server.domain_names.inspect.html_safe %>;
<% end %>
console.log(domain_name_relations);
function change_domain_name(domain_name){
$("#domain_name").val($("#site_name").val().replace("_","-") + "."+domain_name);
function unique(array) {
return $.grep(array, function(el, index) {
return index == $.inArray(el, array);
});
}
function change_domain_name(index){
if (index=='all'){
for (var i=0;i<$('.domain_group').length;i++){
change_domain_name(i)
}
}else{
var $input = $('.domain_group').eq(index).find('input[type="text"]');
var current_root_domain_text = $('.root_domain_group').eq(index).find('select').val()
if ($input.val()==pre_site_name){
$input.val($("#site_name").val().replace("_","-") + ".");
}
$('.domain_group').eq(index).find('input[type="hidden"]').val($('.domain_group').eq(index).find('input[type="text"]').val()+current_root_domain_text)
$('.root_domain_text').eq(index).val(current_root_domain_text)
}
}
$("#school_name").on("blur",function(){
var school = $(this).val().toLowerCase();
@ -136,31 +161,41 @@
$("#path").val("/home/rulingcom/" + type);
}
})
$("#root_domain").change(function(){
change_domain_name($(this).val());
})
function add_change_event_for_root_domain(){
$(".root_domain").off('change')
$(".root_domain").change(function(){
change_domain_name($(this).index('.root_domain'));
})
}
add_change_event_for_root_domain()
$('#site_construct_server_type').change(function(){
var domain_name = domain_name_relations[$(this).val()][0];
var domain_names = domain_name_relations[$(this).val()];
$("#root_domain").find('option').remove()
if ($(".root_domain").length>1){
for (var i=1;i<$(".root_domain").length;i++){
$(".root_domain").eq(i).remove()
}
}
$(".root_domain").find('option').remove()
$.each(domain_names,function(i,v){
var o = new Option(v, v);
/// jquerify the DOM object 'o' so we can use the html method
$(o).html(v);
$("#root_domain").append(o);
$(".root_domain").eq(0).append(o);
})
if ($("#site_name").val()!=''){
change_domain_name(domain_name);
change_domain_name(0);
}
//$('#domain_name').siblings('.hint').html('schoolname-deptname.'+domain_name+' eg: nctu-eed.'+domain_name);
})
$("#site_name").on("blur",function(){
var val = $(this).val(),
type = $("#site_construct_site_type").val(),
school = $("#school_name").val(),
domain_name = $("#root_domain").val();
school = $("#school_name").val();
//$('#domain_name').siblings('.hint').html('schoolname-deptname.'+domain_name+' eg: nctu-eed.'+domain_name);
change_domain_name(domain_name);
change_domain_name('all');
pre_site_name = val.replace("_","-")+'.';
$("#db_name").val(val);
type = (type == "School" ? "school_sites" : "orbit_sites" );
if(school != ""){
@ -169,7 +204,27 @@
$("#path").val("/home/rulingcom/" + type);
}
})
function change_domain_input(ele){
change_domain_name($(ele).parents('.domain_group').index('.domain_group'))
}
$("#site_construct_site_type").val("School");
function delete_domain(ele){
$('.domain_group').eq($(ele).parents('.root_domain_group').index('.root_domain_group')).remove()
$(ele).parents('.root_domain_group').remove()
}
$('#add_root_domain').click(function(){
var first_domain_group = $('#root_domain_group .root_domain_group').first()
var clone_domain_group = $(first_domain_group).clone()
clone_domain_group.find('select').val(clone_domain_group.find('select option:first').val())
clone_domain_group.append("<button class=\"btn btn-danger\" onclick=\"delete_domain(this)\">delete domain</button>")
$('#root_domain_group .root_domain_group').last().after(clone_domain_group)
var clone_input_group = $('.domain_group').last().clone()
clone_input_group.find('input[type="text"]').val(pre_site_name)
clone_input_group.find('input[type="hidden"]').val(pre_site_name+clone_domain_group.find('select').val())
clone_input_group.find('.root_domain_text').val(clone_domain_group.find('select').val())
$('.domain_group').last().after(clone_input_group)
//add_change_event_for_root_domain()
})
$("form.main-forms").submit(function(){
$("#domain_name").removeAttr('disabled');
$("#path").removeAttr("disabled");
@ -181,6 +236,11 @@
}else{
$("#path").val("/home/rulingcom/" + type);
}
$('#site_construct_domain_name').val(unique(
$.map($('.domain_name'),function(v,i){
return $(v).val()
})
).join(' '))
console.log($("#path").val());
})
</script>

View File

@ -13,7 +13,16 @@
<% @sites.each do |site|%>
<tr>
<td><%=site.server_type%></td>
<td><a href="<%=((site.port.to_s == "443") ? "https" : "http")%>://<%=site.domain_name%><%=((site.port.to_s != '80' && site.port.to_s != '443') ? ':'+site.port.to_s : '')%>" title="open <%=((site.port.to_s == "443") ? "https" : "http")%>://<%=site.domain_name%><%=((site.port.to_s != '80' && site.port.to_s != '443') ? ':'+site.port.to_s : '')%> to new window" target="_blank"><%=site.domain_name%></a></td>
<td>
<% 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 : '') %>
<% if i!=0 %>
<br>
<% end %>
<%= link_to domain_name, domain_link, :title => "open #{domain_link} to new window", :target=>"_blank" %>
<% end %>
</td>
<td><%=site.port%></td>
<td class="site_status"><%= (site.status.blank? ? "not yet create" : status_relation[site.status]) %></td>
<td>

View File

@ -1,45 +1,88 @@
<div class="form-horizontal">
<div class="control-group">
<label class="control-label">Server</label>
<div class="controls"><%=@site.server_type%></div>
</div>
<div class="control-group">
<label class="control-label">Domain name</label>
<div class="controls"><%=@site.domain_name%></div>
</div>
<div class="control-group">
<label class="control-label">Port</label>
<div class="controls"><%=@site.port%></div>
</div>
<div class="control-group">
<label class="control-label">Site type</label>
<div class="controls"><%=@site.site_type%></div>
</div>
<% if @site.site_type == "School"%>
<form method="get" action="<%= "/#{I18n.locale}/admin/site_panel/edit_site" %>">
<div class="control-group">
<label class="control-label">School name</label>
<div class="controls"><%=@site.school_name%></div>
<label class="control-label">Server</label>
<div class="controls"><%=@site.server_type%></div>
</div>
<% end %>
<div class="control-group">
<label class="control-label">Site name</label>
<div class="controls"><%=@site.site_name%></div>
</div>
<div class="control-group">
<label class="control-label">Database name</label>
<div class="controls"><%=@site.db_name%></div>
</div>
<div class="control-group">
<label class="control-label">Nginx file</label>
<div class="controls"><%=@site.nginx_file%></div>
</div>
<div class="control-group">
<label class="control-label">Site path</label>
<div class="controls"><%=@site.path%></div>
</div>
<div class="control-group">
<div class="controls">
<a href="<%=admin_site_panel_sites_list_path%>" class="btn btn-primary"><%=t(:back)%></a>
<div class="control-group">
<label class="control-label">Domain name</label>
<div class="controls">
<% @site.domain_name.split(' ').each_with_index do |domain_name,i| %>
<div class="domain_group">
<%= text_field_tag nil,domain_name,:class=>'domain_name',onchange: 'domain_name_change()' %>
<% if i != 0 %>
<button class="btn btn-danger" onclick="delete_domain(this)">
delete domain
</button>
<% end %>
</div>
<% end %>
<%= button_tag 'add domain',:type => 'button', :id => 'add_root_domain',class: 'btn btn-info',:style => 'margin-top: 1em;' %>
<%= hidden_field_tag 'site_construct[domain_name]',@site.domain_name,id: 'site_construct_domain_name' %>
</div>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label">Port</label>
<div class="controls"><%=@site.port%></div>
</div>
<div class="control-group">
<label class="control-label">Site type</label>
<div class="controls"><%=@site.site_type%></div>
</div>
<% if @site.site_type == "School"%>
<div class="control-group">
<label class="control-label">School name</label>
<div class="controls"><%=@site.school_name%></div>
</div>
<% end %>
<div class="control-group">
<label class="control-label">Site name</label>
<div class="controls"><%=@site.site_name%></div>
</div>
<div class="control-group">
<label class="control-label">Database name</label>
<div class="controls"><%=@site.db_name%></div>
</div>
<div class="control-group">
<label class="control-label">Nginx file</label>
<div class="controls"><%=@site.nginx_file%></div>
</div>
<div class="control-group">
<label class="control-label">Site path</label>
<div class="controls"><%=@site.path%></div>
</div>
<div class="control-group">
<div class="controls">
<%= hidden_field_tag 'id',@site.id %>
<%= hidden_field_tag 'type','change_server_name' %>
<a href="<%=admin_site_panel_sites_list_path%>" class="btn btn-primary"><%=t(:back)%></a>
<input type="submit" value="change domain" class="btn btn-primary">
</div>
</div>
</form>
</div>
<script type="text/javascript">
function unique(array) {
return $.grep(array, function(el, index) {
return index == $.inArray(el, array);
});
}
function domain_name_change(){
$('#site_construct_domain_name').val(unique(
$.map($('.domain_name'),function(v,i){
return $(v).val()
})
).join(' '))
}
$('#add_root_domain').click(function(){
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.append("<button class=\"btn btn-danger\" onclick=\"delete_domain(this)\">delete domain</button>")
$('.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()
}
</script>

View File

@ -7,6 +7,11 @@
<%= stylesheet_link_tag "lib/main-forms" %>
<%= stylesheet_link_tag "lib/main-list" %>
<%= stylesheet_link_tag "lib/pageslide" %>
<style type="text/css">
.ui-dialog {
z-index: 100000000000 !important;
}
</style>
<% end %>
<%= render_filter @filter_fields, "index_table" %>
<span id="index_table">

View File

@ -7,6 +7,11 @@
<%= stylesheet_link_tag "lib/main-forms" %>
<%= stylesheet_link_tag "lib/main-list" %>
<%= stylesheet_link_tag "lib/pageslide" %>
<style type="text/css">
.ui-dialog {
z-index: 100000000000 !important;
}
</style>
<% end %>
<% if !params[:id].blank? %>
<div id='dialog-confirm' title='site infos'>

View File

@ -0,0 +1,32 @@
require 'net/ssh'
require 'pathname'
namespace :create_site do
desc "Change Site Server Name"
task :change_site_server_name,[:id,:server_name] => :environment do |task,args|
begin
site_construct = SiteConstruct.find(args.id)
site_server = site_construct.site_server
if !site_server.nil?
@password = site_server.password
Net::SSH.start(site_server.ip , site_server.account , password: site_server.password) do |ssh|
nginx_file_content = exec_ssh_command_by_sudo(ssh,"bash -c \"cat #{site_construct.nginx_file}\"")
nginx_file_content = nginx_file_content.gsub(/^[ \t]*server_name[ \t]+.*;/," server_name #{args.server_name};").gsub('$','\$').gsub(/^\[sudo\].*\: /,'')
puts nginx_file_content
cmd = "sh -c \"echo '#{nginx_file_content}' > #{site_construct.nginx_file}\""
exec_ssh_command_by_sudo(ssh,cmd)
exec_ssh_command_by_sudo(ssh,"service nginx restart")
end
site_construct.update_attributes(domain_name: args.server_name)
end
rescue => e
puts [e,e.backtrace]
end
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

View File

@ -31,63 +31,72 @@ namespace :create_site do
next
end
Net::SSH.start(@site_server.ip , @site_server.account , password: @site_server.password) do |ssh|
nginx_include_dirs = exec_ssh_command_by_sudo(ssh,'echo `grep include /etc/nginx/nginx.conf | grep -v "\#\|include /etc/nginx/mime.types\|include /etc/nginx/conf.d/\*.conf\|/etc/nginx/sites-enabled/\*"`')
nginx_include_dirs = nginx_include_dirs.split("\n").map{|t| t.gsub("include",'').gsub(';','').strip}
nginx_include_dir = exec_ssh_command_by_sudo(ssh,'grep include /etc/nginx/nginx.conf | grep -v "\#\|include /etc/nginx/mime.types\|include /etc/nginx/conf.d/\*.conf\|/etc/nginx/sites-enabled/\*"')
nginx_include_dir = nginx_include_dir.gsub(/include|;|\n/,'').strip
domain_name = @site_server.domain_name#'serv.rulingcom.com'
nginx_include_dirs.each do |nginx_include_dir|
server_names = exec_ssh_command_by_sudo(ssh,"grep 'server_name' -r #{nginx_include_dir}")
server_names_array = server_names.split("\n")
server_names_array = server_names_array.select{|t| !t.include?('No such file or directory')}.flat_map{|t| t.strip.split('server_name').last.split(";").first.strip.split}
server_names_array.each do |server_name|
if !server_name.include?(domain_name)
next if !`nslookup "#{server_name}"`.include?(@site_server.ip)
server_names = exec_ssh_command_by_sudo(ssh,"grep 'server_name' -r #{nginx_include_dir}")
server_names_array = server_names.scan(/(.*):[ \t]*server_name[ \t]+(.*);/)
server_names_array = server_names_array.group_by{|v| v[0]}
server_names_array.each do |nginx_file, server_name_with_file|
server_names_for_site = server_name_with_file.map{|v| v[1].split(/[ |\t]+/)}.flatten.uniq - ["localhost","127.0.0.1"]
server_name_list = []
server_names_for_site.each do |server_name_for_site|
if !server_name_for_site.include?(domain_name)
next if !`nslookup "#{server_name_for_site}"`.include?(@site_server.ip)
end
nginx_file = exec_ssh_command_by_sudo(ssh,"grep '#{server_name}' -r #{nginx_include_dir}").split("\n").select{|s| !s.include?("No such file or directory")}.first.split('server_name').first.strip.split(":").first
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
next
end
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"
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")
if Pathname.new(path).basename.to_s == "orbit_sites" || Pathname.new(path).basename.to_s == "housing_sites" || Pathname.new(path).basename.to_s == "dev_sites" || Pathname.new(path).dirname.to_s == "/home"
school_name = nil
site_type = "Gravity"
server_name_list << server_name_for_site
end
server_name = server_name_list.join(' ')
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
next
end
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"
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")
if Pathname.new(path).basename.to_s == "orbit_sites" || Pathname.new(path).basename.to_s == "housing_sites" || Pathname.new(path).basename.to_s == "dev_sites" || Pathname.new(path).dirname.to_s == "/home"
school_name = nil
site_type = "Gravity"
else
school_name = Pathname.new(path).basename.to_s
site_type = "School"
end
pid_infos = exec_ssh_command_by_sudo(ssh,"fuser #{unicorn_sock_path}").to_s.strip.gsub("\n","")
if pid_infos.length != 0 && !pid_infos.include?("not exist") && !pid_infos.include?("No such file or directory")
status = "finish"
else
bundle_show_info = exec_ssh_command_by_sudo(ssh,"bash -l -c 'cd #{site_path};bundle show'")
if bundle_show_info.include?("is not yet checked out") || bundle_show_info.include?("No such file or directory")
status = ""
else
school_name = Pathname.new(path).basename.to_s
site_type = "School"
end
pid_infos = exec_ssh_command_by_sudo(ssh,"fuser #{unicorn_sock_path}").to_s.strip.gsub("\n","")
if pid_infos.length != 0 && !pid_infos.include?("not exist") && !pid_infos.include?("No such file or directory")
status = "finish"
else
bundle_show_info = exec_ssh_command_by_sudo(ssh,"bash -l -c 'cd #{site_path};bundle show'")
if bundle_show_info.include?("is not yet checked out") || bundle_show_info.include?("No such file or directory")
status = ""
else
status = "closed"
end
end
site_construct = SiteConstruct.where(:server_type => server_type , :domain_name=>server_name).first
update_thread_infos("Detect <a href='#{((port == "443") ? "https" : "http")}://#{server_name}#{((port=="80" || port=="443") ? "" : (':'+port))}'>#{server_name}</a>".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)
else
site_construct.update(: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)
status = "closed"
end
end
site_constructs = SiteConstruct.where(:server_type => server_type , :domain_name.in => [server_name,*server_name_list]).all
site_construct = site_constructs[0]
Array(site_constructs[1..-1]).each do |s|
s.destroy
end
update_thread_infos("Detect <a href='#{((port == "443") ? "https" : "http")}://#{server_name}#{((port=="80" || port=="443") ? "" : (':'+port))}'>#{server_name}</a>".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)
else
site_construct.update(: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)
end
end
end
end
end
SiteConstruct.where(:domain_name.in => ['','localhost','127.0.0.1']).destroy
@thread.update(:status=>@thread.status.merge({"status"=>"finish"}))
rescue => e
@thread.update(:status=>{"infos"=>@thread.status["infos"].push(e.to_s),"status"=>"error"})
puts [e,e.backtrace]
@thread.update(:status=>{"infos"=>@thread.status["infos"].push(e.to_s),"status"=>"error"})
end
end
end