157 lines
5.5 KiB
Python
157 lines
5.5 KiB
Python
|
import requests
|
||
|
import json
|
||
|
import argparse
|
||
|
import mysql.connector
|
||
|
import re
|
||
|
import os
|
||
|
from dotenv import load_dotenv
|
||
|
|
||
|
load_dotenv()
|
||
|
|
||
|
class NginxProxyManager:
|
||
|
def __init__(self, host, email, password):
|
||
|
self.host = host
|
||
|
self.email = email
|
||
|
self.password = password
|
||
|
self.token = None
|
||
|
|
||
|
def login(self):
|
||
|
url = f"{self.host}/api/tokens"
|
||
|
payload = {
|
||
|
"identity": self.email,
|
||
|
"secret": self.password
|
||
|
}
|
||
|
headers = {
|
||
|
"Content-Type": "application/json"
|
||
|
}
|
||
|
response = requests.post(url, headers=headers, data=json.dumps(payload))
|
||
|
if response.status_code == 200:
|
||
|
self.token = response.json()["token"]
|
||
|
print("Login successful.")
|
||
|
else:
|
||
|
print(f"Failed to login: {response.text}")
|
||
|
exit(1)
|
||
|
|
||
|
def get_proxy_hosts(self):
|
||
|
if not self.token:
|
||
|
self.login()
|
||
|
|
||
|
url = f"{self.host}/api/nginx/proxy-hosts"
|
||
|
headers = {
|
||
|
"Authorization": f"Bearer {self.token}"
|
||
|
}
|
||
|
response = requests.get(url, headers=headers)
|
||
|
if response.status_code == 200:
|
||
|
return response.json()
|
||
|
else:
|
||
|
print(f"Failed to get proxy hosts: {response.text}")
|
||
|
return []
|
||
|
|
||
|
def get_proxy_host(self, host_id):
|
||
|
if not self.token:
|
||
|
self.login()
|
||
|
|
||
|
url = f"{self.host}/api/nginx/proxy-hosts/{host_id}"
|
||
|
headers = {
|
||
|
"Authorization": f"Bearer {self.token}"
|
||
|
}
|
||
|
response = requests.get(url, headers=headers)
|
||
|
if response.status_code == 200:
|
||
|
return response.json()
|
||
|
else:
|
||
|
print(f"Failed to get proxy host {host_id}: {response.text}")
|
||
|
return None
|
||
|
|
||
|
def update_proxy_host_config(self, host_id, config):
|
||
|
if not self.token:
|
||
|
self.login()
|
||
|
|
||
|
url = f"{self.host}/api/nginx/proxy-hosts/{host_id}"
|
||
|
payload = {
|
||
|
"advanced_config": config
|
||
|
}
|
||
|
headers = {
|
||
|
"Authorization": f"Bearer {self.token}",
|
||
|
"Content-Type": "application/json"
|
||
|
}
|
||
|
response = requests.put(url, headers=headers, data=json.dumps(payload))
|
||
|
if response.status_code == 200:
|
||
|
print(f"Successfully updated proxy host {host_id}")
|
||
|
else:
|
||
|
print(f"Failed to update proxy host {host_id}: {response.text}")
|
||
|
|
||
|
def get_streams_from_db(db_host, db_user, db_pass, db_name, db_port):
|
||
|
try:
|
||
|
conn = mysql.connector.connect(
|
||
|
host=db_host,
|
||
|
user=db_user,
|
||
|
password=db_pass,
|
||
|
database=db_name,
|
||
|
port=db_port
|
||
|
)
|
||
|
cursor = conn.cursor(dictionary=True)
|
||
|
cursor.execute("SELECT streamName, streamURL FROM streams")
|
||
|
streams = cursor.fetchall()
|
||
|
cursor.close()
|
||
|
conn.close()
|
||
|
return streams
|
||
|
except mysql.connector.Error as err:
|
||
|
print(f"Error connecting to database: {err}")
|
||
|
return []
|
||
|
|
||
|
def update_config_with_streams(config, streams):
|
||
|
for stream in streams:
|
||
|
stream_name = stream['streamName']
|
||
|
stream_url = stream['streamURL']
|
||
|
# Use a more specific regex to avoid replacing parts of other URLs
|
||
|
pattern = re.compile(f'(location ~ \^/{re.escape(stream_name)}\(\.\*\)\$ {{\s*return 302 )([^;]+)(;\\s*}})')
|
||
|
config = pattern.sub(f'\\1{stream_url}/$1$is_args$args\\3', config)
|
||
|
return config
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
parser = argparse.ArgumentParser(description="Modify Nginx Proxy Manager custom configuration.")
|
||
|
parser.add_argument("--list-hosts", action="store_true", help="List all proxy hosts")
|
||
|
parser.add_argument("--host-id", type=int, help="The ID of the proxy host to modify")
|
||
|
parser.add_argument("--config-file", type=str, help="Path to the file containing the new advanced configuration")
|
||
|
parser.add_argument("--download-config", type=str, help="Path to save the current advanced configuration")
|
||
|
parser.add_argument("--update-from-db", action="store_true", help="Update the configuration from the database")
|
||
|
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
npm_host = os.getenv("NPM_HOST")
|
||
|
npm_email = os.getenv("NPM_EMAIL")
|
||
|
npm_password = os.getenv("NPM_PASSWORD")
|
||
|
db_host = os.getenv("DBHOST")
|
||
|
db_user = os.getenv("DBUSER")
|
||
|
db_pass = os.getenv("DBPASS")
|
||
|
db_name = os.getenv("DATABASE")
|
||
|
db_port = os.getenv("DBPORT")
|
||
|
|
||
|
npm = NginxProxyManager(npm_host, npm_email, npm_password)
|
||
|
npm.login()
|
||
|
|
||
|
if args.list_hosts:
|
||
|
hosts = npm.get_proxy_hosts()
|
||
|
for host in hosts:
|
||
|
print(f"ID: {host['id']}, Domains: {', '.join(host['domain_names'])}")
|
||
|
|
||
|
if args.host_id and args.download_config:
|
||
|
host = npm.get_proxy_host(args.host_id)
|
||
|
if host:
|
||
|
with open(args.download_config, 'w') as f:
|
||
|
f.write(host.get('advanced_config', ''))
|
||
|
print(f"Configuration for host {args.host_id} downloaded to {args.download_config}")
|
||
|
|
||
|
if args.host_id and args.config_file:
|
||
|
with open(args.config_file, 'r') as f:
|
||
|
config = f.read()
|
||
|
npm.update_proxy_host_config(args.host_id, config)
|
||
|
|
||
|
if args.host_id and args.update_from_db:
|
||
|
host = npm.get_proxy_host(args.host_id)
|
||
|
if host:
|
||
|
current_config = host.get('advanced_config', '')
|
||
|
streams = get_streams_from_db(db_host, db_user, db_pass, db_name, db_port)
|
||
|
if streams:
|
||
|
new_config = update_config_with_streams(current_config, streams)
|
||
|
npm.update_proxy_host_config(args.host_id, new_config)
|