from flask import Flask, render_template, request, send_file, abort import subprocess import uuid import shutil from pathlib import Path from datetime import datetime import zipfile #app = Flask(__name__) app = Flask(__name__, static_folder="static") BASE = Path("/work") BASE.mkdir(exist_ok=True) def ts(): return datetime.now().strftime("%Y-%m-%d-%H-%M-%S") @app.route("/", methods=["GET", "POST"]) def index(): if request.method == "POST": job_id = str(uuid.uuid4()) job_dir = BASE / job_id job_dir.mkdir(parents=True) cmd = [ "python3", "/app/migrator.py", "--split", "--mapping", "/app/mapping.yaml", ] if request.form.get("from_class"): cmd += ["--from-ingress-class", request.form["from_class"]] if request.form.get("to_class"): cmd += ["--ingress-class", request.form["to_class"]] if request.form.get("namespace"): cmd += ["--namespace", request.form["namespace"]] subprocess.check_call(cmd, cwd=job_dir) timestamp = ts() # result.zip (yaml + report) result_zip = BASE / f"{timestamp}-result.zip" with zipfile.ZipFile(result_zip, "w", zipfile.ZIP_DEFLATED) as z: for p in (job_dir / "yaml").rglob("*"): z.write(p, p.relative_to(job_dir)) report = job_dir / "migration-report.md" if report.exists(): z.write(report, report.relative_to(job_dir)) # backup.zip backup_zip = BASE / f"{timestamp}-backup.zip" with zipfile.ZipFile(backup_zip, "w", zipfile.ZIP_DEFLATED) as z: for p in (job_dir / "backup").rglob("*"): z.write(p, p.relative_to(job_dir)) return preview(job_id, result_zip.name, backup_zip.name) return render_template("index.html") @app.route("/preview///") def preview(job_id, result_zip, backup_zip): job_dir = BASE / job_id def tree(root: Path): t = {} if not root.exists(): return t for ns in sorted(root.iterdir()): if ns.is_dir(): t[ns.name] = sorted(f.name for f in ns.iterdir() if f.is_file()) return t return render_template( "preview.html", job_id=job_id, yaml_tree=tree(job_dir / "yaml"), backup_tree=tree(job_dir / "backup"), result_zip=result_zip, backup_zip=backup_zip, ) @app.route("/view///") def view_file(job_id, kind, path): if kind not in ("yaml", "backup"): abort(404) f = BASE / job_id / kind / path if not f.exists(): abort(404) return f"
{f.read_text()}
" @app.route("/report/") def view_report(job_id): report = BASE / job_id / "migration-report.md" if not report.exists(): abort(404) return f"
{report.read_text()}
" @app.route("/download/") def download(name): path = BASE / name if not path.exists(): abort(404) return send_file(path, as_attachment=True) if __name__ == "__main__": app.run(host="0.0.0.0", port=8080, debug=False)