freelance-project-34-market.../d1/nginx_config.py
2024-11-02 12:26:03 +03:00

395 lines
9.6 KiB
Python

import json
import os
import io
import sys
def forward(
input_json,
output_conf,
):
with io.open(
input_json,
'r'
) as f:
forward_nginx = json.load(f)
with io.open(
output_conf,
'w'
) as f:
names = [o['app_name'] for o in forward_nginx]
if not '' in names:
forward_nginx.append(
dict(
app_name='',
redirect_url='https://product-development-service.blogspot.com',
)
)
sections = dict()
for entry in forward_nginx:
location_path = None
if entry['app_name'] != '':
location_path = '/%s/' % entry['app_name']
else:
location_path = '/'
if 'server_name' in entry:
server_name = entry['server_name']
else:
server_name = 'default_server'
if (
not server_name in sections
):
sections[server_name] = []
if 'client_max_body_size' in entry:
client_max_body_size = entry['client_max_body_size']
else:
client_max_body_size = '50M'
assert isinstance(client_max_body_size, str)
sections[server_name].append(
r'''
client_max_body_size %s;
''' % client_max_body_size
)
location_get = lambda location_body, location_path2, prefix=None,: (
r'''
location {location} {
{location_body}
}
'''.replace(
'{location_body}', location_body,
).replace(
'{location}', '%s %s' % (
(
'^~'
if prefix is None
else prefix
),
location_path2
),
)
)
if 'target_endpoint' in entry:
location_body_get = lambda target_endpoint: \
r'''
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $t1;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
proxy_buffering off;
proxy_pass {target_endpoint};
'''.replace(
'{target_endpoint}', target_endpoint,
)
if 'fallback_endpoint' in entry:
fallback_name = '@fallback-%s' % os.urandom(10).hex()
sections[server_name].append(
location_get(
location_body_get(entry['target_endpoint']) + r'''
proxy_intercept_errors on;
error_page 502 =200 {fallback_name};
'''.replace(
'{fallback_name}', fallback_name,
),
location_path,
)
)
sections[server_name].append(
location_get(
location_body_get(entry['fallback_endpoint']),
fallback_name,
'',
)
)
else:
sections[server_name].append(
location_get(
location_body_get(entry['target_endpoint']),
location_path,
)
)
elif 'redirect_url' in entry:
sections[server_name].append(
location_get(
r'''
return 302 {redirect_url}$request_uri;
'''.replace(
'{redirect_url}', entry['redirect_url'],
),
location_path,
)
)
else:
raise NotImplementedError
servers = []
for server_name, current_sections in sections.items():
servers.append(
r'''
server {
set $t1 $remote_addr;
if ($http_x_forwarded_for)
{
set $t1 $http_x_forwarded_for;
}
server_name {server_name};
listen 80 {default_server};
#client_max_body_size 50M;
{sections_config}
}
'''.replace(
'{sections_config}', '\n'.join(current_sections)
).replace(
'{server_name}',
(
'_'
if server_name == 'default_server'
else server_name
),
).replace(
'{default_server}',
(
''
if not server_name == 'default_server'
else server_name
)
)
)
f.write(r'''
events {
multi_accept on;
worker_connections 64;
}
http {
log_format main
'[$time_local][$remote_addr:$remote_port, $http_x_forwarded_for, $t1, $http_host]'
'[$request_length,$bytes_sent,$request_time]'
'[$status][$request]'
'[$http_user_agent][$http_referer]';
access_log /dev/null combined;
access_log /dev/stderr main;
gzip on;
server_tokens off;
{servers_config}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
}
'''.replace(
'{servers_config}', '\n'.join(servers)
))
def ssl(input_json, output_conf):
with io.open(
input_json,
'r'
) as f:
ssl_nginx = json.load(f)
servers = []
if 'stream_server' in ssl_nginx:
ssl_port = 444
stream_server = r'''
stream {
upstream web {
server 127.0.0.1:444;
}
upstream ssh {
server {ssh};
}
map $ssl_preread_protocol $upstream {
default ssh;
"TLSv1.2" web;
"TLSv1.3" web;
}
# SSH and SSL on the same port
server {
listen 443;
proxy_pass $upstream;
ssl_preread on;
}
}
'''.replace(
'{ssh}', str(ssl_nginx['stream_server'])[:256]
)
else:
stream_server = ''
ssl_port = 443
if 'default_server' in ssl_nginx:
server = ssl_nginx['default_server']
servers.append(
r'''
server {
set $t1 $remote_addr;
if ($http_x_forwarded_for)
{
set $t1 $http_x_forwarded_for;
}
listen {ssl_port} ssl default_server;
server_name _;
client_max_body_size {client_max_body_size};
ssl_certificate {signed_chain_cert};
ssl_certificate_key {domain_key};
return 444;
}
'''.replace(
'{signed_chain_cert}', server['signed_chain_cert'],
).replace(
'{client_max_body_size}', server['client_max_body_size'],
).replace(
'{domain_key}', server['domain_key'],
).replace(
'{ssl_port}', '%d' % ssl_port,
)
)
for server in ssl_nginx['servers']:
servers.append(
r'''
server {
set $t1 $remote_addr;
if ($http_x_forwarded_for)
{
set $t1 $http_x_forwarded_for;
}
listen 80;
server_name {server_names};
client_max_body_size {client_max_body_size};
location ~ ^/.well-known/acme-challenge/ {
alias /var/www/;
try_files $uri =404;
}
location ~ {
#return 444;
return 301 https://$host$request_uri;
}
}
server {
set $t1 $remote_addr;
if ($http_x_forwarded_for)
{
set $t1 $http_x_forwarded_for;
}
listen {ssl_port} ssl;
server_name {server_names};
client_max_body_size {client_max_body_size};
ssl_certificate {signed_chain_cert};
ssl_certificate_key {domain_key};
location ^~ / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://app:80;
}
}
'''.replace(
'{server_names}', ' '.join(server['server_names'])
).replace(
'{signed_chain_cert}', server['signed_chain_cert'],
).replace(
'{client_max_body_size}', server['client_max_body_size'],
).replace(
'{domain_key}', server['domain_key'],
).replace(
'{ssl_port}', '%d' % ssl_port,
)
)
with io.open(
output_conf,
'w'
) as f:
f.write(
r'''
load_module "modules/ngx_stream_module.so";
events {
multi_accept on;
worker_connections 64;
}
{stream_server}
http {
log_format main
'[$time_local][$remote_addr:$remote_port, $http_x_forwarded_for, $t1, $http_host]'
'[$request_length,$bytes_sent,$request_time]'
'[$status][$request]'
'[$http_user_agent][$http_referer]';
access_log /dev/null combined;
access_log /dev/stderr main;
gzip on;
server_tokens off;
{servers}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
}
'''\
.replace('{servers}', '\n'.join(servers)) \
.replace('{stream_server}', stream_server)
)
if __name__ == '__main__':
if len(sys.argv) >= 2 and sys.argv[1] == 'ssl':
ssl(*sys.argv[2:])
else:
forward(*sys.argv[1:])