""" Tools Controller Provides utility tool endpoints including: - DNS lookups - System stats """ from fastapi import APIRouter, HTTPException, status from src.shared.base import BaseController from src.shared.logging import get_logger from src.domains.tools.dns.schemas import DNSLookupRequest, DNSLookupResponse from src.domains.tools.dns.service import DNSService from src.domains.tools.dns.exceptions import DNSQueryError from src.domains.tools.system.schemas import SystemStatsResponse from src.domains.tools.system.service import SystemStatsService logger = get_logger(__name__) class ToolsController(BaseController): """ Controller for utility tools Provides endpoints for: - DNS lookups - System stats """ def __init__(self): super().__init__(prefix="/tools", tags=["Tools"]) self.dns_service = DNSService() self.system_stats_service = SystemStatsService() def create_router(self) -> APIRouter: """Create and configure the router""" router = APIRouter(prefix=self.prefix, tags=self.tags) @router.post( "/dns/lookup", response_model=DNSLookupResponse, status_code=status.HTTP_200_OK, summary="Perform DNS lookup", description=""" Perform DNS lookups for various record types. Uses dnspython for reliable DNS queries with support for multiple record types and custom nameservers. Perfect for troubleshooting DNS issues and checking domain configurations. **Supported Record Types:** - A: IPv4 address records - AAAA: IPv6 address records - MX: Mail exchange records - TXT: Text records (SPF, DKIM, etc.) - CNAME: Canonical name records - NS: Nameserver records - SOA: Start of authority records - PTR: Pointer records (reverse DNS) - CAA: Certification authority authorization - SRV: Service records **Features:** - Custom nameserver support (e.g., 8.8.8.8, 1.1.1.1) - Query time measurement - Detailed error messages **Rate Limiting:** None (internal network use only) """ ) async def dns_lookup(request: DNSLookupRequest) -> DNSLookupResponse: """ Perform DNS lookup for a domain Args: request: DNS lookup request with domain, record type, and optional nameserver Returns: DNS lookup results with records and metadata Raises: HTTPException: 400 for invalid queries, 500 for processing errors """ try: logger.info(f"Received DNS lookup request for: {request.domain} ({request.record_type})") result = await self.dns_service.lookup(request) return result except DNSQueryError as e: logger.warning(f"DNS query error: {str(e)}") raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"DNS query failed: {str(e)}" ) except Exception as e: logger.error(f"Unexpected error during DNS lookup: {str(e)}", exc_info=True) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="An unexpected error occurred during DNS lookup" ) @router.get( "/system/stats", response_model=SystemStatsResponse, status_code=status.HTTP_200_OK, summary="Get host system statistics", description=""" Get real-time host system resource statistics. Returns CPU, memory, disk, network, and GPU/VRAM usage for the host machine (not Docker container metrics). **Metrics Returned:** - **CPU:** Usage percentage, core count, load averages - **Memory:** Usage percentage, total/used/available bytes - **Disk:** Usage percentage, total/used/free bytes (root partition) - **Network:** Total bytes sent/received - **GPU:** VRAM usage (if NVIDIA GPU available via nvidia-smi) **Use Cases:** - Dashboard system monitoring widgets - Health checks and alerting - Capacity planning """ ) async def get_system_stats() -> SystemStatsResponse: """ Get current host system statistics Returns: System statistics including CPU, memory, disk, network, and GPU Raises: HTTPException: 500 for processing errors """ try: logger.info("Fetching system stats") result = await self.system_stats_service.get_stats() return result except Exception as e: logger.error(f"Failed to get system stats: {str(e)}", exc_info=True) raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to collect system stats: {str(e)}" ) return router # Create controller instance tools_controller = ToolsController()