11 KiB
Requested Core-API Services for Core-AI Infrastructure Tools
This document specifies the API endpoints needed by core-ai infrastructure tools. All requests from core-ai should go through core-api for centralized logging and access control.
Context
The core-ai service is implementing 9 infrastructure tools in 3 logical clusters:
- Container Lifecycle (4 tools) - containers.py
- Service Management (3 tools) - services.py
- Monitoring & Resources (2 tools) - monitoring.py
These tools need corresponding core-api REST endpoints to perform operations via Portainer.
Cluster 1: Container Lifecycle Management
1.1 List Containers
Endpoint: GET /v1/infrastructure/containers
Query Parameters:
status(optional): Filter by status - "all", "running", "stopped", "paused" (default: "running")
Response:
[
{
"Id": "abc123...",
"Names": ["/nginx"],
"State": "running",
"Status": "Up 3 days",
"Image": "nginx:latest",
"Ports": [
{"PrivatePort": 80, "PublicPort": 8080, "Type": "tcp"},
{"PrivatePort": 443, "PublicPort": 8443, "Type": "tcp"}
],
"StartedAt": "2024-12-01T10:00:00Z"
}
]
Implementation Notes:
- Use
PortainerClient.list_containers(all_containers=True)with Docker socket fallback - Filter results based on
statusquery parameter - Return standard Docker API container list format
1.2 Manage Container
Endpoint: POST /v1/infrastructure/containers/{container}/{action}
Path Parameters:
container: Container name or ID (e.g., "nginx", "core-ai")action: One of: "start", "stop", "restart", "pause", "unpause", "remove"
Response (Success):
{
"success": true,
"action": "restart",
"container": "nginx",
"message": "Container restarted successfully"
}
Response (Error):
{
"success": false,
"error": "Container not found",
"message": "Container 'nginx2' not found. Available containers: nginx, core-ai, ollama"
}
Status Codes:
200- Success304- Not Modified (already in target state)404- Container not found409- Conflict (e.g., cannot remove running container)500- Server error
Implementation Notes:
- For "restart": call stop then start
- For actions not yet in PortainerClient (pause, unpause, remove):
- Call Portainer API directly:
/api/endpoints/{endpoint_id}/docker/containers/{container_id}/{action}
- Call Portainer API directly:
- Handle partial name matching (case-insensitive)
- Return helpful error messages suggesting
docker_list_containers()when not found
1.3 Inspect Container
Endpoint: GET /v1/infrastructure/containers/{container}
Path Parameters:
container: Container name or ID
Query Parameters:
details(optional): Level of detail - "summary" (default), "full", "resources"
Response:
{
"Id": "abc123...",
"Name": "/nginx",
"State": {
"Status": "running",
"Running": true,
"StartedAt": "2024-12-01T10:00:00Z",
"FinishedAt": "0001-01-01T00:00:00Z",
"ExitCode": 0
},
"Config": {
"Image": "nginx:latest",
"Env": ["PATH=/usr/local/sbin:...", "NGINX_VERSION=1.25.0"],
"Cmd": ["nginx", "-g", "daemon off;"]
},
"NetworkSettings": {
"Ports": {
"80/tcp": [{"HostIp": "0.0.0.0", "HostPort": "8080"}],
"443/tcp": [{"HostIp": "0.0.0.0", "HostPort": "8443"}]
},
"Networks": {
"bridge": {
"IPAddress": "172.17.0.2",
"Gateway": "172.17.0.1"
}
}
},
"HostConfig": {
"Memory": 536870912,
"NanoCpus": 1000000000,
"RestartPolicy": {"Name": "unless-stopped"}
},
"Mounts": [
{
"Type": "bind",
"Source": "/host/path",
"Destination": "/container/path"
}
]
}
Implementation Notes:
- Use
PortainerClient.inspect_container(container)which auto-detects endpoint and falls back to Docker socket - Return full Docker inspect response
- The core-ai tool will handle formatting based on
detailslevel - Return 404 if container not found
1.4 Container Logs
Endpoint: GET /v1/infrastructure/containers/{container}/logs
Path Parameters:
container: Container name or ID
Query Parameters:
lines(optional): Number of log lines (default: 50, max: 500)since(optional): Time filter - "1h", "30m", or ISO timestamp
Response:
{
"container": "nginx",
"lines_requested": 50,
"since": null,
"logs": "2024-12-04T10:00:00.123Z Starting nginx...\n2024-12-04T10:00:01.456Z Ready to accept connections\n..."
}
Implementation Notes:
- Access Docker API directly:
GET /v1.41/containers/{container}/logs- Use Docker socket transport (httpx with uds)
- Parameters:
stdout=true,stderr=true,tail={lines},timestamps=true - If
sinceprovided: addsince={unix_timestamp}parameter
- Strip Docker stream headers (8-byte binary prefix per line)
- Return plain text logs with timestamps
- Return 404 if container not found
Cluster 2: Service Management
2.1 List Services
Endpoint: GET /v1/infrastructure/services (already exists, may need enhancement)
Query Parameters:
stack(optional): Filter by stack name
Response:
[
{
"name": "portainer",
"stack_id": 1,
"status": "active",
"containers_running": 3,
"containers_total": 3,
"ports": [9000, 8000],
"domains": ["portainer.example.com"]
}
]
Implementation Notes:
- Enhance existing
/infrastructure/servicesendpoint if needed - Ensure it returns stack/service information from Portainer
- Include container counts (running/total)
2.2 Manage Service
Endpoint: POST /v1/infrastructure/services/{service}/{action}
Path Parameters:
service: Service/stack nameaction: One of: "start", "stop", "restart", "scale"
Request Body (for scale action):
{
"replicas": 3
}
Response:
{
"success": true,
"action": "restart",
"service": "web",
"message": "Service restarted successfully"
}
Implementation Notes:
- For "start"/"stop": Use Portainer stack start/stop API
- For "restart": Stop then start the stack
- For "scale": Update stack with new replica count
- This may require updating stack compose file
2.3 Service Status
Endpoint: GET /v1/infrastructure/services/{service}/status
Path Parameters:
service: Service/stack name
Response:
{
"name": "web",
"status": "active",
"stack_id": 5,
"containers": [
{
"name": "web_app_1",
"status": "running",
"health": "healthy",
"uptime": "2 days"
}
],
"replica_status": "3/3 running",
"resources": {
"memory_total": "1.2 GB",
"cpu_usage": "15%"
},
"recent_events": [
{"time": "2024-12-04T09:00:00Z", "action": "container_start", "container": "web_app_3"}
]
}
Implementation Notes:
- Get stack details from Portainer
- Get individual container statuses
- Calculate aggregate resource usage
- May require querying Docker events API for recent events
Cluster 3: Monitoring & Resources
3.1 System Resources
Endpoint: GET /v1/infrastructure/resources/system
Response:
{
"cpu": {
"cores": 8,
"usage_percent": 45.2,
"load_average": [2.5, 2.3, 2.1]
},
"memory": {
"total_bytes": 16777216000,
"used_bytes": 8388608000,
"available_bytes": 8388608000,
"usage_percent": 50.0
},
"disk": {
"total_bytes": 500000000000,
"used_bytes": 250000000000,
"available_bytes": 250000000000,
"usage_percent": 50.0
},
"network": {
"interfaces": {
"eth0": {
"rx_bytes": 1000000000,
"tx_bytes": 500000000
}
}
}
}
Implementation Notes:
- Use Docker system info API:
GET /v1.41/system/df - May also use
GET /v1.41/infofor system-wide stats - Calculate percentages and format nicely
- Include load averages from system stats
3.2 Container Resources
Endpoint: GET /v1/infrastructure/resources/containers
Query Parameters:
container(optional): Specific container name/ID (if omitted, return all)
Response:
[
{
"name": "nginx",
"cpu_percent": 5.2,
"memory_usage_bytes": 45000000,
"memory_limit_bytes": 100000000,
"memory_percent": 45.0,
"network_rx_bytes": 50000000,
"network_tx_bytes": 25000000,
"block_read_bytes": 10000000,
"block_write_bytes": 5000000
}
]
Implementation Notes:
- Use Docker stats API:
GET /v1.41/containers/{id}/stats?stream=false - If
containerparam provided: return single container stats - If omitted: return stats for all running containers
- Calculate percentages where applicable
- Stats API returns real-time metrics (one-time snapshot, not streaming)
Implementation Priority
Phase 1 (Needed immediately for core-ai):
GET /v1/infrastructure/containers- List containersPOST /v1/infrastructure/containers/{container}/{action}- Manage containersGET /v1/infrastructure/containers/{container}- Inspect containerGET /v1/infrastructure/containers/{container}/logs- Container logs
Phase 2 (Needed for full infrastructure tools):
5. POST /v1/infrastructure/services/{service}/{action} - Manage services
6. GET /v1/infrastructure/services/{service}/status - Service status
7. GET /v1/infrastructure/resources/system - System resources
8. GET /v1/infrastructure/resources/containers - Container resources
Security & Access Control
All endpoints should:
- Log all requests (especially write operations)
- Support OIDC authentication when enabled
- Require admin privileges for destructive operations (remove, scale)
- Rate limit to prevent abuse
- Validate input parameters
- Return sanitized errors (no sensitive data in error messages)
Error Handling
Standard error response format:
{
"error": "ContainerNotFound",
"message": "Container 'nginx2' not found",
"details": {
"container": "nginx2",
"available_containers": ["nginx", "core-ai", "ollama"]
}
}
Common error codes:
400- Bad Request (invalid parameters)404- Not Found (container/service doesn't exist)409- Conflict (invalid state transition)500- Internal Server Error (Portainer/Docker API failed)503- Service Unavailable (Portainer/Docker not accessible)
Testing
Each endpoint should have:
- Unit tests (mock Portainer client)
- Integration tests (real Portainer/Docker)
- Error case tests (not found, permission denied, etc.)
- Performance tests (ensure response times < 2s)
Questions / Decisions Needed
- Authentication: Should container management require admin role, or allow read-only for all users?
- Rate Limiting: What limits should be applied to prevent abuse?
- Caching: Should container lists be cached? (TTL: 5s?)
- Async: Should heavy operations (like logs) be async with job IDs?
- Webhooks: Should operations emit events for monitoring?
Notes
- All endpoints follow RESTful conventions
- Use existing PortainerClient methods where available
- Fall back to Docker socket when Portainer doesn't have data
- Log all operations with timestamps, user, and outcome
- Consider adding
/v1/infrastructure/containers/searchfor fuzzy name matching