ehh. I'm sorry.
This commit is contained in:
parent
f7c8eed701
commit
5becd6d9a1
8 changed files with 137 additions and 26 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -4,4 +4,5 @@ __pycache__
|
|||
.vscode
|
||||
clusters.json
|
||||
/nginx
|
||||
/autossl
|
||||
/autossl
|
||||
.env
|
18
README.md
18
README.md
|
@ -1,9 +1,21 @@
|
|||
# Nginx configurator (patent for that name is pending...)
|
||||
|
||||
# TODO
|
||||
* Add a way to generate autoincrementing config ID
|
||||
* document dhparam.pem generation
|
||||
|
||||
* Prepare config templates for nginx and dehydrated?
|
||||
* document dhparam.pem generation (`openssl dhparam -out ssl-dhparams.pem 4096` in /etc/autossl)
|
||||
* Limit current SSH keys to only config rsync and nginx reload
|
||||
* Write down how it works in human language
|
||||
* Create a guide how to use it to intrawiki
|
||||
* Teach everybody how to use it...
|
||||
|
||||
# Setup
|
||||
* `python3 -m venv .venv`
|
||||
* `source .venv/bin/activate`
|
||||
* `pip3 install -r ./requirements.txt`
|
||||
* `cp env.sample .env` # and customize to your needs
|
||||
|
||||
|
||||
|
||||
|
||||
# Contributions
|
||||
Please use `black` formatter.
|
||||
|
|
5
env.sample
Normal file
5
env.sample
Normal file
|
@ -0,0 +1,5 @@
|
|||
NGINX_DIR="/etc/nginx"
|
||||
DOMAINS_TXT="/etc/autossl/domains.txt"
|
||||
DEHYDRATED_LOC="/etc/autossl/dehydrated.sh"
|
||||
REMOTE="10.0.0.1"
|
||||
REMOTE_SSH_KEY="./ssh.key"
|
|
@ -1,18 +1,34 @@
|
|||
import os
|
||||
import json
|
||||
import pyinputplus as pyip
|
||||
from jinja2 import Environment, PackageLoader, select_autoescape
|
||||
from dotenv import load_dotenv
|
||||
import n_ssl
|
||||
|
||||
# Get clusters from json config
|
||||
with open("clusters.json") as json_file:
|
||||
CLUSTERS = json.load(json_file)["clusters"]
|
||||
|
||||
# Setup Jinja2
|
||||
jin = Environment(loader=PackageLoader("n-gen"), autoescape=select_autoescape())
|
||||
jin = Environment(loader=PackageLoader("n_gen"), autoescape=select_autoescape())
|
||||
|
||||
# ID of next config - TBD - read this from list of configs and increment!
|
||||
CONF_ID = 1
|
||||
load_dotenv()
|
||||
NGINX_DIR = os.getenv('NGINX_DIR')
|
||||
|
||||
|
||||
# Go through config names and find highest config number. Increment by 1 and use as new ID
|
||||
def get_conf_id(nginx_dir):
|
||||
list_auto = os.listdir(nginx_dir + "/sites/auto")
|
||||
list_custom = os.listdir(nginx_dir + "/sites/custom")
|
||||
domain_list = list_auto + list_custom
|
||||
last_id = 0
|
||||
for dom in domain_list:
|
||||
id = int(dom.split('-')[0])
|
||||
if id > last_id:
|
||||
last_id = id
|
||||
new_id = last_id + 1
|
||||
return(new_id)
|
||||
|
||||
def get_domains():
|
||||
new_domain = True
|
||||
domains = []
|
||||
|
@ -85,26 +101,59 @@ def input_check(domains, upstreams, port, proto):
|
|||
exit()
|
||||
|
||||
|
||||
def fill_template(id, domains, upstreams, port, proto):
|
||||
def create_nginx_config(id, domains, upstreams, port, proto):
|
||||
template = jin.get_template("nginx-site.conf")
|
||||
return template.render(
|
||||
id=id, domains=domains, upstreams=upstreams, port=port, proto=proto
|
||||
)
|
||||
|
||||
def write_nginx_config(config, nginx_dir, domains, conf_id):
|
||||
filename = str(conf_id) + "-" + domains[0] + ".conf"
|
||||
path = nginx_dir + "/sites/auto/" + filename
|
||||
with open(path, "w") as conf_file:
|
||||
conf_file.write(config)
|
||||
|
||||
def create_ssl_config(conf_id):
|
||||
template = jin.get_template("ssl.conf")
|
||||
return template.render(id=conf_id)
|
||||
|
||||
def write_ssl_config(config, conf_id, nginx_dir):
|
||||
filename = str(conf_id) + ".conf"
|
||||
path = nginx_dir + "/ssl/" + filename
|
||||
with open(path, "w") as conf_file:
|
||||
conf_file.write(config)
|
||||
|
||||
def ssl_continue():
|
||||
if pyip.inputYesNo("Do you want to prepare ssl certs and replicate the config? (y/n) ") == "yes":
|
||||
n_ssl.main()
|
||||
else:
|
||||
print("Ok, you can run n_ssl.py to do it later.")
|
||||
exit()
|
||||
|
||||
def main():
|
||||
print("This script will generate nginx configuration and for new service.\n")
|
||||
conf_id = get_conf_id(NGINX_DIR)
|
||||
domains = get_domains()
|
||||
upstreams = get_upstreams(CLUSTERS)
|
||||
port = get_port()
|
||||
proto = get_proto()
|
||||
input_check(domains, upstreams, port, proto)
|
||||
print(fill_template(CONF_ID, domains, upstreams, port, proto))
|
||||
nginx_config = create_nginx_config(conf_id, domains, upstreams, port, proto)
|
||||
write_nginx_config(nginx_config, NGINX_DIR, domains, conf_id)
|
||||
|
||||
ssl_config = create_ssl_config(conf_id)
|
||||
write_ssl_config(ssl_config, conf_id, NGINX_DIR)
|
||||
|
||||
print("Nginx config created.")
|
||||
ssl_continue()
|
||||
|
||||
|
||||
|
||||
|
||||
# def test():
|
||||
# print(fill_template("1110", ['nolog.cz', 'www.nolog.cz'], ['10.0.0.1', '10.0.0.2'], 80, 'https://'))
|
||||
# print(create_nginx_config("1110", ['nolog.cz', 'www.nolog.cz'], ['10.0.0.1', '10.0.0.2'], 80, 'https://'))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
# test()
|
||||
|
||||
|
|
@ -1,16 +1,19 @@
|
|||
import os
|
||||
import subprocess
|
||||
import re
|
||||
import sysrsync
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# NGINX_DIR="/etc/nginx"
|
||||
# DOMAINS_TXT = "/etc/autossl/domains.txt"
|
||||
# DEHYDRATED_LOC = "/etc/autossl/dehydrated.sh"
|
||||
|
||||
NGINX_DIR = "./nginx"
|
||||
DOMAINS_TXT = "./autossl/domains.txt"
|
||||
DEHYDRATED_LOC = "./autossl/dehydrated.sh"
|
||||
|
||||
REMOTE = "10.55.55.55" # make a .env variable or something like that. It will be different on each server
|
||||
load_dotenv()
|
||||
NGINX_DIR = os.getenv('NGINX_DIR')
|
||||
DOMAINS_TXT = os.getenv('DOMAINS_TXT')
|
||||
DEHYDRATED_LOC = os.getenv('DEHYDRATED_LOC')
|
||||
REMOTE = os.getenv('REMOTE')
|
||||
REMOTE_SSH_KEY = os.getenv('REMOTE_SSH_KEY')
|
||||
|
||||
|
||||
def create_domfile():
|
||||
|
@ -70,22 +73,51 @@ def reload_local_nginx():
|
|||
exit()
|
||||
|
||||
|
||||
def remote_replication(remote):
|
||||
# Do RSYNC to second server
|
||||
return True
|
||||
def remote_replication(remote, ssh_key):
|
||||
# Copy nginx config to second server
|
||||
sysrsync.run(
|
||||
source="/etc/nginx/",
|
||||
destination="/etc/nginx/",
|
||||
destination_ssh=remote,
|
||||
private_key=ssh_key,
|
||||
options=["-a"],
|
||||
)
|
||||
# Copy certificates to second server
|
||||
sysrsync.run(
|
||||
source="/etc/autossl/",
|
||||
destination="/etc/autossl/",
|
||||
destination_ssh=remote,
|
||||
private_key=ssh_key,
|
||||
options=["-a"],
|
||||
)
|
||||
|
||||
|
||||
def remote_reload(remote):
|
||||
def remote_reload(remote, ssh_key):
|
||||
# Check and reload nginx on second server
|
||||
return True
|
||||
nginx_check = subprocess.run(
|
||||
["ssh", "-i", ssh_key, remote, "nginx", "-t"], capture_output=True, text=True
|
||||
)
|
||||
if nginx_check.returncode != 0:
|
||||
print("Remote nginx config is not valid! Please check manually.")
|
||||
print(nginx_check.stdout)
|
||||
return False
|
||||
else:
|
||||
nginx_reload = subprocess.run(
|
||||
["ssh", "-i", ssh_key, remote, "systemctl", "reload", "nginx.service"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if nginx_reload.returncode != 0:
|
||||
print("Remote nginx reload failed, please check manually.")
|
||||
print(nginx_reload.stdout)
|
||||
|
||||
|
||||
def main():
|
||||
# create_domfile()
|
||||
create_domfile()
|
||||
request_cert()
|
||||
reload_local_nginx()
|
||||
remote_replication(REMOTE)
|
||||
remote_reload(REMOTE)
|
||||
remote_replication(REMOTE, REMOTE_SSH_KEY)
|
||||
remote_reload(REMOTE, REMOTE_SSH_KEY)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
10
new_service.sh
Normal file
10
new_service.sh
Normal file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
kill -s $(keepalived --signum=DATA) $(cat /var/run/keepalived.pid)
|
||||
STATE=$(cat /tmp/keepalived.data |grep MASTER)
|
||||
|
||||
if [[ -z "${STATE}" ]]; then
|
||||
echo "This is a secondary backup server, run the script on current master"
|
||||
else
|
||||
python3 n_gen.py
|
||||
fi
|
|
@ -1,2 +1,4 @@
|
|||
pyinputplus
|
||||
Jinja2
|
||||
Jinja2
|
||||
sysrsync
|
||||
python-dotenv
|
|
@ -1,5 +1,5 @@
|
|||
# ID: {{ id }}
|
||||
# Service configured by nxa.py
|
||||
# Service configured by n_gen.py
|
||||
|
||||
upstream up_{{ id }} {
|
||||
{%- for upstream in upstreams %}
|
||||
|
|
Loading…
Reference in a new issue