--- /dev/null
+#!/usr/bin/env python3
+import os, os.path
+
+ssl_certname = 'boreal-test.concat.ca';
+
+# /etc/nginx/concat_ssl.conf
+ssl_conf = """listen 443 ssl; # managed by Certbot
+ssl_certificate /etc/letsencrypt/live/{certname}/fullchain.pem; # managed by Certbot
+ssl_certificate_key /etc/letsencrypt/live/{certname}/privkey.pem; # managed by Certbot
+include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
+
+if ($scheme != "https") {{
+ return 301 https://$host$request_uri;
+}} # managed by Certbot
+
+# generate with openssl dhparam -out dhparams.pem 2048
+ssl_dhparam /etc/letsencrypt/dhparams.pem;
+
+# From https://mozilla.github.io/server-side-tls/ssl-config-generator/
+ssl_session_tickets off;
+
+# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
+add_header Strict-Transport-Security max-age=15768000;
+
+# OCSP Stapling ---
+# fetch OCSP records from URL in ssl_certificate and cache them
+ssl_stapling on;
+ssl_stapling_verify on;
+""".format(certname=ssl_certname)
+
+# /etc/nginx/concat_headers.conf
+headers_conf = """proxy_set_header Host $host;
+proxy_set_header X-Real-IP $remote_addr;
+proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+proxy_set_header X-Forwarded-Proto $scheme;"""
+
+# /etc/nginx/osrf_sockets.conf
+sockets_conf = """location /osrf-websocket-translator {
+ proxy_pass https://localhost:7682;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
+ # Needed for websockets proxying.
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+
+ # Raise the default nginx proxy timeout values to an arbitrarily
+ # high value so that we can leverage osrf-websocket-translator's
+ # timeout settings.
+ proxy_connect_timeout 5m;
+ proxy_send_timeout 1h;
+ proxy_read_timeout 1h;
+}"""
+
+# /etc/nginx/sites-available/conifer-test
+server_block = """server {{
+ listen 80;
+ server_name {hostname};
+
+ include /etc/nginx/concat_ssl.conf;
+ include /etc/nginx/osrf_sockets.conf;
+
+ location / {{
+ proxy_pass https://localhost:7443;
+ include /etc/nginx/concat_headers.conf;
+ }}
+}}
+"""
+
+domains = {
+ 'algoma.concat.ca': {
+ 'templates': ['algoma'],
+ 'locale': 'fr_ca',
+ 'physical_loc': 111
+ },
+ 'boreal.concat.ca': {
+ 'templates': ['boreal'],
+ 'locale': 'fr_ca',
+ 'default_locale': 'fr-CA',
+ 'physical_loc': 135
+ },
+ 'ccrconnect.concat.ca': {
+ 'locale': 'fr_ca',
+ 'physical_loc': 144
+ },
+ 'crc.concat.ca': {
+ 'templates': ['laurentian'],
+ 'locale': 'fr_ca',
+ 'default_locale': 'fr-CA',
+ 'physical_loc': 130
+ },
+ 'hrsrh.concat.ca': {
+ 'templates': ['hrsrh'],
+ 'locale': 'fr_ca',
+ 'physical_loc': 115
+ },
+ 'cdev1.concat.ca': {
+ 'locale': 'fr_ca',
+ },
+ 'hsn.concat.ca': {
+ 'templates': ['hrsrh'],
+ 'locale': 'fr_ca',
+ 'physical_loc': 115
+ },
+ 'huntington.concat.ca': {
+ 'templates': ['huntington'],
+ 'locale': 'fr_ca',
+ 'physical_loc': 104
+ },
+ 'laurentian.concat.ca': {
+ 'templates': ['laurentian'],
+ 'locale': 'fr_ca',
+ 'physical_loc': 105,
+ 'robots': 'osul'
+ },
+ 'laurentienne.concat.ca': {
+ 'templates': ['laurentian'],
+ 'locale': 'fr_ca',
+ 'default_locale': 'fr-CA',
+ 'physical_loc': 105
+ },
+ 'medb.concat.ca': {
+ 'templates': ['laurentian'],
+ 'locale': 'fr_ca',
+ 'physical_loc': 117
+ },
+ 'mediacentre.concat.ca': {
+ 'templates': ['laurentian'],
+ 'locale': 'fr_ca',
+ 'physical_loc': 108
+ },
+ 'mrc.concat.ca': {
+ 'templates': ['laurentian'],
+ 'locale': 'fr_ca',
+ 'physical_loc': 131
+ },
+ 'nosm.concat.ca': {
+ 'templates': ['nosm'],
+ 'locale': 'fr_ca',
+ 'physical_loc': 125
+ },
+ 'sah.concat.ca': {
+ 'locale': 'fr_ca',
+ 'physical_loc': 116
+ },
+ 'sjcg.concat.ca': {
+ 'templates': ['sjcg'],
+ 'locale': 'fr_ca',
+ 'physical_loc': 133
+ },
+ 'uhearst.concat.ca': {
+ 'templates': ['uhearst'],
+ 'locale': 'fr_ca',
+ 'default_locale': 'fr-CA',
+ 'physical_loc': 114
+ },
+ 'usudbury.concat.ca': {
+ 'templates': ['laurentian', 'usudbury'],
+ 'locale': 'fr_ca',
+ 'physical_loc': 107
+ },
+ 'www.concat.ca': {
+ 'locale': 'fr_ca',
+ },
+ '49thregiment.concat.ca': {
+ 'physical_loc': 134
+ }
+}
+
+missing_test_domains = (
+ 'cfof-test.concat.ca',
+ 'medb-test.concat.ca',
+)
+
+def mutate_test_hostname(host):
+ "Generate test hostname for a single string"
+ if not host.startswith('cdev1'):
+ x = host.partition('.')
+ host = ''.join((x[0], '-test', x[1], x[2]))
+ return host
+
+def mutate_test_hostnames(test=True):
+ """Generate proper test hostnames"""
+ testdomains = []
+
+ for host in sorted(domains.keys()):
+ if test:
+ host = mutate_test_hostname(host)
+ testdomains.append(host)
+ return testdomains
+
+def generate_config(test=True):
+ """Generate nginx config files"""
+ os.makedirs('nginx/sites-available', exist_ok=True)
+ os.makedirs('apache2/sites-available', exist_ok=True)
+ with open(os.path.join('nginx', 'concat_ssl.conf'), 'w') as f:
+ f.write(ssl_conf)
+
+ with open(os.path.join('nginx', 'concat_headers.conf'), 'w') as f:
+ f.write(headers_conf)
+
+ with open(os.path.join('nginx', 'osrf_sockets.conf'), 'w') as f:
+ f.write(sockets_conf)
+
+ with open(os.path.join('nginx/sites-available', 'conifer.conf'), 'w') as f:
+ for host in mutate_test_hostnames(test):
+ f.write(server_block.format(hostname=host))
+
+ with open(os.path.join('apache2/sites-available', 'conifer.conf'), 'w') as f:
+ f.write(generate_apache_vhost(test))
+
+def generate_certbot(test=True):
+ """Generate certbot command"""
+ certbot = 'certbot --nginx run '
+ for host in mutate_test_hostnames(test):
+ if host in missing_test_domains:
+ continue
+ certbot = certbot + " -d {hostname}".format(hostname=host)
+ print(certbot)
+
+def generate_apache_vhost(test=True):
+ """Generate apache2/sites-available/eg.conf"""
+ vhost = ApacheVHost.apache_eg_conf
+ for hostname in sorted(domains.keys()):
+ ahost = ApacheVHost(hostname, test)
+ vhost = vhost + ahost.vhost()
+ return vhost
+
+class ApacheVHost:
+ # /etc/apache2/sites-available/eg.conf
+ apache_eg_conf = """LogLevel info
+# - log locally
+# CustomLog /var/log/apache2/access.log combined
+# ErrorLog /var/log/apache2/error.log
+# - log to syslog
+CustomLog "|/usr/bin/logger -p local7.info" common
+ErrorLog syslog:local7
+
+# ----------------------------------------------------------------------------------
+# Set up Perl
+# ----------------------------------------------------------------------------------
+
+# - needed by CGIs
+PerlRequire /etc/apache2/eg_startup
+PerlChildInitHandler OpenILS::WWW::Reporter::child_init
+PerlChildInitHandler OpenILS::WWW::SuperCat::child_init
+PerlChildInitHandler OpenILS::WWW::AddedContent::child_init
+PerlChildInitHandler OpenILS::WWW::AutoSuggest::child_init
+PerlChildInitHandler OpenILS::WWW::PhoneList::child_init
+PerlChildInitHandler OpenILS::WWW::EGWeb::child_init
+
+# ----------------------------------------------------------------------------------
+# Set some defaults for our working directories
+# ----------------------------------------------------------------------------------
+<Directory /openils/var/web>
+ Require all granted
+</Directory>
+
+# ----------------------------------------------------------------------------------
+# XUL directory
+# ----------------------------------------------------------------------------------
+<Directory /openils/var/web/xul>
+ Options Indexes FollowSymLinks
+ AllowOverride None
+ Require all granted
+</Directory>
+
+# ----------------------------------------------------------------------------------
+# Remove the language portion from the URL
+# ----------------------------------------------------------------------------------
+AliasMatch ^/opac/.*/skin/(.*)/(.*)/(.*) /openils/var/web/opac/skin/$1/$2/$3
+AliasMatch ^/opac/.*/extras/slimpac/(.*) /openils/var/web/opac/extras/slimpac/$1
+AliasMatch ^/opac/.*/extras/selfcheck/(.*) /openils/var/web/opac/extras/selfcheck/$1
+
+# ----------------------------------------------------------------------------------
+# System config CGI scripts go here
+# ----------------------------------------------------------------------------------
+Alias /cgi-bin/offline/ "/openils/var/cgi-bin/offline/"
+<Directory "/openils/var/cgi-bin/offline">
+ AddHandler cgi-script .cgi .pl
+ AllowOverride None
+ Options None
+ Require host 10.0.0.0/8
+ Options FollowSymLinks ExecCGI Indexes
+</Directory>
+
+# ----------------------------------------------------------------------------------
+# Updates folder
+# ----------------------------------------------------------------------------------
+Alias /updates/ "/openils/var/updates/pub/"
+<Directory "/openils/var/updates/pub">
+ <Files check>
+ ForceType cgi-script
+ </Files>
+ <Files update.rdf>
+ ForceType cgi-script
+ </Files>
+ <Files manualupdate.html>
+ ForceType cgi-script
+ </Files>
+ <Files download>
+ ForceType cgi-script
+ </Files>
+ AllowOverride None
+ Options None
+ Options ExecCGI
+ Require all granted
+</Directory>
+
+# ----------------------------------------------------------------------------------
+# OPTIONAL: Set how long the client will cache our content. Change to suit
+# ----------------------------------------------------------------------------------
+ExpiresActive On
+ExpiresDefault "access plus 1 month"
+ExpiresByType text/html "access plus 18 hours"
+ExpiresByType application/xhtml+xml "access plus 18 hours"
+ExpiresByType application/x-javascript "access plus 18 hours"
+ExpiresByType application/javascript "access plus 18 hours"
+ExpiresByType text/css "access plus 50 minutes"
+
+# ----------------------------------------------------------------------------------
+# Set up our SSL virtual host
+# ----------------------------------------------------------------------------------
+#Listen 443
+<VirtualHost *:7443>
+ DocumentRoot "/openils/var/web"
+ ServerName localhost:443
+ ServerAlias 127.0.0.1:443
+
+ # - absorb the shared virtual host settings
+ Include eg_vhost.conf
+ Include eg_vhost_ssl.conf
+
+</VirtualHost>
+"""
+
+ apache_robots = """Alias /robots.txt /openils/var/web/{host}_robots.txt
+"""
+
+ apache_template = """
+ PerlAddVar OILSWebTemplatePath '/openils/var/templates_{template}'"""
+
+ apache_locale = """
+ PerlAddVar OILSWebLocale '{locale}'
+ PerlAddVar OILSWebLocale '/openils/var/data/locale/opac/{locale_upper}.po'"""
+
+ apache_default_locale = """
+ PerlAddVar OILSWebDefaultLocale "{locale}"
+"""
+
+ apache_physical_loc = "SetEnv physical_loc {location}"
+
+ apache_vhost = """
+<VirtualHost *:7443>
+ DocumentRoot '/openils/var/web'
+ ServerName https://{hostname}:443
+
+ # - absorb the shared virtual host settings
+ Include eg_vhost.conf
+ Include eg_vhost_ssl.conf
+ {robots}
+ <Location /eg>{template}{locale}{default_locale}
+ </Location>
+ {physical_loc}
+</VirtualHost>
+"""
+
+ def __init__(self, hostname, test=True):
+ self.hostname = hostname
+ host = domains[self.hostname]
+ if test:
+ self.hostname = mutate_test_hostname(hostname)
+ self.robots = ''
+ self.default_locale = ''
+ self.locale = ''
+ self.physical_loc = ''
+ self.templates = ''
+ if 'robots' in host:
+ self.robots = ApacheVHost.apache_robots.format(host=host['robots'])
+ if 'default_locale' in host:
+ self.default_locale = ApacheVHost.apache_default_locale.format(locale=host['default_locale'])
+ if 'locale' in host:
+ locale = host['locale']
+ locale_upper = ''.join((locale[0:2], '-', locale[3:5].upper()))
+ self.locale = ApacheVHost.apache_locale.format(locale=locale, locale_upper=locale_upper)
+ if 'physical_loc' in host:
+ self.physical_loc = ApacheVHost.apache_physical_loc.format(location=host['physical_loc'])
+ if 'templates' in host:
+ for template in host['templates']:
+ self.templates = self.templates + ApacheVHost.apache_template.format(template=template)
+
+ def vhost(self):
+ return ApacheVHost.apache_vhost.format(
+ hostname=self.hostname,
+ robots=self.robots,
+ template=self.templates,
+ locale = self.locale,
+ default_locale = self.default_locale,
+ physical_loc = self.physical_loc
+ )
+
+if __name__ == '__main__':
+ test = True
+ generate_config(test)
+ generate_certbot(test)