Files
vps-manager/app/routers/ssl.py
T

149 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""SSL 监控路由:子域名管理与站点证书监控
- /api/subdomains:域名资产下的子域名 CRUD
- /api/site-certshttps 站点证书的探测与监控
写操作(POST/PUT/DELETE)受 API Key 保护。
"""
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlmodel import Session
from app.core.security import require_api_key
from app.database import get_session
from app.schemas.ssl import SiteCertCreate, SubdomainCreate, SubdomainUpdate
from app.services import ssl_service
router = APIRouter(prefix="/api", tags=["ssl"])
def _guard(exc: ValueError) -> HTTPException:
"""service 抛出的 ValueError 统一转 404"""
return HTTPException(status_code=404, detail=str(exc))
# ---------------- 子域名 ----------------
@router.get("/subdomains", summary="子域名列表(可按域名资产筛选)")
def list_subdomains(
asset_id: Optional[int] = Query(default=None, description="按域名资产 ID 筛选"),
session: Session = Depends(get_session),
) -> list:
return ssl_service.list_subdomains(session, asset_id)
@router.post(
"/subdomains",
status_code=201,
summary="创建子域名",
dependencies=[Depends(require_api_key)],
)
def create_subdomain(data: SubdomainCreate, session: Session = Depends(get_session)) -> dict:
sub = ssl_service.create_subdomain(session, data.model_dump())
return {
"id": sub.id,
"asset_id": sub.asset_id,
"host": sub.host,
"record_type": sub.record_type,
"record_value": sub.record_value,
"is_active": sub.is_active,
"note": sub.note,
}
@router.put(
"/subdomains/{sub_id}",
summary="更新子域名",
dependencies=[Depends(require_api_key)],
)
def update_subdomain(sub_id: int, data: SubdomainUpdate, session: Session = Depends(get_session)) -> dict:
try:
sub = ssl_service.update_subdomain(session, sub_id, data.model_dump(exclude_unset=True))
except ValueError as e:
raise _guard(e) from e
return {
"id": sub.id,
"asset_id": sub.asset_id,
"host": sub.host,
"record_type": sub.record_type,
"record_value": sub.record_value,
"is_active": sub.is_active,
"note": sub.note,
}
@router.delete(
"/subdomains/{sub_id}",
status_code=204,
summary="删除子域名",
dependencies=[Depends(require_api_key)],
)
def delete_subdomain(sub_id: int, session: Session = Depends(get_session)):
try:
ssl_service.delete_subdomain(session, sub_id)
except ValueError as e:
raise _guard(e) from e
# ---------------- 站点证书监控 ----------------
@router.get("/site-certs", summary="站点证书监控列表(可按状态/资产筛选)")
def list_site_certs(
status: Optional[str] = Query(default=None, description="按状态筛选"),
asset_id: Optional[int] = Query(default=None, description="按关联资产筛选"),
session: Session = Depends(get_session),
) -> list:
return ssl_service.list_site_certs(session, status, asset_id)
@router.post(
"/site-certs",
status_code=201,
summary="创建证书探测目标(创建后立即探测一次)",
dependencies=[Depends(require_api_key)],
)
def create_site_cert(data: SiteCertCreate, session: Session = Depends(get_session)) -> dict:
try:
cert = ssl_service.create_site_cert(
session, data.hostname, data.port, data.asset_id
)
except ValueError as e:
raise _guard(e) from e
return ssl_service._to_dict(cert)
@router.post(
"/site-certs/check-all",
summary="全量重新探测所有站点证书",
dependencies=[Depends(require_api_key)],
)
def check_all_site_certs(session: Session = Depends(get_session)) -> dict:
return ssl_service.check_all_site_certs(session)
@router.post(
"/site-certs/{cert_id}/check",
summary="重新探测单条站点证书",
dependencies=[Depends(require_api_key)],
)
def check_one_site_cert(cert_id: int, session: Session = Depends(get_session)) -> dict:
cert = session.get(ssl_service.SiteCert, cert_id)
if not cert:
raise HTTPException(status_code=404, detail=f"证书监控记录不存在(id={cert_id}")
ssl_service.check_one(session, cert)
return ssl_service._to_dict(cert)
@router.delete(
"/site-certs/{cert_id}",
status_code=204,
summary="删除证书探测目标",
dependencies=[Depends(require_api_key)],
)
def delete_site_cert(cert_id: int, session: Session = Depends(get_session)):
try:
ssl_service.delete_site_cert(session, cert_id)
except ValueError as e:
raise _guard(e) from e