feat: register connected routing nodes without execution
This commit is contained in:
parent
46b63e343c
commit
8be10cc3da
@ -135,6 +135,33 @@ class Handler(BaseHTTPRequestHandler):
|
||||
))
|
||||
audit(db, "intake_created", {"intake_id": intake_id, "domain_id": payload["domain_id"]})
|
||||
return self.respond(201, {"ok": True, "intake_id": intake_id, "state": "PENDING_REVIEW", "next": "sovereign approval, human email confirmation, then node connector enrollment"})
|
||||
if self.path == "/v1/nodes/bootstrap":
|
||||
"""Register a manually verified routing node without enabling execution.
|
||||
|
||||
This exists for the controlled migration of an already verified
|
||||
domain entry. It deliberately cannot make a node ACTIVE: the
|
||||
GLSV connector, server-local key enrollment, and human email
|
||||
confirmation remain required before any operation can proceed.
|
||||
"""
|
||||
required = ("id", "domain_id", "display_name", "server_ip")
|
||||
if any(not isinstance(payload.get(field), str) or not payload[field].strip() for field in required):
|
||||
return self.respond(400, {"ok": False, "error": "id, domain_id, display_name, and server_ip are required"})
|
||||
if payload["domain_id"] not in DOMAINS:
|
||||
return self.respond(400, {"ok": False, "error": "domain_id is not registered"})
|
||||
try:
|
||||
ip_address(payload["server_ip"])
|
||||
except ValueError:
|
||||
return self.respond(400, {"ok": False, "error": "server_ip must be a valid IP address"})
|
||||
node_id = payload["id"].strip()
|
||||
if db.execute("SELECT 1 FROM nodes WHERE id=?", (node_id,)).fetchone():
|
||||
return self.respond(409, {"ok": False, "error": "node id is already registered"})
|
||||
db.execute("INSERT INTO nodes VALUES (?, ?, NULL, 'CONNECTED_PENDING_CONNECTOR', ?, ?, ?, NULL, ?, ?)", (
|
||||
node_id, payload["domain_id"], payload["display_name"].strip(), payload["server_ip"],
|
||||
json.dumps(["health_check"]), now(), now(),
|
||||
))
|
||||
db.execute("UPDATE domains SET state='ENTRY_NODE_CONNECTED' WHERE id=?", (payload["domain_id"],))
|
||||
audit(db, "node_bootstrap_connected", {"node_id": node_id, "domain_id": payload["domain_id"], "mode": "manual_verified_routing_only"})
|
||||
return self.respond(201, {"ok": True, "node_id": node_id, "state": "CONNECTED_PENDING_CONNECTOR", "execution": "disabled until GLSV connector enrollment and human authorization"})
|
||||
if self.path == "/v1/preflight":
|
||||
action, node_id = payload.get("action"), payload.get("target_node_id")
|
||||
if action not in FIXED_ACTIONS or not node_id:
|
||||
|
||||
@ -22,6 +22,10 @@ with tempfile.TemporaryDirectory() as temp:
|
||||
else: raise AssertionError("server did not start")
|
||||
request = urllib.request.Request("http://127.0.0.1:48031/v1/intakes", data=json.dumps({"human_name":"Test","email":"test@example.invalid","server_ip":"203.0.113.8","domain_id":"DOMAIN-FIFTH"}).encode(), method="POST", headers={"X-Lighthouse-Admin-Token":"test-token"})
|
||||
assert json.load(urllib.request.urlopen(request))["state"] == "PENDING_REVIEW"
|
||||
bootstrap = urllib.request.Request("http://127.0.0.1:48031/v1/nodes/bootstrap", data=json.dumps({"id":"NODE-TEST-001","domain_id":"DOMAIN-FIFTH","display_name":"Test entry","server_ip":"203.0.113.8"}).encode(), method="POST", headers={"X-Lighthouse-Admin-Token":"test-token"})
|
||||
assert json.load(urllib.request.urlopen(bootstrap))["state"] == "CONNECTED_PENDING_CONNECTOR"
|
||||
preflight = urllib.request.Request("http://127.0.0.1:48031/v1/preflight", data=json.dumps({"action":"health_check","target_node_id":"NODE-TEST-001"}).encode(), method="POST", headers={"X-Lighthouse-Admin-Token":"test-token"})
|
||||
assert json.load(urllib.request.urlopen(preflight))["decision"] == "REJECT"
|
||||
bad = urllib.request.Request("http://127.0.0.1:48031/v1/intakes", data=b'{"cmd":"rm -rf /"}', method="POST", headers={"X-Lighthouse-Admin-Token":"test-token"})
|
||||
try: urllib.request.urlopen(bad)
|
||||
except urllib.error.HTTPError as error: assert error.code == 400
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user