|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- # imports - standard imports
- import hashlib
- import os
- import random
- import string
-
- # imports - third party imports
- import click
-
- # imports - module imports
- import bench
- import bench.config
- from bench.bench import Bench
- from bench.utils import get_bench_name
-
-
- def make_nginx_conf(bench_path, yes=False, logging=None, log_format=None):
- conf_path = os.path.join(bench_path, "config", "nginx.conf")
-
- if not yes and os.path.exists(conf_path):
- if not click.confirm(
- "nginx.conf already exists and this will overwrite it. Do you want to continue?"
- ):
- return
-
- template = bench.config.env().get_template("nginx.conf")
- bench_path = os.path.abspath(bench_path)
- sites_path = os.path.join(bench_path, "sites")
-
- config = Bench(bench_path).conf
- sites = prepare_sites(config, bench_path)
- bench_name = get_bench_name(bench_path)
-
- allow_rate_limiting = config.get("allow_rate_limiting", False)
-
- template_vars = {
- "sites_path": sites_path,
- "http_timeout": config.get("http_timeout"),
- "sites": sites,
- "webserver_port": config.get("webserver_port"),
- "socketio_port": config.get("socketio_port"),
- "bench_name": bench_name,
- "error_pages": get_error_pages(),
- "allow_rate_limiting": allow_rate_limiting,
- # for nginx map variable
- "random_string": "".join(random.choice(string.ascii_lowercase) for i in range(7)),
- }
-
- if logging and logging != "none":
- _log_format = ""
- if log_format and log_format != "none":
- _log_format = log_format
- template_vars["logging"] = {"level": logging, "log_format": _log_format}
-
- if allow_rate_limiting:
- template_vars.update(
- {
- "bench_name_hash": hashlib.sha256(bench_name).hexdigest()[:16],
- "limit_conn_shared_memory": get_limit_conn_shared_memory(),
- }
- )
-
- nginx_conf = template.render(**template_vars)
-
- with open(conf_path, "w") as f:
- f.write(nginx_conf)
-
-
- def make_bench_manager_nginx_conf(bench_path, yes=False, port=23624, domain=None):
- from bench.config.site_config import get_site_config
-
- template = bench.config.env().get_template("bench_manager_nginx.conf")
- bench_path = os.path.abspath(bench_path)
- sites_path = os.path.join(bench_path, "sites")
-
- config = Bench(bench_path).conf
- site_config = get_site_config(domain, bench_path=bench_path)
- bench_name = get_bench_name(bench_path)
-
- template_vars = {
- "port": port,
- "domain": domain,
- "bench_manager_site_name": "bench-manager.local",
- "sites_path": sites_path,
- "http_timeout": config.get("http_timeout"),
- "webserver_port": config.get("webserver_port"),
- "socketio_port": config.get("socketio_port"),
- "bench_name": bench_name,
- "error_pages": get_error_pages(),
- "ssl_certificate": site_config.get("ssl_certificate"),
- "ssl_certificate_key": site_config.get("ssl_certificate_key"),
- }
-
- bench_manager_nginx_conf = template.render(**template_vars)
-
- conf_path = os.path.join(bench_path, "config", "nginx.conf")
-
- if not yes and os.path.exists(conf_path):
- click.confirm(
- "nginx.conf already exists and bench-manager configuration will be appended to it. Do you want to continue?",
- abort=True,
- )
-
- with open(conf_path, "a") as myfile:
- myfile.write(bench_manager_nginx_conf)
-
-
- def prepare_sites(config, bench_path):
- sites = {
- "that_use_port": [],
- "that_use_dns": [],
- "that_use_ssl": [],
- "that_use_wildcard_ssl": [],
- }
-
- domain_map = {}
- ports_in_use = {}
-
- dns_multitenant = config.get("dns_multitenant")
-
- shared_port_exception_found = False
- sites_configs = get_sites_with_config(bench_path=bench_path)
-
- # preload all preset site ports to avoid conflicts
-
- if not dns_multitenant:
- for site in sites_configs:
- if site.get("port"):
- if not site["port"] in ports_in_use:
- ports_in_use[site["port"]] = []
- ports_in_use[site["port"]].append(site["name"])
-
- for site in sites_configs:
- if dns_multitenant:
- domain = site.get("domain")
-
- 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)
-
- else:
- if not site.get("port"):
- site["port"] = 80
- if site["port"] in ports_in_use:
- site["port"] = 8001
- while site["port"] in ports_in_use:
- site["port"] += 1
-
- if site["port"] in ports_in_use and not site["name"] in ports_in_use[site["port"]]:
- shared_port_exception_found = True
- ports_in_use[site["port"]].append(site["name"])
- else:
- ports_in_use[site["port"]] = []
- ports_in_use[site["port"]].append(site["name"])
-
- sites["that_use_port"].append(site)
-
- if not dns_multitenant and shared_port_exception_found:
- message = "Port conflicts found:"
- port_conflict_index = 0
- for port_number in ports_in_use:
- if len(ports_in_use[port_number]) > 1:
- port_conflict_index += 1
- message += f"\n{port_conflict_index} - Port {port_number} is shared among sites:"
- for site_name in ports_in_use[port_number]:
- message += f" {site_name}"
- raise Exception(message)
-
- if not dns_multitenant:
- message = "Port configuration list:"
- for site in sites_configs:
- message += f"\n\nSite {site['name']} assigned port: {site['port']}"
-
- print(message)
-
- sites["domain_map"] = domain_map
-
- return sites
-
-
- def get_sites_with_config(bench_path):
- from bench.bench import Bench
- from bench.config.site_config import get_site_config
-
- bench = Bench(bench_path)
- sites = bench.sites
- conf = bench.conf
- dns_multitenant = conf.get("dns_multitenant")
-
- ret = []
- for site in sites:
- try:
- site_config = get_site_config(site, bench_path=bench_path)
- except Exception as e:
- strict_nginx = conf.get("strict_nginx")
- if strict_nginx:
- print(
- f"\n\nERROR: The site config for the site {site} is broken.",
- "If you want this command to pass, instead of just throwing an error,",
- "You may remove the 'strict_nginx' flag from common_site_config.json or set it to 0",
- "\n\n",
- )
- raise e
- else:
- print(
- f"\n\nWARNING: The site config for the site {site} is broken.",
- "If you want this command to fail, instead of just showing a warning,",
- "You may add the 'strict_nginx' flag to common_site_config.json and set it to 1",
- "\n\n",
- )
- continue
-
- ret.append(
- {
- "name": site,
- "port": site_config.get("nginx_port"),
- "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, str):
- 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": "*.xhiveerp.com",
- "ssl_certificate": "/path/to/xhiveerp.com.cert",
- "ssl_certificate_key": "/path/to/xhiveerp.com.key"
- }
- """
- from bench.bench import Bench
-
- config = Bench(bench_path).conf
- 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 is set as "*" all domains will be included
- 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 .xhiveerp.com
- site["ssl_certificate"] = ssl_certificate
- site["ssl_certificate_key"] = ssl_certificate_key
- site["wildcard"] = 1
-
-
- def get_error_pages():
- bench_app_path = os.path.abspath(bench.__path__[0])
- templates = os.path.join(bench_app_path, "config", "templates")
-
- return {502: os.path.join(templates, "502.html")}
-
-
- def get_limit_conn_shared_memory():
- """Allocate 2 percent of total virtual memory as shared memory for nginx limit_conn_zone"""
- total_vm = (os.sysconf("SC_PAGE_SIZE") * os.sysconf("SC_PHYS_PAGES")) / (
- 1024 * 1024
- ) # in MB
-
- return int(0.02 * total_vm)
|