refactor: guided UI — no fw.conf needed, add node deploys immediately

- No fw.conf required on first run — only option is Add Node
- Adding a node deploys it immediately (saves to fw.conf)
- Shows pending deploys when fw.conf has undeployed nodes
- Status/Remove shown only when nodes are deployed
This commit is contained in:
admin 2026-08-03 15:07:58 +00:00
parent 3ba8e6e6c2
commit ebde840b28

View file

@ -10,7 +10,7 @@ CONF = f"{APP}/fw.conf"
STATE = f"{APP}/state.json" STATE = f"{APP}/state.json"
DOCKER_DIR = f"{BASE}/docker" DOCKER_DIR = f"{BASE}/docker"
OFFLINE_DIR = f"{BASE}/offline" OFFLINE_DIR = f"{BASE}/offline"
WALLARM_IMAGE = os.environ.get("WALLARM_IMAGE", "wallarm/node:6.13.0") WALLARM_IMAGE = os.environ.get("WALLARM_IMAGE", "wallarm/node:6.11.0-rc1")
# Ensure Docker is in PATH # Ensure Docker is in PATH
os.environ["PATH"] = f"{DOCKER_DIR}/bin:{os.environ.get('PATH', '')}" os.environ["PATH"] = f"{DOCKER_DIR}/bin:{os.environ.get('PATH', '')}"
@ -126,33 +126,53 @@ def main():
if len(sys.argv) > 1 and sys.argv[1] == "--deploy-all": if len(sys.argv) > 1 and sys.argv[1] == "--deploy-all":
return deploy_all() return deploy_all()
print(f"═══ Wallarm Docker Manager v{VERSION} ═══\n") print(f"═══ Wallarm Node Manager v{VERSION} ═══\n")
print("Preflight checks...")
if not shutil.which("docker"):
print(" ❌ Docker not found. Run setup.sh first.")
sys.exit(1)
print(" ✅ Docker ready\n")
# Check for fw.conf
cfg = load_config() cfg = load_config()
if not cfg: deployed = {n["name"] for n in load_state().get("nodes", [])}
print("No fw.conf found. Create one? [Y/n]: ", end="")
if input().strip().lower() in ("", "y", "yes"):
create_config()
cfg = load_config()
else:
print("Create /opt/fw/app/fw.conf manually or use the menu to add nodes.")
while True: while True:
print("\n─── Menu ───") undeployed = [k for k in cfg if k not in deployed]
print(" [1] Deploy all")
print(" [2] Add a node") print("─── Menu ───")
print(" [3] Status") if undeployed:
print(" [4] Remove a node") print(f" Nodes ready to deploy: {', '.join(undeployed)}")
print(" [5] Edit a node") else:
print(" No nodes pending deployment.")
if undeployed:
print(" [1] Deploy all pending nodes")
print(" [2] Add a new node")
if deployed:
print(" [3] Show status")
print(" [4] Remove a node")
print(" [q] Quit") print(" [q] Quit")
c = input("\nChoice: ").strip() c = input("\nChoice: ").strip()
if c == "1": deploy_all()
elif c == "2": add_node() if c == "1" and undeployed:
elif c == "3": container_status() for name in undeployed:
elif c == "4": remove_menu() nc = cfg[name]
elif c == "5": edit_menu() print(f"\nDeploying {name}...")
elif c.lower() == "q": break deploy_container(name, nc["token"], nc.get("cloud","EU"),
str(nc.get("port","8081")), nc.get("upstream_ip",""),
str(nc.get("upstream_port","80")), "",
nc.get("mode","monitoring"))
elif c == "2":
add_node()
cfg = load_config()
deployed = {n["name"] for n in load_state().get("nodes", [])}
elif c == "3" and deployed:
container_status()
elif c == "4" and deployed:
remove_menu()
elif c.lower() == "q":
break
def create_config(): def create_config():
print("\n─── Create Node Config ───") print("\n─── Create Node Config ───")
@ -175,16 +195,28 @@ def create_config():
print(f"{name} added to fw.conf") print(f"{name} added to fw.conf")
def add_node(): def add_node():
create_config() print("\n─── Add New Node ───")
name = input("Node name: ").strip()
if not name: return
token = input("Wallarm token: ").strip()
if not token: print("Token required."); return
cloud = input("Cloud region [EU]: ").strip() or "EU"
port = input("Port [8081]: ").strip() or "8081"
upstream_ip = input("Upstream IP [127.0.0.1]: ").strip() or "127.0.0.1"
upstream_port = input("Upstream port [80]: ").strip() or "80"
mode = input("Mode [monitoring]: ").strip() or "monitoring"
# Save to fw.conf
cfg = load_config() cfg = load_config()
if cfg: cfg[name] = {"token": token, "cloud": cloud, "port": port,
# Deploy just the newly added node "upstream_ip": upstream_ip, "upstream_port": upstream_port,
for name in list(cfg.keys()): "labels": f"group={name}", "mode": mode}
if not any(n["name"] == name for n in load_state().get("nodes", [])): os.makedirs(APP, exist_ok=True)
deploy_container(name, cfg[name]["token"], cfg[name].get("cloud","EU"), with open(CONF, "w") as f: json.dump(cfg, f, indent=2)
str(cfg[name].get("port","8081")), cfg[name].get("upstream_ip",""),
str(cfg[name].get("upstream_port","80")), "", # Deploy immediately
cfg[name].get("mode","monitoring")) print(f"\nDeploying {name}...")
deploy_container(name, token, cloud, port, upstream_ip, upstream_port, f"group={name}", mode)
def remove_menu(): def remove_menu():
s = load_state().get("nodes", []) s = load_state().get("nodes", [])