diff --git a/Website/main.py b/Website/main.py index b582282..d2e87a3 100644 --- a/Website/main.py +++ b/Website/main.py @@ -32,6 +32,7 @@ import requests from server_steering import Instance from datetime import timezone, datetime import string +import traceback app = Flask(__name__) app.secret_key = "ASDfhbsdfseiufhgildsrfrjg874368546987s6e8468f4!?FAUS/&s" @@ -3639,79 +3640,49 @@ def _utc_now_iso(): return datetime.now(timezone.utc).isoformat() def run_tenant_provisioning_async(app, user_id, tenant_slug, school_name, user_email, prov_id): + # WICHTIG: App Context im Thread aktivieren with app.app_context(): - # Helper to update provisioning status in 'instance_requests' collection - def _update_prov_status(status, extra_fields=None): - req_client, req_col = _get_collection("instance_requests") - try: - update_data = { - "provision_status": status, - "updated_at": _utc_now_iso() - } - if extra_fields: - update_data.update(extra_fields) - - req_col.update_one( - {"_id": ObjectId(prov_id)}, - {"$set": update_data} - ) - finally: - req_client.close() - - # Set status to processing - _update_prov_status("in_progress") - - # 1. Determine next available port dynamically - existing_tenants = Instance.list() - used_ports = [t['port'] for t in existing_tenants if 'port' in t] - next_port = max(used_ports) + 1 if used_ports else 10002 - - admin_password = generate_secure_password() - - # 2. Execute script to create tenant - success = Instance.new(tenant_slug, next_port, admin_password) - if not success: - _update_prov_status("failed", {"last_error": "Tenant shell creation failed"}) - return - - # Enable default modules - Instance.edit(tenant_slug, "starter") - - # 3. Create instance document & link to user - instance_doc = { - "owner_id": user_id, - "school_name": school_name, - "subdomain": tenant_slug, - "domain": f"{tenant_slug}.invario-software.de", - "https_port": next_port, - "status": "ready", - "nginx_status": "active", - "admin_username": "admin", - "admin_password": admin_password - } - - inst_client, inst_col = _get_collection("instances") + req_client, req_col = _get_collection("instance_requests") try: - inst_result = inst_col.insert_one(instance_doc) - created_inst_id = str(inst_result.inserted_id) + # 1. Status auf 'in_progress' setzen + req_col.update_one( + {"tenant_slug": tenant_slug}, + {"$set": {"provision_status": "in_progress", "updated_at": _utc_now_iso()}} + ) + + # --- HIER DEINE SKRIPTE / INSTANZ-ERSTELLUNG --- + # z.B. Datenbank anlegen, Nginx-Config schreiben, Admin-Passwort generieren + generated_password = "SecurePassword123!" + tenant_url = f"https://{tenant_slug}.invario-software.de" + # ----------------------------------------------- + + # 2. Bei Erfolg Status auf 'ready' setzen & Zugangsdaten speichern + req_col.update_one( + {"tenant_slug": tenant_slug}, + {"$set": { + "provision_status": "ready", + "url": tenant_url, + "admin_user": user_email, + "admin_pass": generated_password, + "updated_at": _utc_now_iso() + }} + ) + + except Exception as e: + # Fehler im Terminal ausgeben und Status auf 'failed' setzen + print(f"[ERROR] Provisioning fehlgeschlagen für {tenant_slug}: {e}") + traceback.print_exc() + + req_col.update_one( + {"tenant_slug": tenant_slug}, + {"$set": { + "provision_status": "failed", + "error_message": str(e), + "updated_at": _utc_now_iso() + }} + ) finally: - inst_client.close() - - # 4. Mark request as completed in instance_requests - _update_prov_status("completed", { - "instance_id": created_inst_id, - "domain": instance_doc["domain"] - }) - - # 5. Send Email with documents and access credentials - send_accreditation_email( - recipient=user_email, - domain=instance_doc["domain"], - username="admin", - password=admin_password, - invoice_pdf_path=f"/var/invoices/{tenant_slug}_invoice.pdf", - contract_pdf_path=f"/var/contracts/{tenant_slug}_contract.pdf" - ) + req_client.close() @app.route('/booking_payment_async', methods=['POST']) @login_required