feat: add ops center and node onboarding flow
This commit is contained in:
175
domain-api/app/api/routes/ops_release.py
Normal file
175
domain-api/app/api/routes/ops_release.py
Normal file
@@ -0,0 +1,175 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter, Request
|
||||
from fastapi.responses import FileResponse
|
||||
|
||||
from app.schemas.common import ApiResponse
|
||||
from app.services.ops_release_service import (
|
||||
advance_release_rollout,
|
||||
activate_release,
|
||||
create_release,
|
||||
create_release_and_smart_rollout_from_latest_package,
|
||||
create_release_from_latest_package,
|
||||
create_release_rollout,
|
||||
create_smart_release_rollout,
|
||||
get_latest_release_package_metadata,
|
||||
get_release_launchpad,
|
||||
get_latest_release,
|
||||
get_release_package_archive_path,
|
||||
get_release_package_sha256_path,
|
||||
get_release,
|
||||
get_release_rollout,
|
||||
list_release_rollout_jobs,
|
||||
list_release_rollouts,
|
||||
list_releases,
|
||||
preview_release_from_latest_package,
|
||||
preview_smart_release_rollout,
|
||||
preview_smart_release_rollout_from_latest_package,
|
||||
)
|
||||
|
||||
router = APIRouter(tags=["ops-release"])
|
||||
|
||||
|
||||
@router.get("/ops/releases", response_model=ApiResponse)
|
||||
def ops_releases(limit: int = 20, channel: str | None = None) -> ApiResponse:
|
||||
return ApiResponse(data={"releases": list_releases(limit=limit, channel=channel)})
|
||||
|
||||
|
||||
@router.get("/ops/releases/latest", response_model=ApiResponse)
|
||||
def ops_releases_latest(channel: str = "stable") -> ApiResponse:
|
||||
return ApiResponse(data=get_latest_release(channel=channel))
|
||||
|
||||
|
||||
@router.get("/ops/releases/package-metadata/latest", response_model=ApiResponse)
|
||||
def ops_releases_package_metadata_latest() -> ApiResponse:
|
||||
return ApiResponse(data=get_latest_release_package_metadata())
|
||||
|
||||
|
||||
@router.get("/ops/releases/launchpad", response_model=ApiResponse)
|
||||
def ops_releases_launchpad(request: Request, channel: str = "stable") -> ApiResponse:
|
||||
derived_base_url = str(request.base_url).rstrip("/")
|
||||
return ApiResponse(data=get_release_launchpad(control_plane_base_url=derived_base_url, channel=channel))
|
||||
|
||||
|
||||
@router.get("/ops/releases/packages/{package_name}/download")
|
||||
def ops_release_package_download(package_name: str):
|
||||
try:
|
||||
archive_path = get_release_package_archive_path(package_name)
|
||||
except ValueError:
|
||||
return ApiResponse(code=1, message="发布包名称不合法", data={})
|
||||
if not archive_path:
|
||||
return ApiResponse(code=1, message="发布包不存在", data={})
|
||||
media_type = "application/octet-stream"
|
||||
archive_name = archive_path.name.lower()
|
||||
if archive_name.endswith(".tar.gz"):
|
||||
media_type = "application/gzip"
|
||||
elif archive_name.endswith(".zip"):
|
||||
media_type = "application/zip"
|
||||
return FileResponse(path=archive_path, filename=archive_path.name, media_type=media_type)
|
||||
|
||||
|
||||
@router.get("/ops/releases/packages/{package_name}/sha256")
|
||||
def ops_release_package_sha256(package_name: str):
|
||||
try:
|
||||
sha256_path = get_release_package_sha256_path(package_name)
|
||||
except ValueError:
|
||||
return ApiResponse(code=1, message="发布包名称不合法", data={})
|
||||
if not sha256_path:
|
||||
return ApiResponse(code=1, message="发布包校验文件不存在", data={})
|
||||
return FileResponse(path=sha256_path, filename=sha256_path.name, media_type="text/plain; charset=utf-8")
|
||||
|
||||
|
||||
@router.get("/ops/releases/{release_id}", response_model=ApiResponse)
|
||||
def ops_releases_detail(release_id: int) -> ApiResponse:
|
||||
data = get_release(release_id)
|
||||
if not data:
|
||||
return ApiResponse(code=1, message="Release 不存在", data={})
|
||||
return ApiResponse(data=data)
|
||||
|
||||
|
||||
@router.post("/ops/releases", response_model=ApiResponse)
|
||||
def ops_releases_create(payload: dict) -> ApiResponse:
|
||||
ok, message, data = create_release(payload)
|
||||
return ApiResponse(code=0 if ok else 1, message=message, data=data)
|
||||
|
||||
|
||||
@router.post("/ops/releases/from-package/latest", response_model=ApiResponse)
|
||||
def ops_releases_create_from_latest_package(request: Request, payload: dict | None = None) -> ApiResponse:
|
||||
derived_base_url = str(request.base_url).rstrip("/")
|
||||
ok, message, data = create_release_from_latest_package(payload or {}, control_plane_base_url=derived_base_url)
|
||||
return ApiResponse(code=0 if ok else 1, message=message, data=data)
|
||||
|
||||
|
||||
@router.post("/ops/releases/from-package/latest/preview", response_model=ApiResponse)
|
||||
def ops_releases_preview_from_latest_package(request: Request, payload: dict | None = None) -> ApiResponse:
|
||||
derived_base_url = str(request.base_url).rstrip("/")
|
||||
ok, message, data = preview_release_from_latest_package(payload or {}, control_plane_base_url=derived_base_url)
|
||||
return ApiResponse(code=0 if ok else 1, message=message, data=data)
|
||||
|
||||
|
||||
@router.post("/ops/releases/from-package/latest/smart-rollout", response_model=ApiResponse)
|
||||
def ops_releases_create_from_latest_package_and_smart_rollout(request: Request, payload: dict | None = None) -> ApiResponse:
|
||||
derived_base_url = str(request.base_url).rstrip("/")
|
||||
ok, message, data = create_release_and_smart_rollout_from_latest_package(
|
||||
payload or {},
|
||||
control_plane_base_url=derived_base_url,
|
||||
)
|
||||
return ApiResponse(code=0 if ok else 1, message=message, data=data)
|
||||
|
||||
|
||||
@router.post("/ops/releases/from-package/latest/smart-rollout-preview", response_model=ApiResponse)
|
||||
def ops_releases_preview_from_latest_package_and_smart_rollout(request: Request, payload: dict | None = None) -> ApiResponse:
|
||||
derived_base_url = str(request.base_url).rstrip("/")
|
||||
ok, message, data = preview_smart_release_rollout_from_latest_package(
|
||||
payload or {},
|
||||
control_plane_base_url=derived_base_url,
|
||||
)
|
||||
return ApiResponse(code=0 if ok else 1, message=message, data=data)
|
||||
|
||||
|
||||
@router.post("/ops/releases/{release_id}/activate", response_model=ApiResponse)
|
||||
def ops_releases_activate(release_id: int) -> ApiResponse:
|
||||
ok, message, data = activate_release(release_id)
|
||||
return ApiResponse(code=0 if ok else 1, message=message, data=data)
|
||||
|
||||
|
||||
@router.post("/ops/releases/{release_id}/smart-rollout-preview", response_model=ApiResponse)
|
||||
def ops_releases_smart_rollout_preview(release_id: int, payload: dict | None = None) -> ApiResponse:
|
||||
ok, message, data = preview_smart_release_rollout(release_id, payload or {})
|
||||
return ApiResponse(code=0 if ok else 1, message=message, data=data)
|
||||
|
||||
|
||||
@router.post("/ops/releases/{release_id}/smart-rollout", response_model=ApiResponse)
|
||||
def ops_releases_smart_rollout(release_id: int, payload: dict | None = None) -> ApiResponse:
|
||||
ok, message, data = create_smart_release_rollout(release_id, payload or {})
|
||||
return ApiResponse(code=0 if ok else 1, message=message, data=data)
|
||||
|
||||
|
||||
@router.get("/ops/releases/{release_id}/rollouts", response_model=ApiResponse)
|
||||
def ops_release_rollouts(release_id: int, limit: int = 20) -> ApiResponse:
|
||||
return ApiResponse(data={"rollouts": list_release_rollouts(release_id=release_id, limit=limit)})
|
||||
|
||||
|
||||
@router.get("/ops/rollouts/{rollout_id}", response_model=ApiResponse)
|
||||
def ops_rollout_detail(rollout_id: int) -> ApiResponse:
|
||||
data = get_release_rollout(rollout_id)
|
||||
if not data:
|
||||
return ApiResponse(code=1, message="Rollout 不存在", data={})
|
||||
return ApiResponse(data=data)
|
||||
|
||||
|
||||
@router.get("/ops/rollouts/{rollout_id}/jobs", response_model=ApiResponse)
|
||||
def ops_rollout_jobs(rollout_id: int, limit: int = 200) -> ApiResponse:
|
||||
return ApiResponse(data={"jobs": list_release_rollout_jobs(rollout_id, limit=limit)})
|
||||
|
||||
|
||||
@router.post("/ops/rollouts/{rollout_id}/advance", response_model=ApiResponse)
|
||||
def ops_rollout_advance(rollout_id: int, payload: dict | None = None) -> ApiResponse:
|
||||
ok, message, data = advance_release_rollout(rollout_id, payload or {})
|
||||
return ApiResponse(code=0 if ok else 1, message=message, data=data)
|
||||
|
||||
|
||||
@router.post("/ops/releases/{release_id}/rollouts", response_model=ApiResponse)
|
||||
def ops_release_rollouts_create(release_id: int, payload: dict) -> ApiResponse:
|
||||
ok, message, data = create_release_rollout(release_id, payload)
|
||||
return ApiResponse(code=0 if ok else 1, message=message, data=data)
|
||||
Reference in New Issue
Block a user