117 lines
3.9 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""
门桥接 · Gate Bridge · ICE-GL-ZY-AGT-GATE-005
铸渊要连接服务器桥接提供所有Gatekeeper的凭据和通道
不需要铸渊记住12台服务器的IP和密钥桥接知道
用法:
python3 bridge.py list # 列出所有服务器
python3 bridge.py connect BS-SG-001 # 获取连接信息
python3 bridge.py exec BS-SG-001 "ls" # 通过Gatekeeper执行命令
python3 bridge.py scan # 扫描所有服务器在线状态
"""
import json
import os
import sys
import urllib.request
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parent.parent.parent
def load_gatekeepers():
"""加载所有Gatekeeper"""
gk_path = REPO_ROOT / "brain" / "gatekeeper-deployment.json"
if gk_path.exists():
with open(gk_path) as f:
data = json.load(f)
return data
return {"servers": []}
def list_servers():
"""列出所有服务器(不暴露密钥)"""
data = load_gatekeepers()
servers = []
for s in data.get("servers", []):
servers.append({
"code": s["code"],
"name": s.get("name", ""),
"ip": s["ip"],
"port": s["port"],
"domain": s.get("domain", ""),
"spec": s.get("spec", {}),
})
return {
"total": len(servers),
"domains": list(set(s.get("domain", "") for s in data.get("servers", []))),
"servers": servers
}
def get_connection(server_code):
"""获取指定服务器的完整连接信息(含密钥)"""
data = load_gatekeepers()
for s in data.get("servers", []):
if s["code"] == server_code:
return {
"code": s["code"],
"name": s.get("name"),
"gatekeeper_url": f"http://{s['ip']}:{s['port']}/exec",
"auth_header": f"Bearer {s['key']}",
"curl_example": f'curl -X POST http://{s["ip"]}:{s["port"]}/exec -H "Authorization: Bearer {s["key"]}" -H "Content-Type: application/json" -d \'{{"cmd":"echo hello"}}\''
}
return {"error": f"未找到服务器: {server_code}"}
def exec_command(server_code, command):
"""通过Gatekeeper在远程服务器上执行命令"""
conn = get_connection(server_code)
if "error" in conn:
return conn
data = json.dumps({"cmd": command}).encode()
req = urllib.request.Request(
conn["gatekeeper_url"],
data=data,
headers={
"Authorization": conn["auth_header"],
"Content-Type": "application/json"
}
)
try:
with urllib.request.urlopen(req, timeout=15) as resp:
return json.loads(resp.read())
except Exception as e:
return {"error": str(e), "server": server_code}
def scan_all():
"""扫描所有服务器在线状态"""
data = load_gatekeepers()
results = {}
for s in data.get("servers", []):
try:
r = exec_command(s["code"], "echo ONLINE")
results[s["code"]] = {
"online": r.get("ok", False),
"name": s.get("name", ""),
"domain": s.get("domain", ""),
}
except:
results[s["code"]] = {"online": False, "name": s.get("name", "")}
return results
if __name__ == "__main__":
if len(sys.argv) < 2:
print("用法: bridge.py <list|connect|exec|scan> [参数]")
sys.exit(1)
action = sys.argv[1]
if action == "list":
print(json.dumps(list_servers(), ensure_ascii=False, indent=2))
elif action == "connect" and len(sys.argv) > 2:
print(json.dumps(get_connection(sys.argv[2]), ensure_ascii=False, indent=2))
elif action == "exec" and len(sys.argv) > 3:
print(json.dumps(exec_command(sys.argv[2], sys.argv[3]), ensure_ascii=False, indent=2))
elif action == "scan":
print(json.dumps(scan_all(), ensure_ascii=False, indent=2))