Export CSV serveurs avec filtres (domaine, env, tier, état, recherche)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalid MOUTAOUAKIL 2026-04-07 01:49:23 +02:00
parent 769e199735
commit c550597a86
2 changed files with 32 additions and 2 deletions

View File

@ -1,6 +1,6 @@
"""Router serveurs — CRUD + detail + edit via HTMX""" """Router serveurs — CRUD + detail + edit via HTMX"""
from fastapi import APIRouter, Request, Depends, Query, Form from fastapi import APIRouter, Request, Depends, Query, Form
from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.responses import HTMLResponse, RedirectResponse, StreamingResponse
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from ..dependencies import get_db, get_current_user from ..dependencies import get_db, get_current_user
from ..services.server_service import ( from ..services.server_service import (
@ -36,6 +36,36 @@ async def servers_list(request: Request, db=Depends(get_db),
}) })
@router.get("/servers/export-csv")
async def servers_export_csv(request: Request, db=Depends(get_db),
domain: str = Query(None), env: str = Query(None),
tier: str = Query(None), etat: str = Query(None),
search: str = Query(None)):
user = get_current_user(request)
if not user:
return RedirectResponse(url="/login")
import io, csv
filters = {"domain": domain, "env": env, "tier": tier, "etat": etat, "search": search}
servers, total = list_servers(db, filters, page=1, per_page=99999, sort="hostname", sort_dir="asc")
output = io.StringIO()
w = csv.writer(output, delimiter=";")
w.writerow(["Hostname", "FQDN", "OS", "Version OS", "Domaine", "Environnement",
"Zone", "Tier", "Etat", "Owner patching", "Application"])
for s in servers:
w.writerow([
s.hostname, getattr(s, "fqdn", "") or "", s.os_family or "",
getattr(s, "os_version", "") or "",
getattr(s, "domaine", "") or "", getattr(s, "environnement", "") or "",
getattr(s, "zone_name", "") or "", s.tier or "", s.etat or "",
s.patch_os_owner or "", getattr(s, "application_name", "") or "",
])
output.seek(0)
return StreamingResponse(
iter(["\ufeff" + output.getvalue()]),
media_type="text/csv",
headers={"Content-Disposition": "attachment; filename=serveurs.csv"})
@router.get("/servers/{server_id}/detail", response_class=HTMLResponse) @router.get("/servers/{server_id}/detail", response_class=HTMLResponse)
async def server_detail(request: Request, server_id: int, db=Depends(get_db)): async def server_detail(request: Request, server_id: int, db=Depends(get_db)):
user = get_current_user(request) user = get_current_user(request)

View File

@ -17,7 +17,7 @@
<div class="flex justify-between items-center mb-4"> <div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold text-cyber-accent">Serveurs <span class="text-sm text-gray-500">({{ total }})</span></h2> <h2 class="text-xl font-bold text-cyber-accent">Serveurs <span class="text-sm text-gray-500">({{ total }})</span></h2>
<div class="flex gap-2"> <div class="flex gap-2">
<button class="btn-sm bg-cyber-green text-black" onclick="alert('Export bientot')">Export CSV</button> <a href="/servers/export-csv?search={{ filters.search or '' }}&domain={{ filters.domain or '' }}&env={{ filters.env or '' }}&tier={{ filters.tier or '' }}&etat={{ filters.etat or '' }}" class="btn-sm bg-cyber-green text-black">Export CSV</a>
</div> </div>
</div> </div>