Apache recipe now works with the myinstance.myhostname schema

example : https://softinst118.host.vifib.net can redirect to any url specified in slave.
parent b3f9e84d
...@@ -69,8 +69,8 @@ class Recipe(BaseSlapRecipe): ...@@ -69,8 +69,8 @@ class Recipe(BaseSlapRecipe):
if url is None: if url is None:
continue continue
reference = slave_instance.get("slave_reference") reference = slave_instance.get("slave_reference")
slave_dict[reference] = "https://%s.%s" % (reference.replace("-", ""), subdomain = reference.replace("-", "").lower()
base_url) slave_dict[reference] = "https://%s.%s" % (subdomain, base_url)
enable_cache = slave_instance.get("enable_cache", "") enable_cache = slave_instance.get("enable_cache", "")
if enable_cache.upper() in ('1', 'TRUE'): if enable_cache.upper() in ('1', 'TRUE'):
...@@ -103,11 +103,13 @@ class Recipe(BaseSlapRecipe): ...@@ -103,11 +103,13 @@ class Recipe(BaseSlapRecipe):
public_port=stunnel_port, public_port=stunnel_port,
private_ip=slave_host.replace("[", "").replace("]", ""), private_ip=slave_host.replace("[", "").replace("]", ""),
private_port=slave_port) private_port=slave_port)
rewrite_rule_list.append("%s http://%s:%s" % \ rewrite_rule_list.append("%s.%s http://%s:%s" % \
(reference.replace("-", ""), varnish_ip, base_varnish_port)) (reference.replace("-", ""), frontend_domain_name,
varnish_ip, base_varnish_port))
base_varnish_port += 2 base_varnish_port += 2
else: else:
rewrite_rule_list.append("%s %s" % (reference.replace("-", ""), url)) rewrite_rule_list.append("%s.%s %s" % (subdomain, frontend_domain_name,
url))
valid_certificate_str = self.parameter_dict.get("domain_ssl_ca_cert") valid_certificate_str = self.parameter_dict.get("domain_ssl_ca_cert")
valid_key_str = self.parameter_dict.get("domain_ssl_ca_key") valid_key_str = self.parameter_dict.get("domain_ssl_ca_key")
...@@ -197,7 +199,6 @@ class Recipe(BaseSlapRecipe): ...@@ -197,7 +199,6 @@ class Recipe(BaseSlapRecipe):
crontabs = os.path.join(self.etc_directory, 'crontabs') crontabs = os.path.join(self.etc_directory, 'crontabs')
self._createDirectory(cron_d) self._createDirectory(cron_d)
self._createDirectory(crontabs) self._createDirectory(crontabs)
# Use execute from erp5.
wrapper = zc.buildout.easy_install.scripts([('crond', wrapper = zc.buildout.easy_install.scripts([('crond',
'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable, 'slapos.recipe.librecipe.execute', 'execute')], self.ws, sys.executable,
self.wrapper_directory, arguments=[ self.wrapper_directory, arguments=[
...@@ -258,7 +259,7 @@ class Recipe(BaseSlapRecipe): ...@@ -258,7 +259,7 @@ class Recipe(BaseSlapRecipe):
self._writeFile(openssl_configuration, pkg_resources.resource_string( self._writeFile(openssl_configuration, pkg_resources.resource_string(
__name__, 'template/openssl.cnf.ca.in') % config) __name__, 'template/openssl.cnf.ca.in') % config)
self.path_list.extend(zc.buildout.easy_install.scripts([ self.path_list.extend(zc.buildout.easy_install.scripts([
('certificate_authority', 'slapos.recipe.erp5.certificate_authority', ('certificate_authority', 'slapos.recipe.apache.certificate_authority',
'runCertificateAuthority')], 'runCertificateAuthority')],
self.ws, sys.executable, self.wrapper_directory, arguments=[dict( self.ws, sys.executable, self.wrapper_directory, arguments=[dict(
openssl_configuration=openssl_configuration, openssl_configuration=openssl_configuration,
...@@ -291,6 +292,8 @@ class Recipe(BaseSlapRecipe): ...@@ -291,6 +292,8 @@ class Recipe(BaseSlapRecipe):
name + '.pid') name + '.pid')
apache_conf['lock_file'] = os.path.join(self.run_directory, apache_conf['lock_file'] = os.path.join(self.run_directory,
name + '.lock') name + '.lock')
apache_conf['document_root'] = os.path.join(self.data_root_directory,
'htdocs')
apache_conf['ip_list'] = ip_list apache_conf['ip_list'] = ip_list
apache_conf['port'] = port apache_conf['port'] = port
apache_conf['server_admin'] = 'admin@' apache_conf['server_admin'] = 'admin@'
...@@ -377,15 +380,26 @@ class Recipe(BaseSlapRecipe): ...@@ -377,15 +380,26 @@ class Recipe(BaseSlapRecipe):
self.path_list.append(wrapper) self.path_list.append(wrapper)
return stunnel_conf return stunnel_conf
def installFrontendApache(self, ip_list, port, key, certificate, def installFrontendApache(self, ip_list, port, key, certificate, name,
name, rewrite_rule_list, rewrite_rule_zope_list, rewrite_rule_list=[], rewrite_rule_zope_list=[],
access_control_string=None): access_control_string=None):
# Create htdocs, populate it with default 404 document
htdocs_location = os.path.join(self.data_root_directory, 'htdocs')
self._createDirectory(htdocs_location)
notfound_file_location = os.path.join(htdocs_location, 'notfound.html')
notfound_template_file_location = self.getTemplateFilename(
'notfound.html')
notfound_file_content = open(notfound_template_file_location, 'r').read()
self._writeFile(notfound_file_location, notfound_file_content)
# Create configuration file and rewritemaps
apachemap_name = "apachemap.txt" apachemap_name = "apachemap.txt"
# XXX-Cedric : implement zope specific rewrites list. Current apachemap is # XXX-Cedric : implement zope specific rewrites list. Current apachemap is
# generic and does not use VirtualHost Monster. # generic and does not use VirtualHost Monster.
apachemapzope_name = "apachemapzope.txt" apachemapzope_name = "apachemapzope.txt"
self.createConfigurationFile(apachemap_name, "\n".join(rewrite_rule_list)) self.createConfigurationFile(apachemap_name, "\n".join(rewrite_rule_list))
self.createConfigurationFile(apachemapzope_name,
"\n".join(rewrite_rule_zope_list))
apache_conf = self._getApacheConfigurationDict(name, ip_list, port) apache_conf = self._getApacheConfigurationDict(name, ip_list, port)
apache_conf['ssl_snippet'] = self.substituteTemplate( apache_conf['ssl_snippet'] = self.substituteTemplate(
self.getTemplateFilename('apache.ssl-snippet.conf.in'), self.getTemplateFilename('apache.ssl-snippet.conf.in'),
...@@ -400,6 +414,7 @@ class Recipe(BaseSlapRecipe): ...@@ -400,6 +414,7 @@ class Recipe(BaseSlapRecipe):
apache_conf.update(**dict( apache_conf.update(**dict(
path_enable=path, path_enable=path,
apachemap_path=os.path.join(self.etc_directory, apachemap_name), apachemap_path=os.path.join(self.etc_directory, apachemap_name),
apachemapzope_path=os.path.join(self.etc_directory, apachemapzope_name),
apache_domain=name, apache_domain=name,
port=port, port=port,
)) ))
...@@ -410,6 +425,7 @@ class Recipe(BaseSlapRecipe): ...@@ -410,6 +425,7 @@ class Recipe(BaseSlapRecipe):
apache_config_file = self.createConfigurationFile(name + '.conf', apache_config_file = self.createConfigurationFile(name + '.conf',
apache_conf_string) apache_conf_string)
self.path_list.append(apache_config_file) self.path_list.append(apache_config_file)
self.path_list.extend(zc.buildout.easy_install.scripts([( self.path_list.extend(zc.buildout.easy_install.scripts([(
name, 'slapos.recipe.erp5.apache', 'runApache')], self.ws, name, 'slapos.recipe.erp5.apache', 'runApache')], self.ws,
......
import os
import subprocess
import time
import ConfigParser
import uuid
def popenCommunicate(command_list, input=None):
subprocess_kw = dict(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if input is not None:
subprocess_kw.update(stdin=subprocess.PIPE)
popen = subprocess.Popen(command_list, **subprocess_kw)
result = popen.communicate(input)[0]
if popen.returncode is None:
popen.kill()
if popen.returncode != 0:
raise ValueError('Issue during calling %r, result was:\n%s' % (
command_list, result))
return result
class CertificateAuthority:
def __init__(self, key, certificate, openssl_binary,
openssl_configuration, request_dir):
self.key = key
self.certificate = certificate
self.openssl_binary = openssl_binary
self.openssl_configuration = openssl_configuration
self.request_dir = request_dir
def checkAuthority(self):
file_list = [ self.key, self.certificate ]
ca_ready = True
for f in file_list:
if not os.path.exists(f):
ca_ready = False
break
if ca_ready:
return
for f in file_list:
if os.path.exists(f):
os.unlink(f)
try:
# no CA, let us create new one
popenCommunicate([self.openssl_binary, 'req', '-nodes', '-config',
self.openssl_configuration, '-new', '-x509', '-extensions', 'v3_ca',
'-keyout', self.key, '-out', self.certificate, '-days', '10950'],
# Authority name will be random, so no instance has the same issuer
'Certificate Authority %s\n' % uuid.uuid1())
except:
try:
for f in file_list:
if os.path.exists(f):
os.unlink(f)
except:
# do not raise during cleanup
pass
raise
def _checkCertificate(self, common_name, key, certificate):
file_list = [key, certificate]
ready = True
for f in file_list:
if not os.path.exists(f):
ready = False
break
if ready:
return False
for f in file_list:
if os.path.exists(f):
os.unlink(f)
csr = certificate + '.csr'
try:
popenCommunicate([self.openssl_binary, 'req', '-config',
self.openssl_configuration, '-nodes', '-new', '-keyout',
key, '-out', csr, '-days', '3650'],
common_name + '\n')
try:
popenCommunicate([self.openssl_binary, 'ca', '-batch', '-config',
self.openssl_configuration, '-out', certificate,
'-infiles', csr])
finally:
if os.path.exists(csr):
os.unlink(csr)
except:
try:
for f in file_list:
if os.path.exists(f):
os.unlink(f)
except:
# do not raise during cleanup
pass
raise
else:
return True
def checkRequestDir(self):
for request_file in os.listdir(self.request_dir):
parser = ConfigParser.RawConfigParser()
parser.readfp(open(os.path.join(self.request_dir, request_file), 'r'))
if self._checkCertificate(parser.get('certificate', 'name'),
parser.get('certificate', 'key_file'), parser.get('certificate',
'certificate_file')):
print 'Created certificate %r' % parser.get('certificate', 'name')
def runCertificateAuthority(args):
ca_conf = args[0]
ca = CertificateAuthority(ca_conf['key'], ca_conf['certificate'],
ca_conf['openssl_binary'], ca_conf['openssl_configuration'],
ca_conf['request_dir'])
while True:
ca.checkAuthority()
ca.checkRequestDir()
time.sleep(60)
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
PidFile "%(pid_file)s" PidFile "%(pid_file)s"
LockFile "%(lock_file)s" LockFile "%(lock_file)s"
ServerName %(server_name)s ServerName %(server_name)s
DocumentRoot %(document_root)s
%(listen)s %(listen)s
...@@ -37,15 +38,24 @@ CustomLog "%(access_log)s" common ...@@ -37,15 +38,24 @@ CustomLog "%(access_log)s" common
%(path_enable)s %(path_enable)s
# Magic of Zope related rewrite # Rewrite part
RewriteMap apachemapzope txt:%(apachemapzope_path)s
RewriteEngine On RewriteEngine On
# XXX-Cedric : apply only known apachemapzope rules.
RewriteRule ^/(\w+)($|/.*) ${apachemapzope:$1}/VirtualHostBase/https/%(apache_domain)s:%(port)s/VirtualHostRoot/_vh_$1$2 [L,P]
# Sadly, Zope isn't used everywhere. So let's add a generic purpose rule # Define the two rewritemaps : one for zope, one generic
RewriteMap apachemapzope txt:%(apachemapzope_path)s
RewriteMap apachemapgeneric txt:%(apachemap_path)s RewriteMap apachemapgeneric txt:%(apachemap_path)s
RewriteRule ^/(\w+)($|/.*) ${apachemapgeneric:$1}/$2 [L,P]
# First, we check if we have a zope backend server
# If so, let's use Virtual Host Daemon rewrite
#RewriteCond ${apachemapzope:%%{SERVER_NAME}} >""
#RewriteRule ^/(\w+)($|/.*) ${apachemapzope:$1}/VirtualHostBase/https/%(apache_domain)s:%(port)s/VirtualHostRoot/_vh_$1$2 [L,P]
# If we have generic backend server, let's rewrite without virtual host daemon
RewriteCond ${apachemapgeneric:%%{SERVER_NAME}} >""
RewriteRule ^/(.*)$ ${apachemapgeneric:%%{SERVER_NAME}}/$1 [L,P]
# If nothing exist : put a nice error
ErrorDocument 404 /notfound.html
# List of modules # List of modules
LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_host_module modules/mod_authz_host.so
......
<html>
<head>
<title>Instance not found</title>
</head>
<body>
<h1>This instance has not been found.</h1>
<p>If this error persists, please check your instance URL and status on SlapOS Master.</p>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment