From 71a8823b35f7bc9e179226c55fa995addabb8de3 Mon Sep 17 00:00:00 2001 From: AIIrondev Date: Wed, 5 Aug 2026 18:53:25 +0200 Subject: [PATCH] Addition of the nginx forwarding --- manage-tenant.sh | 264 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 260 insertions(+), 4 deletions(-) diff --git a/manage-tenant.sh b/manage-tenant.sh index b59ba5b..8751655 100755 --- a/manage-tenant.sh +++ b/manage-tenant.sh @@ -12,6 +12,250 @@ fi # Resolve script directory so config paths are deterministic even when called via sudo SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONFIG_FILE="$SCRIPT_DIR/config.json" +NGINX_DOMAIN_BASE="${INVENTAR_TENANT_DOMAIN_BASE:-invario-software.de}" +NGINX_PROXY_HOST="${INVENTAR_NGINX_PROXY_HOST:-172.17.0.1}" +NGINX_SITES_AVAILABLE="${INVENTAR_NGINX_SITES_AVAILABLE:-/etc/nginx/sites-available}" +NGINX_SITES_ENABLED="${INVENTAR_NGINX_SITES_ENABLED:-/etc/nginx/sites-enabled}" +NGINX_SITE_PREFIX="${INVENTAR_NGINX_SITE_PREFIX:-inventarsystem}" +CERTBOT_EMAIL="${INVENTAR_CERTBOT_EMAIL:-}" + +tenant_domain() { + printf '%s.%s' "$1" "$NGINX_DOMAIN_BASE" +} + +tenant_nginx_site_path() { + printf '%s/%s-%s.conf' "$NGINX_SITES_AVAILABLE" "$NGINX_SITE_PREFIX" "$1" +} + +tenant_nginx_enabled_path() { + printf '%s/%s-%s.conf' "$NGINX_SITES_ENABLED" "$NGINX_SITE_PREFIX" "$1" +} + +run_host_command() { + if [ "$(id -u)" -eq 0 ]; then + "$@" + elif command -v sudo >/dev/null 2>&1; then + sudo "$@" + else + return 127 + fi +} + +reload_host_nginx() { + if command -v nginx >/dev/null 2>&1 || command -v sudo >/dev/null 2>&1; then + if ! run_host_command nginx -t; then + echo "Warning: nginx configuration test failed; skipping reload." + return 1 + fi + + if command -v systemctl >/dev/null 2>&1; then + if ! run_host_command systemctl reload nginx; then + echo "Warning: systemctl reload nginx failed." + return 1 + fi + else + if ! run_host_command nginx -s reload; then + echo "Warning: nginx reload failed." + return 1 + fi + fi + fi +} + +write_tenant_nginx_config() { + local tenant_id="$1" + local port="$2" + local domain site_path enabled_path + + domain="$(tenant_domain "$tenant_id")" + site_path="$(tenant_nginx_site_path "$tenant_id")" + enabled_path="$(tenant_nginx_enabled_path "$tenant_id")" + + if [ -z "$port" ]; then + echo "Warning: No port configured for tenant '$tenant_id'; skipping nginx vhost creation." + return 0 + fi + + if ! run_host_command mkdir -p "$NGINX_SITES_AVAILABLE" "$NGINX_SITES_ENABLED"; then + echo "Warning: Unable to prepare nginx site directories; skipping reverse-proxy setup." + return 0 + fi + + local have_cert=false + + if [ -f "/etc/letsencrypt/live/$domain/fullchain.pem" ] && [ -f "/etc/letsencrypt/live/$domain/privkey.pem" ]; then + have_cert=true + else + if [ "$(id -u)" -eq 0 ]; then + cat > "$site_path" </dev/null </dev/null 2>&1 || command -v sudo >/dev/null 2>&1; then + local certbot_args=(certbot --nginx --non-interactive --agree-tos -d "$domain") + if [ -n "$CERTBOT_EMAIL" ]; then + certbot_args+=(--email "$CERTBOT_EMAIL") + else + certbot_args+=(--register-unsafely-without-email) + fi + + if ! run_host_command "${certbot_args[@]}"; then + echo "Warning: certbot failed for tenant '$tenant_id'; keeping HTTP-only vhost for now." + return 1 + fi + + have_cert=true + fi + fi + + if [ "$have_cert" != true ]; then + echo "Warning: No TLS certificate available for tenant '$tenant_id'; leaving HTTP-only nginx config in place." + return 1 + fi + + if [ "$(id -u)" -eq 0 ]; then + cat > "$site_path" </dev/null </dev/null 2>&1 || command -v sudo >/dev/null 2>&1; then + run_host_command certbot delete --cert-name "$domain" --non-interactive >/dev/null 2>&1 || true + fi + + reload_host_nginx || true +} ensure_runtime_config_json() { local config_path backup_path @@ -505,15 +749,18 @@ ${YELLOW}Nutzung:${RESET} $0 [tenant_id] [optionen] ${BLUE}${BOLD}VERFÜGBARE BEFEHLE:${RESET} ${GREEN}add${RESET} [port] - Legt einen neuen Tenant an, registriert den Port und initialisiert - die MongoDB-Datenbank mit einem Standard-Admin (${YELLOW}admin / admin123${RESET}). + Legt einen neuen Tenant an, registriert den Port, richtet den nginx-Host + für ${YELLOW}.invario-software.de${RESET} ein und initialisiert + die MongoDB-Datenbank mit einem Standard-Admin (${YELLOW}admin / admin123${RESET}). ${GREEN}trial${RESET} [port] [tage] Erstellt einen temporären Test-Tenant. Standardlaufzeit: 7 Tage. - Läuft automatisch ab und löscht sich selbst. + Läuft automatisch ab, löscht sich selbst und bekommt die gleiche nginx/ + Certbot-Anbindung wie ein normaler Tenant. ${GREEN}remove${RESET} [-y|--yes] - Löscht einen Tenant, seine Konfiguration, Ports und die Datenbank. + Löscht einen Tenant, seine Konfiguration, Ports, nginx-VHost und das + zugehörige Let's-Encrypt-Zertifikat sowie die Datenbank. Nutze ${RED}-y${RESET}, um die Bestätigungsabfrage zu überspringen. ${GREEN}restart-tenant${RESET} @@ -574,11 +821,16 @@ case "$COMMAND" in register_tenant_port "$TENANT_ID" "$PORT_ARG" update_runtime_ports "$PORT_ARG" sync_tenant_port_map + if ! write_tenant_nginx_config "$TENANT_ID" "$PORT_ARG"; then + echo "Warning: nginx/certbot provisioning for '$TENANT_ID' could not be completed automatically." + fi if [ -n "$(docker ps -qf 'name=app' | head -n 1)" ]; then restart_app_container fi fi + + echo "Adding new tenant '$TENANT_ID'..." echo "Initializing database for $TENANT_ID..." initialize_tenant_database "$TENANT_ID" "standard" @@ -603,6 +855,9 @@ case "$COMMAND" in register_tenant_port "$TENANT_ID" "$PORT_ARG" update_runtime_ports "$PORT_ARG" sync_tenant_port_map + if ! write_tenant_nginx_config "$TENANT_ID" "$PORT_ARG"; then + echo "Warning: nginx/certbot provisioning for trial tenant '$TENANT_ID' could not be completed automatically." + fi fi write_trial_tenant_config "$TENANT_ID" "$PORT_ARG" "$DAYS_ARG" @@ -682,6 +937,7 @@ case "$COMMAND" in if [ -n "$port_to_remove" ]; then remove_runtime_port "$port_to_remove" fi + remove_tenant_nginx_config "$TENANT_ID" sync_tenant_port_map if [ -n "$(docker ps -qf 'name=app' | head -n 1)" ]; then restart_app_container