from __future__ import annotations import json from typing import Dict, Optional from fastapi import APIRouter, HTTPException, Query from pydantic import BaseModel def _normalize_filters(filters: str) -> str: """Zet key=value formaat om naar {"key":["value"]} JSON dat Libpod verwacht. Als de waarde al met '{' begint, wordt hij ongewijzigd doorgegeven.""" if filters.startswith("{"): return filters # key=value → {"key": ["value"]} if "=" in filters: key, _, value = filters.partition("=") return json.dumps({key.strip(): [value.strip()]}) # Alleen een key zonder waarde → {"key": ["true"]} return json.dumps({filters.strip(): ["true"]}) class VolumeCreateRequest(BaseModel): name: str driver: str = "local" driverOpts: Optional[Dict[str, str]] = None labels: Optional[Dict[str, str]] = None def _raise_on_error(resp): if 200 <= resp.status_code < 300: return raise HTTPException(status_code=resp.status_code, detail=resp.text) def init_volumes_router(session, podman_api_base: str) -> APIRouter: router = APIRouter(prefix="/volumes", tags=["volumes"]) @router.get("") def list_volumes(filters: Optional[str] = Query(None)): url = f"{podman_api_base}/libpod/volumes/json" params = {} if filters is not None: params["filters"] = _normalize_filters(filters) resp = session.get(url, params=params) _raise_on_error(resp) return resp.json() @router.post("") def create_volume(req: VolumeCreateRequest): url = f"{podman_api_base}/libpod/volumes/create" body: dict = {"name": req.name, "driver": req.driver} if req.driverOpts: body["driverOpts"] = req.driverOpts if req.labels: body["labels"] = req.labels resp = session.post(url, json=body) _raise_on_error(resp) return resp.json() @router.post("/prune") def prune_volumes(): """⚠️ Destructief: verwijdert alle ongebruikte volumes permanent. Niet terug te draaien.""" url = f"{podman_api_base}/libpod/volumes/prune" resp = session.post(url) _raise_on_error(resp) return resp.json() @router.get("/{name}/exists") def volume_exists(name: str): url = f"{podman_api_base}/libpod/volumes/{name}/exists" resp = session.get(url) if resp.status_code == 204: return {"exists": True} if resp.status_code == 404: return {"exists": False} _raise_on_error(resp) @router.get("/{name}") def get_volume(name: str): url = f"{podman_api_base}/libpod/volumes/{name}/json" resp = session.get(url) _raise_on_error(resp) return resp.json() @router.delete("/{name}") def remove_volume(name: str, force: bool = Query(False)): """⚠️ Destructief: verwijdert een volume permanent. Niet terug te draaien als het volume data bevat.""" url = f"{podman_api_base}/libpod/volumes/{name}" params = {"force": str(force).lower()} resp = session.delete(url, params=params) if resp.status_code == 204: return {"ok": True} _raise_on_error(resp) return router