Files
server-26/drb-server-discord-bot/app/internal/c2_client.py
T
Logan 2f0597c81b Initial commit — DRB server stack
Includes c2-core (FastAPI/MQTT/Firestore), discord-bot (slash commands),
frontend (Next.js admin UI), and mosquitto config.
2026-04-05 19:01:39 -04:00

57 lines
1.8 KiB
Python

import httpx
from typing import Optional
from app.config import settings
from app.internal.logger import logger
class C2Client:
def __init__(self):
self.base = settings.c2_url.rstrip("/")
async def get_nodes(self) -> list:
try:
async with httpx.AsyncClient(timeout=10) as client:
r = await client.get(f"{self.base}/nodes")
r.raise_for_status()
return r.json()
except Exception as e:
logger.error(f"C2 get_nodes failed: {e}")
return []
async def get_systems(self) -> list:
try:
async with httpx.AsyncClient(timeout=10) as client:
r = await client.get(f"{self.base}/systems")
r.raise_for_status()
return r.json()
except Exception as e:
logger.error(f"C2 get_systems failed: {e}")
return []
async def send_command(self, node_id: str, payload: dict) -> bool:
try:
async with httpx.AsyncClient(timeout=10) as client:
r = await client.post(
f"{self.base}/nodes/{node_id}/command",
json=payload,
)
r.raise_for_status()
return True
except Exception as e:
logger.error(f"C2 send_command failed: {e}")
return False
async def find_node_for_system(self, system_id: str) -> Optional[dict]:
"""Return the first online node assigned to the given system."""
nodes = await self.get_nodes()
for node in nodes:
if (
node.get("assigned_system_id") == system_id
and node.get("status") in ("online", "recording")
):
return node
return None
c2 = C2Client()