78 lines
2.3 KiB
Python
78 lines
2.3 KiB
Python
"""
|
|
Room - Runtime environment configuration.
|
|
|
|
A Room defines connection details for a managed environment (hosts, ports, domains, credentials).
|
|
Used by Pulse (Vein + Room + Depot) and Desk (Cabinet + Room + Depots).
|
|
|
|
Room instances are stored in data/rooms.json.
|
|
"""
|
|
|
|
from enum import Enum
|
|
from typing import Optional
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class RoomStatus(str, Enum):
|
|
PENDING = "pending"
|
|
PLANNED = "planned"
|
|
BUILDING = "building"
|
|
DEV = "dev"
|
|
LIVE = "live"
|
|
READY = "ready"
|
|
|
|
|
|
class RoomConfig(BaseModel):
|
|
"""Environment-specific configuration for a room."""
|
|
|
|
# Network
|
|
host: Optional[str] = Field(None, description="Primary host/domain")
|
|
port: Optional[int] = Field(None, description="Primary port")
|
|
|
|
# Paths
|
|
config_path: Optional[str] = Field(None, description="Path to room config folder")
|
|
deploy_path: Optional[str] = Field(None, description="Deployment target path")
|
|
|
|
# Docker
|
|
network_name: Optional[str] = Field(None, description="Docker network name")
|
|
deployment_name: Optional[str] = Field(None, description="Container name prefix")
|
|
|
|
# Database (when room has DB access)
|
|
db_host: Optional[str] = None
|
|
db_port: Optional[int] = Field(None, ge=1, le=65535)
|
|
db_name: Optional[str] = None
|
|
db_user: Optional[str] = None
|
|
# Note: db_password should come from env vars, not stored in config
|
|
|
|
|
|
class Room(BaseModel):
|
|
"""Runtime environment configuration."""
|
|
|
|
name: str = Field(..., description="Unique identifier")
|
|
slug: str = Field(..., description="URL-friendly identifier")
|
|
title: str = Field(..., description="Display title for UI")
|
|
status: RoomStatus = Field(RoomStatus.PENDING, description="Current status")
|
|
|
|
# Optional extended config
|
|
config: Optional[RoomConfig] = Field(None, description="Environment configuration")
|
|
|
|
# Legacy field for backwards compatibility
|
|
config_path: Optional[str] = Field(None, description="Path to room config folder")
|
|
|
|
class Config:
|
|
use_enum_values = True
|
|
|
|
|
|
def load_rooms(data_path: str = "data/rooms.json") -> list[Room]:
|
|
"""Load rooms from data file."""
|
|
import json
|
|
from pathlib import Path
|
|
|
|
path = Path(data_path)
|
|
if not path.exists():
|
|
return []
|
|
|
|
with open(path) as f:
|
|
data = json.load(f)
|
|
|
|
return [Room(**item) for item in data.get("items", [])]
|