api endpoints ekle
Deploy / deploy (push) Successful in 19s

This commit is contained in:
2026-09-23 15:27:03 +03:00
parent 36c220b1eb
commit 29cd52cdf9
+96 -2
View File
@@ -3,13 +3,20 @@ import os
import subprocess
import requests
from flask import Flask, redirect, render_template_string
from flask import Flask, jsonify, redirect, render_template_string, request
app = Flask(__name__)
CF_API_TOKEN = os.environ["CF_API_TOKEN"]
CF_ZONE_ID = os.environ["CF_ZONE_ID"]
SELF_NAME = os.environ.get("SELF_CONTAINER_NAME", "")
API_TOKEN = os.environ["PANEL_API_TOKEN"]
SERVER_IP = os.environ.get("SERVER_IP", "148.135.181.126")
def check_auth():
auth = request.headers.get("Authorization", "")
return auth == f"Bearer {API_TOKEN}"
def extract_hostname(labels, name):
@@ -46,6 +53,33 @@ def list_projects():
return projects
def find_container_hostname(name):
result = subprocess.run(["docker", "inspect", name], capture_output=True, text=True)
if result.returncode != 0:
return None
info = json.loads(result.stdout)[0]
labels = info["Config"]["Labels"] or {}
return extract_hostname(labels, name)
def ensure_dns(hostname):
existing = requests.get(
f"https://api.cloudflare.com/client/v4/zones/{CF_ZONE_ID}/dns_records",
params={"type": "A", "name": hostname},
headers={"Authorization": f"Bearer {CF_API_TOKEN}"},
timeout=10,
).json()
if existing.get("result"):
return {"created": False}
requests.post(
f"https://api.cloudflare.com/client/v4/zones/{CF_ZONE_ID}/dns_records",
headers={"Authorization": f"Bearer {CF_API_TOKEN}", "Content-Type": "application/json"},
json={"type": "A", "name": hostname, "content": SERVER_IP, "ttl": 1, "proxied": True},
timeout=10,
)
return {"created": True}
def delete_dns_record(hostname):
if not hostname:
return
@@ -118,7 +152,7 @@ def index():
@app.route("/delete/<name>", methods=["POST"])
def delete(name):
def delete_ui(name):
projects = {p["name"]: p for p in list_projects()}
target = projects.get(name)
if target:
@@ -127,5 +161,65 @@ def delete(name):
return redirect("/")
@app.route("/api/ensure-dns", methods=["POST"])
def api_ensure_dns():
if not check_auth():
return jsonify({"error": "unauthorized"}), 401
body = request.get_json(force=True)
hostname = body.get("hostname")
if not hostname:
return jsonify({"error": "hostname required"}), 400
result = ensure_dns(hostname)
return jsonify(result), 200
@app.route("/api/deploy", methods=["POST"])
def api_deploy():
if not check_auth():
return jsonify({"error": "unauthorized"}), 401
body = request.get_json(force=True)
name = body.get("name")
hostname = body.get("hostname")
port = str(body.get("port", "80"))
if not name or not hostname:
return jsonify({"error": "name and hostname required"}), 400
current_hostname = find_container_hostname(name)
if current_hostname is not None and current_hostname != hostname:
return jsonify({
"error": "name_conflict",
"message": f"'{name}' is already deployed with a different hostname ({current_hostname}).",
}), 409
ensure_dns(hostname)
subprocess.run(["docker", "rm", "-f", name])
rule = f"Host(`{hostname}`)"
subprocess.run([
"docker", "run", "-d",
"--name", name,
"--network", "proxy",
"--restart", "always",
"-l", "traefik.enable=true",
"-l", f"traefik.http.routers.{name}.rule={rule}",
"-l", f"traefik.http.routers.{name}.entrypoints=websecure",
"-l", f"traefik.http.routers.{name}.tls.certresolver=letsencrypt",
"-l", f"traefik.http.services.{name}.loadbalancer.server.port={port}",
f"{name}:latest",
], check=True)
return jsonify({"status": "deployed", "url": f"https://{hostname}"}), 200
@app.route("/api/deploy/<name>", methods=["DELETE"])
def api_delete(name):
if not check_auth():
return jsonify({"error": "unauthorized"}), 401
hostname = find_container_hostname(name)
subprocess.run(["docker", "rm", "-f", name])
delete_dns_record(hostname)
return jsonify({"status": "deleted"}), 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)