import os from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.dependencies import get_current_user, get_db from app.models.ssh_key import SSHKey from app.models.user import User from app.schemas.ssh_key import SSHKeyCreate, SSHKeyRead, SSHKeyUpdate router = APIRouter(prefix="/api/v1/ssh-keys", tags=["ssh-keys"]) @router.get("", response_model=list[SSHKeyRead]) async def list_ssh_keys( db: AsyncSession = Depends(get_db), _: User = Depends(get_current_user), ): result = await db.execute(select(SSHKey).order_by(SSHKey.name)) return result.scalars().all() @router.post("", response_model=SSHKeyRead, status_code=status.HTTP_201_CREATED) async def create_ssh_key( body: SSHKeyCreate, db: AsyncSession = Depends(get_db), _: User = Depends(get_current_user), ): if not os.path.isfile(body.path): raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=f"Key file not found on server: {body.path}", ) key = SSHKey(**body.model_dump()) db.add(key) await db.flush() await db.refresh(key) return key @router.patch("/{key_id}", response_model=SSHKeyRead) async def update_ssh_key( key_id: int, body: SSHKeyUpdate, db: AsyncSession = Depends(get_db), _: User = Depends(get_current_user), ): result = await db.execute(select(SSHKey).where(SSHKey.id == key_id)) key = result.scalar_one_or_none() if key is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="SSH key not found") data = body.model_dump(exclude_none=True) if "path" in data and not os.path.isfile(data["path"]): raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=f"Key file not found on server: {data['path']}", ) for field, value in data.items(): setattr(key, field, value) await db.flush() await db.refresh(key) return key @router.delete("/{key_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_ssh_key( key_id: int, db: AsyncSession = Depends(get_db), _: User = Depends(get_current_user), ): result = await db.execute(select(SSHKey).where(SSHKey.id == key_id)) key = result.scalar_one_or_none() if key is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="SSH key not found") await db.delete(key)