# [DEF:backend.src.api.routes.migration:Module] # @SEMANTICS: api, migration, dashboards # @PURPOSE: API endpoints for migration operations. # @LAYER: API # @RELATION: DEPENDS_ON -> backend.src.dependencies # @RELATION: DEPENDS_ON -> backend.src.models.dashboard from fastapi import APIRouter, Depends, HTTPException from typing import List, Dict from backend.src.dependencies import get_config_manager, get_task_manager from backend.src.models.dashboard import DashboardMetadata, DashboardSelection from backend.src.core.superset_client import SupersetClient from superset_tool.models import SupersetConfig router = APIRouter(prefix="/api", tags=["migration"]) # [DEF:get_dashboards:Function] # @PURPOSE: Fetch all dashboards from the specified environment for the grid. # @PRE: Environment ID must be valid. # @POST: Returns a list of dashboard metadata. # @PARAM: env_id (str) - The ID of the environment to fetch from. # @RETURN: List[DashboardMetadata] @router.get("/environments/{env_id}/dashboards", response_model=List[DashboardMetadata]) async def get_dashboards(env_id: str, config_manager=Depends(get_config_manager)): environments = config_manager.get_environments() env = next((e for e in environments if e.id == env_id), None) if not env: raise HTTPException(status_code=404, detail="Environment not found") config = SupersetConfig( env=env.name, base_url=env.url, auth={'provider': 'db', 'username': env.username, 'password': env.password, 'refresh': False}, verify_ssl=True, timeout=30 ) client = SupersetClient(config) dashboards = client.get_dashboards_summary() return dashboards # [/DEF:get_dashboards:Function] # [DEF:execute_migration:Function] # @PURPOSE: Execute the migration of selected dashboards. # @PRE: Selection must be valid and environments must exist. # @POST: Starts the migration task and returns the task ID. # @PARAM: selection (DashboardSelection) - The dashboards to migrate. # @RETURN: Dict - {"task_id": str, "message": str} @router.post("/migration/execute") async def execute_migration(selection: DashboardSelection, config_manager=Depends(get_config_manager), task_manager=Depends(get_task_manager)): # Validate environments exist environments = config_manager.get_environments() env_ids = {e.id for e in environments} if selection.source_env_id not in env_ids or selection.target_env_id not in env_ids: raise HTTPException(status_code=400, detail="Invalid source or target environment") # Create migration task with debug logging from ...core.logger import logger # Include replace_db_config in the task parameters task_params = selection.dict() task_params['replace_db_config'] = selection.replace_db_config logger.info(f"Creating migration task with params: {task_params}") logger.info(f"Available environments: {env_ids}") logger.info(f"Source env: {selection.source_env_id}, Target env: {selection.target_env_id}") try: task = await task_manager.create_task("superset-migration", task_params) logger.info(f"Task created successfully: {task.id}") return {"task_id": task.id, "message": "Migration initiated"} except Exception as e: logger.error(f"Task creation failed: {e}") raise HTTPException(status_code=500, detail=f"Failed to create migration task: {str(e)}") # [/DEF:execute_migration:Function] # [/DEF:backend.src.api.routes.migration:Module]