2
0
mirror of https://github.com/frappe/bench.git synced 2024-09-23 12:39:01 +00:00

[refactor] nginx config now supports wildcard ssl and custom domains

This commit is contained in:
Anand Doshi 2016-06-26 22:40:32 +05:30
parent cc2f948a68
commit 003f3cda20
3 changed files with 123 additions and 17 deletions

View File

@ -2,7 +2,7 @@ from jinja2 import Environment, PackageLoader
__version__ = "4.0.0-beta"
env = Environment(loader=PackageLoader('bench.config'), trim_blocks=True)
env = Environment(loader=PackageLoader('bench.config'))
FRAPPE_VERSION = None

View File

@ -1,4 +1,4 @@
import os, json, click
import os, json, click, random, string
from bench.utils import get_sites, get_bench_name
def make_nginx_conf(bench_path, force=False):
@ -18,7 +18,10 @@ def make_nginx_conf(bench_path, force=False):
"sites": sites,
"webserver_port": config.get('webserver_port'),
"socketio_port": config.get('socketio_port'),
"bench_name": get_bench_name(bench_path)
"bench_name": get_bench_name(bench_path),
# for nginx map variable
"random_string": "".join(random.choice(string.ascii_lowercase) for i in xrange(7))
})
conf_path = os.path.join(bench_path, "config", "nginx.conf")
@ -31,22 +34,39 @@ def make_nginx_conf(bench_path, force=False):
def prepare_sites(config, bench_path):
sites = {
"that_use_port": [],
"that_use_dns": [],
"that_use_ssl": [],
"that_use_port": []
"that_use_wildcard_ssl": []
}
domain_map = {}
ports_in_use = {}
dns_multitenant = config.get('dns_multitenant')
for site in get_sites_with_config(bench_path=bench_path):
if dns_multitenant:
# assumes site's folder name is same as the domain name
domain = site.get('domain')
if site.get("ssl_certificate") and site.get("ssl_certificate_key"):
if domain:
# when site's folder name is different than domain name
domain_map[domain] = site['name']
site_name = domain or site['name']
if site.get('wildcard'):
sites["that_use_wildcard_ssl"].append(site_name)
if not sites.get('wildcard_ssl_certificate'):
sites["wildcard_ssl_certificate"] = site['ssl_certificate']
sites["wildcard_ssl_certificate_key"] = site['ssl_certificate_key']
elif site.get("ssl_certificate") and site.get("ssl_certificate_key"):
sites["that_use_ssl"].append(site)
else:
sites["that_use_dns"].append(site["name"])
sites["that_use_dns"].append(site_name)
else:
if not site.get("port"):
@ -58,10 +78,16 @@ def prepare_sites(config, bench_path):
ports_in_use[site["port"]] = site["name"]
sites["that_use_port"].append(site)
sites['domain_map'] = domain_map
return sites
def get_sites_with_config(bench_path):
from bench.config.common_site_config import get_config
sites = get_sites(bench_path=bench_path)
dns_multitenant = get_config(bench_path).get('dns_multitenant')
ret = []
for site in sites:
site_config = get_site_config(site, bench_path=bench_path)
@ -71,8 +97,55 @@ def get_sites_with_config(bench_path):
"ssl_certificate": site_config.get('ssl_certificate'),
"ssl_certificate_key": site_config.get('ssl_certificate_key')
})
if dns_multitenant and site_config.get('domains'):
for domain in site_config.get('domains'):
# domain can be a string or a dict with 'domain', 'ssl_certificate', 'ssl_certificate_key'
if isinstance(domain, basestring):
domain = { 'domain': domain }
domain['name'] = site
ret.append(domain)
use_wildcard_certificate(bench_path, ret)
return ret
def use_wildcard_certificate(bench_path, ret):
'''
stored in common_site_config.json as:
"wildcard": {
"domain": "*.erpnext.com",
"ssl_certificate": "/path/to/erpnext.com.cert",
"ssl_certificate_key": "/path/to/erpnext.com.key"
}
'''
from bench.config.common_site_config import get_config
config = get_config(bench_path=bench_path)
wildcard = config.get('wildcard')
if not wildcard:
return
domain = wildcard['domain']
ssl_certificate = wildcard['ssl_certificate']
ssl_certificate_key = wildcard['ssl_certificate_key']
if domain.startswith('*.'):
domain = domain[1:]
else:
domain = '.' + domain
for site in ret:
if site.get('ssl_certificate'):
continue
if (site.get('domain') or site['name']).endswith(domain):
# example: ends with .erpnext.com
site['ssl_certificate'] = ssl_certificate
site['ssl_certificate_key'] = ssl_certificate_key
site['wildcard'] = 1
def get_site_config(site, bench_path='.'):
with open(os.path.join(bench_path, 'sites', site, 'site_config.json')) as f:
return json.load(f)

View File

@ -1,7 +1,16 @@
{% macro server_block(bench_name, port, server_names, sites_path, ssl_certificate, ssl_certificate_key) %}
{%- macro nginx_map(from_variable, to_variable, values, default) %}
map {{ from_variable }} {{ to_variable }} {
{% for (from, to) in values.items() -%}
{{ from }} {{ to }};
{% endfor %}
{%- set site_name = server_names[0] if (server_names|length)==1 else "$host" -%}
{%- if default -%}
default {{ default }};
{% endif %}
}
{%- endmacro %}
{%- macro server_block(bench_name, port, server_names, site_name, sites_path, ssl_certificate, ssl_certificate_key) %}
server {
listen {{ port }};
server_name
@ -94,18 +103,22 @@ server {
# text/html is always compressed by HttpGzipModule
}
{% if ssl_certificate and ssl_certificate_key %}
# http to https redirect for {{ server_names[0] }}
{% if ssl_certificate and ssl_certificate_key -%}
# http to https redirect
server {
listen 80;
server_name {{ server_names[0] }};
server_name
{% for name in server_names -%}
{{ name }}
{% endfor -%}
;
return 301 https://$host$request_uri?$query_string;
}
{% endif %}
{# keep the empty line above for a pleasant rendering #}
{% endmacro %}
{%- endmacro -%}
upstream {{ bench_name }}-frappe {
server 127.0.0.1:{{ webserver_port or 8000 }} fail_timeout=0;
@ -115,16 +128,36 @@ upstream {{ bench_name}}-socketio-server {
server 127.0.0.1:{{ socketio_port or 3000 }} fail_timeout=0;
}
# setup maps
{%- set site_name_variable="$host" %}
{% if sites.domain_map -%}
{# we append these variables with a random string as there could be multiple benches #}
{%- set site_name_variable="$site_name_{0}".format(random_string) -%}
{{ nginx_map(from_variable="$host", to_variable=site_name_variable, values=sites.domain_map, default="$host") }}
{%- endif %}
# server blocks
{% if sites.that_use_dns -%}
{{ server_block(bench_name, 80, sites.that_use_dns, sites_path) }}
{{ server_block(bench_name, port=80, server_names=sites.that_use_dns, site_name=site_name_variable, sites_path=sites_path) }}
{%- endif %}
{% if sites.that_use_wildcard_ssl -%}
{{ server_block(bench_name, port=443, server_names=sites.that_use_wildcard_ssl,
site_name=site_name_variable, sites_path=sites_path,
ssl_certificate=sites.wildcard_ssl_certificate,
ssl_certificate_key=sites.wildcard_ssl_certificate_key) }}
{%- endif %}
{%- if sites.that_use_ssl -%}
{% for site in sites.that_use_ssl -%}
{{ server_block(bench_name, 443, [site.name], sites_path, site.ssl_certificate, site.ssl_certificate_key) }}
{{ server_block(bench_name, port=443, server_names=[site.domain or site.name],
site_name=site_name_variable, sites_path=sites_path,
ssl_certificate=site.ssl_certificate, ssl_certificate_key=site.ssl_certificate_key) }}
{% endfor %}
{%- endif %}
@ -132,7 +165,7 @@ upstream {{ bench_name}}-socketio-server {
{% if sites.that_use_port -%}
{%- for site in sites.that_use_port -%}
{{ server_block(bench_name, site.port, [site.name], sites_path) }}
{{ server_block(bench_name, port=site.port, server_names=[site.name], site_name=site.name, sites_path=sites_path) }}
{%- endfor %}
{% endif %}