133 lines
3.4 KiB
Python
133 lines
3.4 KiB
Python
"""Emergency Control Router"""
|
|
from fastapi import APIRouter, HTTPException
|
|
from pydantic import BaseModel
|
|
from typing import Optional
|
|
from datetime import datetime
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
class SystemStatus(BaseModel):
|
|
system_id: str
|
|
name: str
|
|
status: str # active, suspended, degraded
|
|
last_updated: datetime
|
|
|
|
|
|
class SuspendRequest(BaseModel):
|
|
system_id: str
|
|
reason: str
|
|
duration_minutes: Optional[int] = None # None = indefinite
|
|
|
|
|
|
class Incident(BaseModel):
|
|
id: str
|
|
system_id: str
|
|
action: str # suspend, resume, degrade
|
|
reason: str
|
|
initiated_by: str
|
|
timestamp: datetime
|
|
|
|
|
|
# In-memory state (replace with database in production)
|
|
SYSTEM_STATES = {}
|
|
INCIDENTS = []
|
|
|
|
|
|
@router.get("/status")
|
|
async def get_all_status():
|
|
"""Get status of all registered systems"""
|
|
return {"systems": list(SYSTEM_STATES.values())}
|
|
|
|
|
|
@router.get("/status/{system_id}")
|
|
async def get_system_status(system_id: str):
|
|
"""Get status of a specific system"""
|
|
if system_id not in SYSTEM_STATES:
|
|
return SystemStatus(
|
|
system_id=system_id,
|
|
name="Unknown",
|
|
status="unknown",
|
|
last_updated=datetime.now()
|
|
)
|
|
return SYSTEM_STATES[system_id]
|
|
|
|
|
|
@router.post("/suspend")
|
|
async def suspend_system(request: SuspendRequest):
|
|
"""Immediately suspend a system"""
|
|
SYSTEM_STATES[request.system_id] = SystemStatus(
|
|
system_id=request.system_id,
|
|
name=request.system_id,
|
|
status="suspended",
|
|
last_updated=datetime.now()
|
|
)
|
|
|
|
incident = Incident(
|
|
id=f"inc_{len(INCIDENTS)+1}",
|
|
system_id=request.system_id,
|
|
action="suspend",
|
|
reason=request.reason,
|
|
initiated_by="api",
|
|
timestamp=datetime.now()
|
|
)
|
|
INCIDENTS.append(incident)
|
|
|
|
return {
|
|
"message": f"System {request.system_id} suspended",
|
|
"incident_id": incident.id
|
|
}
|
|
|
|
|
|
@router.post("/resume/{system_id}")
|
|
async def resume_system(system_id: str, reason: str = "Manual resume"):
|
|
"""Resume a suspended system"""
|
|
SYSTEM_STATES[system_id] = SystemStatus(
|
|
system_id=system_id,
|
|
name=system_id,
|
|
status="active",
|
|
last_updated=datetime.now()
|
|
)
|
|
|
|
incident = Incident(
|
|
id=f"inc_{len(INCIDENTS)+1}",
|
|
system_id=system_id,
|
|
action="resume",
|
|
reason=reason,
|
|
initiated_by="api",
|
|
timestamp=datetime.now()
|
|
)
|
|
INCIDENTS.append(incident)
|
|
|
|
return {"message": f"System {system_id} resumed", "incident_id": incident.id}
|
|
|
|
|
|
@router.post("/degrade/{system_id}")
|
|
async def degrade_system(system_id: str, reason: str = "Graceful degradation"):
|
|
"""Put system into degraded mode"""
|
|
SYSTEM_STATES[system_id] = SystemStatus(
|
|
system_id=system_id,
|
|
name=system_id,
|
|
status="degraded",
|
|
last_updated=datetime.now()
|
|
)
|
|
|
|
return {"message": f"System {system_id} in degraded mode"}
|
|
|
|
|
|
@router.get("/incidents")
|
|
async def list_incidents(limit: int = 100):
|
|
"""List recent incidents"""
|
|
return {"incidents": INCIDENTS[-limit:]}
|
|
|
|
|
|
@router.post("/register")
|
|
async def register_system(system_id: str, name: str):
|
|
"""Register a new system for monitoring"""
|
|
SYSTEM_STATES[system_id] = SystemStatus(
|
|
system_id=system_id,
|
|
name=name,
|
|
status="active",
|
|
last_updated=datetime.now()
|
|
)
|
|
return {"message": f"System {system_id} registered"}
|