From dc147def1be5feb1faff1f1179a2fec50756d9f5 Mon Sep 17 00:00:00 2001 From: AIIrondev Date: Tue, 25 Aug 2026 19:33:34 +0200 Subject: [PATCH] changes to the provisioning --- Website/main.py | 118 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 80 insertions(+), 38 deletions(-) diff --git a/Website/main.py b/Website/main.py index d2e87a3..6172bc6 100644 --- a/Website/main.py +++ b/Website/main.py @@ -3640,49 +3640,91 @@ 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(): - req_client, req_col = _get_collection("instance_requests") - try: - # 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, + # Hilfsfunktion zum Aktualisieren des Status + 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() + + # 1. Status auf "in_progress" setzen + _update_prov_status("in_progress") + + # GESAMTEN PROZESS IN TRY-EXCEPT PACKEN + try: + # 2. Port dynamisch ermitteln + 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() + + # 3. Skript für Tenant-Erstellung ausführen + success = Instance.new(tenant_slug, next_port, admin_password) + if not success: + _update_prov_status("failed", {"last_error": "Tenant shell creation failed"}) + return + + # Module aktivieren + Instance.edit(tenant_slug, "starter") + + # 4. Instanz in der Datenbank anlegen + domain = f"{tenant_slug}.invario-software.de" + instance_doc = { + "owner_id": user_id, + "school_name": school_name, + "subdomain": tenant_slug, + "domain": domain, + "https_port": next_port, + "status": "ready", + "nginx_status": "active", + "admin_username": "admin", + "admin_password": admin_password + } + + inst_client, inst_col = _get_collection("instances") + try: + inst_result = inst_col.insert_one(instance_doc) + created_inst_id = str(inst_result.inserted_id) + finally: + inst_client.close() + + # 5. E-Mail versenden (wird vor dem Status-Update gemacht, damit bei Crash 'failed' ausgelöst wird) + send_accreditation_email( + recipient=user_email, + domain=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" ) + # 6. Request als erfolgreich markieren (WICHTIG: Status "ready" und exakte Felder für Frontend) + _update_prov_status("ready", { + "instance_id": created_inst_id, + "url": f"https://{domain}", + "username": "admin", + "password": admin_password + # Optional: "invoice_url": f"/download/invoice/{tenant_slug}" falls du den PDF-Download im Frontend anbietest + }) + except Exception as e: - # Fehler im Terminal ausgeben und Status auf 'failed' setzen - print(f"[ERROR] Provisioning fehlgeschlagen für {tenant_slug}: {e}") + # Wenn irgendetwas im Block abstürzt, Frontend informieren! + print(f"[ERROR] Provisioning fehlgeschlagen für {tenant_slug}:") 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: - req_client.close() + _update_prov_status("failed", {"last_error": str(e)}) @app.route('/booking_payment_async', methods=['POST']) @login_required @@ -3714,7 +3756,7 @@ def booking_payment_async(): # Asynchronen Thread starten... thread = threading.Thread( target=run_tenant_provisioning_async, - args=(app, user_id, tenant_slug, school_name, user_email, prov_id) + args=(app._get_current_object(), user_id, tenant_slug, school_name, user_email, prov_id) ) thread.start()