client_management/app/models/site_construct.rb

202 lines
7.9 KiB
Ruby

class SiteConstruct
include Mongoid::Document
include Mongoid::Timestamps
def self.server_types
SiteServer.all.map{|s| s.server_name}
end
SITE_TYPES = ["School","Gravity"]
field :rails_env, type: String, :default => "development"
field :server_type
field :site_name
field :domain_name
field :nginx_file
field :db_name
field :port, type: Array, :default => ["80"]
field :path
field :site_type
field :school_name
field :user_id
field :constructed, type: Boolean, :default => false
field :status, type: String, :default => ""
field :infos, type: Array, :default => []
field :hidden, type: Boolean, :default => false
field :copy_id
field :only_copy_installed_module, type: Boolean, :default => false
field :redirect_to_https, type: Boolean, :default => false
field :cert_ver_added_text
field :cert_ver_file_content
field :cert_ver_location_path
belongs_to :site_cert
after_initialize do |record|
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
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
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 match_exact_index(text,match_character,level=1)
text.enum_for(:scan,/(?:[^#{match_character}])#{match_character}{#{level}}(?!#{match_character})/m).map { offset_index=Regexp.last_match.to_s.index(match_character);Regexp.last_match.offset(0).first + offset_index}
end
def parse_nginx_text_to_server_blocks(nginx_text,get_all_blocks=false,level=1)
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 = match_exact_index(nginx_text_tmp,'}',level)
start_indices = match_exact_index(nginx_text_tmp,'{',level)
start_indices = start_indices.map{|i| (i - nginx_text_tmp[0...i].reverse.index(/(}|;)/m)) rescue 0}
all_blocks = (0...end_indices.count).map{|i| nginx_text_tmp[start_indices[i]..end_indices[i]]}
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
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[^;]+;/,'')
get_redirect_block = parse_nginx_text_to_server_blocks(old_server_block,true,2).select{|t| t.match(/\s*return\s+30[12]\s+https:\/\/\$host\$request_uri\s*;/)}
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 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"}
else
if self.redirect_to_https && !self.site_cert.nil?
new_server_block = new_server_block.sub(/(listen\s+)[^;]+;[\s\r\n]*/){|ff| ff + " if ($host ~ (#{self.site_cert.domain_names.map{|s| '^'+s.gsub('.','\.').gsub('*','[^.]*').gsub(',','')}.join('|')}) ) {\n"+
" return 301 https://$host$request_uri;\n"+
" }\n"}
end
end
new_server_block = new_server_block.gsub(/[ \t\s]+\n/,"\n\n").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"+
((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" : '') : '')+
' 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| "<a href=\"#{get_domain_name(port)}\" title=\"#{port}\" target=\"_blank\">#{port}</a>"}.join("<br>").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.to_s.gsub(" ","\\ ")
end
def get_domain_name(port=nil)
scheme = ""
extra_port = ""
port = self.get_port if port.nil?
if port == "443"
scheme = "https://"
else
scheme = "http://"
if port != "80"
extra_port = ":#{port}"
end
end
return (scheme + self.domain_name.split(" ").first + extra_port)
end
def site_server
SiteServer.where(server_name: self.server_type).first
end
end