3
This commit is contained in:
@@ -1,174 +0,0 @@
|
|||||||
import reflex as rx
|
|
||||||
import subprocess
|
|
||||||
import os
|
|
||||||
import glob
|
|
||||||
import datetime
|
|
||||||
import asyncio
|
|
||||||
|
|
||||||
# --- PFADE ABSOLUT DEFINIEREN ---
|
|
||||||
# Holt das Verzeichnis, in dem die app.py liegt (test_ansible/app/)
|
|
||||||
APP_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
# Geht eine Ebene höher in das Hauptverzeichnis (test_ansible/)
|
|
||||||
BASE_DIR = os.path.dirname(APP_DIR)
|
|
||||||
|
|
||||||
PLAYBOOK_DIR = os.path.join(BASE_DIR, "playbooks")
|
|
||||||
OUTPUT_DIR = os.path.join(BASE_DIR, "outputs")
|
|
||||||
|
|
||||||
# Sichere Ordner-Erstellung
|
|
||||||
try:
|
|
||||||
os.makedirs(PLAYBOOK_DIR, exist_ok=True)
|
|
||||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Fehler bei der Ordner-Erstellung: {str(e)}")
|
|
||||||
|
|
||||||
|
|
||||||
class AppState(rx.State):
|
|
||||||
playbooks: list[str] = []
|
|
||||||
selected_playbook: str = ""
|
|
||||||
output: str = ""
|
|
||||||
is_running: bool = False
|
|
||||||
error: str = ""
|
|
||||||
|
|
||||||
# Füge diesen Event-Handler manuell hinzu:
|
|
||||||
def set_selected_playbook(self, val: str):
|
|
||||||
self.selected_playbook = val
|
|
||||||
|
|
||||||
|
|
||||||
async def load_playbooks(self):
|
|
||||||
"""Lädt alle Playbooks aus dem konfigurierten Ordner."""
|
|
||||||
try:
|
|
||||||
# --- DIESE PRINTS HIER HINZUFÜGEN ---
|
|
||||||
print(f"[DEBUG] Suche in Ordner: {PLAYBOOK_DIR}")
|
|
||||||
print(f"[DEBUG] Existiert der Ordner? {os.path.exists(PLAYBOOK_DIR)}")
|
|
||||||
|
|
||||||
playbook_files = glob.glob(os.path.join(PLAYBOOK_DIR, "*.yml")) + \
|
|
||||||
glob.glob(os.path.join(PLAYBOOK_DIR, "*.yaml"))
|
|
||||||
|
|
||||||
print(f"[DEBUG] Gefundene Dateien: {playbook_files}")
|
|
||||||
# ------------------------------------
|
|
||||||
|
|
||||||
self.playbooks = [os.path.basename(p) for p in playbook_files]
|
|
||||||
if self.playbooks:
|
|
||||||
self.selected_playbook = self.playbooks[0]
|
|
||||||
else:
|
|
||||||
self.selected_playbook = ""
|
|
||||||
self.error = ""
|
|
||||||
except Exception as e:
|
|
||||||
self.error = f"Fehler beim Laden der Playbooks: {str(e)}"
|
|
||||||
|
|
||||||
|
|
||||||
async def run_playbook(self):
|
|
||||||
"""Führt das ausgewählte Playbook asynchron aus und speichert den Output."""
|
|
||||||
if not self.selected_playbook:
|
|
||||||
self.error = "Bitte wählen Sie ein Playbook aus."
|
|
||||||
return
|
|
||||||
|
|
||||||
self.is_running = True
|
|
||||||
self.error = ""
|
|
||||||
self.output = "Wird ausgeführt..."
|
|
||||||
yield # State aktualisieren, bevor die lange Aufgabe startet
|
|
||||||
|
|
||||||
playbook_path = os.path.join(PLAYBOOK_DIR, self.selected_playbook)
|
|
||||||
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
||||||
output_filename = f"{timestamp}_{self.selected_playbook.replace('.yml', '').replace('.yaml', '')}.txt"
|
|
||||||
output_path = os.path.join(OUTPUT_DIR, output_filename)
|
|
||||||
|
|
||||||
try:
|
|
||||||
# ansible-playbook Befehl asynchron ausführen
|
|
||||||
proc = await asyncio.create_subprocess_exec(
|
|
||||||
"ansible-playbook", playbook_path,
|
|
||||||
stdout=asyncio.subprocess.PIPE,
|
|
||||||
stderr=asyncio.subprocess.PIPE
|
|
||||||
)
|
|
||||||
|
|
||||||
# Timeout von 300 Sekunden (5 Minuten)
|
|
||||||
try:
|
|
||||||
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=300)
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
proc.kill()
|
|
||||||
await proc.wait()
|
|
||||||
raise asyncio.TimeoutError("Playbook hat das Timeout überschritten.")
|
|
||||||
|
|
||||||
output_text = stdout.decode() + stderr.decode()
|
|
||||||
self.output = output_text
|
|
||||||
|
|
||||||
# Output speichern
|
|
||||||
try:
|
|
||||||
with open(output_path, "w", encoding="utf-8") as f:
|
|
||||||
f.write(output_text)
|
|
||||||
except Exception as e:
|
|
||||||
self.error = f"Fehler beim Speichern des Outputs: {str(e)}"
|
|
||||||
|
|
||||||
if proc.returncode != 0:
|
|
||||||
self.error = f"Playbook wurde mit Fehlercode {proc.returncode} beendet."
|
|
||||||
else:
|
|
||||||
duration = (datetime.datetime.now() - start_time).total_seconds()
|
|
||||||
self.error = ""
|
|
||||||
rx.notify(
|
|
||||||
title="Erfolgreich ausgeführt",
|
|
||||||
description=f"{self.selected_playbook} in {duration:.2f} Sekunden abgeschlossen",
|
|
||||||
status="success",
|
|
||||||
duration=3000
|
|
||||||
)
|
|
||||||
|
|
||||||
except asyncio.TimeoutError as e:
|
|
||||||
self.error = str(e)
|
|
||||||
self.output = "Fehler: Timeout"
|
|
||||||
except Exception as e:
|
|
||||||
self.error = f"Ein Fehler ist aufgetreten: {str(e)}"
|
|
||||||
self.output = "Fehler bei der Ausführung"
|
|
||||||
finally:
|
|
||||||
self.is_running = False
|
|
||||||
yield # State nach Abschluss aktualisieren
|
|
||||||
def index():
|
|
||||||
return rx.container(
|
|
||||||
rx.heading("Ansible Playbook Runner", size="6"),
|
|
||||||
|
|
||||||
# Flexiblerer und reaktiverer Aufbau des Dropdowns:
|
|
||||||
rx.select.root(
|
|
||||||
rx.select.trigger(placeholder="Wählen Sie ein Playbook..."),
|
|
||||||
rx.select.content(
|
|
||||||
rx.select.group(
|
|
||||||
rx.foreach(
|
|
||||||
AppState.playbooks,
|
|
||||||
lambda item: rx.select.item(item, value=item)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
value=AppState.selected_playbook,
|
|
||||||
on_change=AppState.set_selected_playbook,
|
|
||||||
width="100%",
|
|
||||||
),
|
|
||||||
|
|
||||||
rx.button(
|
|
||||||
"Ausführen",
|
|
||||||
on_click=AppState.run_playbook,
|
|
||||||
disabled=AppState.is_running,
|
|
||||||
color_scheme="blue",
|
|
||||||
margin_top="1em",
|
|
||||||
),
|
|
||||||
rx.text(
|
|
||||||
AppState.error,
|
|
||||||
color=rx.cond(AppState.error, "red", "transparent"),
|
|
||||||
margin_top="1em",
|
|
||||||
),
|
|
||||||
rx.text_area(
|
|
||||||
value=AppState.output,
|
|
||||||
width="100%",
|
|
||||||
height="400px",
|
|
||||||
margin_top="1em",
|
|
||||||
disabled=True,
|
|
||||||
resize="none",
|
|
||||||
),
|
|
||||||
padding="2em",
|
|
||||||
max_width="800px",
|
|
||||||
margin="auto",
|
|
||||||
)
|
|
||||||
|
|
||||||
app = rx.App()
|
|
||||||
app.add_page(index, route="/", on_load=AppState.load_playbooks)
|
|
||||||
if __name__ == "__main__":
|
|
||||||
try:
|
|
||||||
app.run(debug=True)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Fehler bei der Ausführung: {str(e)}")
|
|
||||||
Reference in New Issue
Block a user