More impl for devops
This commit is contained in:
parent
217f33fc17
commit
308f82740d
@ -18,6 +18,11 @@ class SiteSettings(BaseSettings):
|
|||||||
|
|
||||||
BASE_PATH: str = os.path.dirname(os.path.dirname((os.path.abspath(__file__))))
|
BASE_PATH: str = os.path.dirname(os.path.dirname((os.path.abspath(__file__))))
|
||||||
|
|
||||||
|
BASE_GITEA_URL: str = "https://gitea.freeleaps.mathmast.com"
|
||||||
|
|
||||||
|
# TODO: confirm with Zhenyu
|
||||||
|
BASE_RECONSILE_URL: str = "https://reconcile.freeleaps.mathmast.com"
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
env_file = ".devbase-webapi.env"
|
env_file = ".devbase-webapi.env"
|
||||||
env_file_encoding = "utf-8"
|
env_file_encoding = "utf-8"
|
||||||
|
|||||||
6
apps/devops/app/common/daos/code_depot/__init__.py
Normal file
6
apps/devops/app/common/daos/code_depot/__init__.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from app.common.daos.code_depot.code_depot_dao import CodeDepotDao
|
||||||
|
|
||||||
|
code_depot_dao = CodeDepotDao()
|
||||||
|
|
||||||
|
def get_code_depot_dao() -> CodeDepotDao:
|
||||||
|
return code_depot_dao
|
||||||
19
apps/devops/app/common/daos/code_depot/code_depot_dao.py
Normal file
19
apps/devops/app/common/daos/code_depot/code_depot_dao.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
from app.common.models.code_depot.code_depot import CodeDepotDoc
|
||||||
|
|
||||||
|
|
||||||
|
class CodeDepotDao():
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def get_code_depot_by_product_id(self, product_id: str) -> CodeDepotDoc:
|
||||||
|
"""
|
||||||
|
Retrieve code depot by product id
|
||||||
|
"""
|
||||||
|
return await CodeDepotDoc.find_one({"product_id": product_id})
|
||||||
|
|
||||||
|
async def insert_code_depot(self, code_depot: CodeDepotDoc) -> CodeDepotDoc:
|
||||||
|
"""
|
||||||
|
Insert a new code depot into the database
|
||||||
|
"""
|
||||||
|
return await CodeDepotDoc.insert_one(code_depot)
|
||||||
@ -2,5 +2,5 @@ from app.common.daos.deployment.deployment_dao import DeploymentDao
|
|||||||
|
|
||||||
deployment_dao = DeploymentDao()
|
deployment_dao = DeploymentDao()
|
||||||
|
|
||||||
def get_hello_world_dao() -> DeploymentDao:
|
def get_deployment_dao() -> DeploymentDao:
|
||||||
return deployment_dao
|
return deployment_dao
|
||||||
@ -5,9 +5,10 @@ class DeploymentDao():
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def create_deployment(self, deployment_data: Deployment):
|
async def create_deployment(self, deployment_data: Deployment) -> Deployment:
|
||||||
# Logic to create a new deployment
|
# Logic to create a new deployment
|
||||||
Deployment.insert(deployment_data)
|
return await Deployment.insert(deployment_data)
|
||||||
|
|
||||||
|
|
||||||
async def get_deployments_by_deployment_id(self, deployment_id: str):
|
async def get_deployments_by_deployment_id(self, deployment_id: str):
|
||||||
# Logic to get a deployment by ID
|
# Logic to get a deployment by ID
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
|
from app.common.models.code_depot.code_depot import CodeDepotDoc
|
||||||
from app.common.models.deployment.deployment import Deployment
|
from app.common.models.deployment.deployment import Deployment
|
||||||
|
|
||||||
# list of beanie document models
|
# list of beanie document models,
|
||||||
db_models = [Deployment]
|
# must add here so that the mongo db collection can be automatically created
|
||||||
|
db_models = [Deployment, CodeDepotDoc]
|
||||||
@ -4,6 +4,7 @@ from typing import List
|
|||||||
from fastapi import APIRouter, Depends
|
from fastapi import APIRouter, Depends
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
|
from app.common.models import CodeDepotDoc
|
||||||
from app.common.models.deployment.deployment import Deployment, InitDeploymentRequest
|
from app.common.models.deployment.deployment import Deployment, InitDeploymentRequest
|
||||||
from app.routes.deployment.service import DeploymentService, get_deployment_service
|
from app.routes.deployment.service import DeploymentService, get_deployment_service
|
||||||
|
|
||||||
@ -31,3 +32,16 @@ async def check_deployment_status(
|
|||||||
) -> List[Deployment]:
|
) -> List[Deployment]:
|
||||||
return await service.check_deployment_status(deployment_id)
|
return await service.check_deployment_status(deployment_id)
|
||||||
|
|
||||||
|
@router.post("/createDummyCodeDepot")
|
||||||
|
async def create_dummy_code_depot(
|
||||||
|
service: DeploymentService = Depends(get_deployment_service)
|
||||||
|
) -> CodeDepotDoc:
|
||||||
|
"""
|
||||||
|
Create a dummy code depot for testing purposes.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
depot_name = await service.create_dummy_code_depot()
|
||||||
|
return depot_name
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to create dummy code depot: {e}")
|
||||||
|
raise e
|
||||||
|
|||||||
@ -3,9 +3,14 @@ from collections import defaultdict
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from fastapi import HTTPException
|
import httpx
|
||||||
|
from fastapi import HTTPException, Depends
|
||||||
|
|
||||||
|
from app.common.config.site_settings import site_settings
|
||||||
|
from app.common.daos.code_depot import get_code_depot_dao, CodeDepotDao
|
||||||
|
from app.common.daos.deployment import DeploymentDao, get_deployment_dao
|
||||||
from app.common.models import Deployment
|
from app.common.models import Deployment
|
||||||
|
from app.common.models.code_depot.code_depot import CodeDepotDoc, DepotStatus
|
||||||
from app.common.models.deployment.deployment import InitDeploymentRequest
|
from app.common.models.deployment.deployment import InitDeploymentRequest
|
||||||
|
|
||||||
|
|
||||||
@ -16,27 +21,25 @@ class DeploymentService:
|
|||||||
|
|
||||||
async def init_deployment(
|
async def init_deployment(
|
||||||
self,
|
self,
|
||||||
request: InitDeploymentRequest
|
request: InitDeploymentRequest,
|
||||||
|
dao: DeploymentDao = Depends(get_deployment_dao)
|
||||||
) -> Deployment:
|
) -> Deployment:
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
# TODO validate permission with user_id
|
# TODO validate permission with user_id
|
||||||
# currently skip
|
# currently skip
|
||||||
|
|
||||||
git_url = await self._retrieve_git_url_by_product_id(request.product_id)
|
code_depot = await self._get_code_depot_by_product_id(request.product_id)
|
||||||
|
|
||||||
|
git_url = await self._compose_git_url(code_depot.depot_name)
|
||||||
|
|
||||||
product_initialized = await self._check_if_project_initialized(git_url, request.product_id)
|
|
||||||
if not product_initialized:
|
|
||||||
await self._init_product(git_url, request.product_id)
|
|
||||||
|
|
||||||
# retrieve project name
|
# retrieve project name
|
||||||
project_name = "TODO"
|
project_name = "TODO"
|
||||||
|
|
||||||
# retrieve product info
|
# retrieve product info, depot name should be the same as product name
|
||||||
product_id = request.product_id
|
product_id = request.product_id
|
||||||
product_name = "TODO"
|
product_name = code_depot.depot_name
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
deployment = Deployment.model_construct(
|
deployment = Deployment.model_construct(
|
||||||
deployment_id = str(uuid.uuid4()),
|
deployment_id = str(uuid.uuid4()),
|
||||||
@ -57,8 +60,8 @@ class DeploymentService:
|
|||||||
)
|
)
|
||||||
|
|
||||||
await self._start_deployment(deployment)
|
await self._start_deployment(deployment)
|
||||||
|
res = await dao.create_deployment(deployment)
|
||||||
|
|
||||||
res = await deployment.insert()
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
async def check_deployment_status(
|
async def check_deployment_status(
|
||||||
@ -111,47 +114,64 @@ class DeploymentService:
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def _retrieve_git_url_by_product_id(
|
async def _get_code_depot_by_product_id(
|
||||||
self,
|
self,
|
||||||
product_id: str
|
product_id: str,
|
||||||
|
code_depot_dao: CodeDepotDao = Depends(get_code_depot_dao)
|
||||||
|
) -> CodeDepotDoc:
|
||||||
|
"""
|
||||||
|
Retrieve code depot by product id
|
||||||
|
"""
|
||||||
|
code_depot = await code_depot_dao.get_code_depot_by_product_id(product_id)
|
||||||
|
if not code_depot:
|
||||||
|
raise HTTPException(status_code=404,
|
||||||
|
detail="Code depot not found for the given product id, "
|
||||||
|
"please initialize the product first"
|
||||||
|
)
|
||||||
|
return code_depot
|
||||||
|
|
||||||
|
async def _compose_git_url(
|
||||||
|
self,
|
||||||
|
code_depot_name: str,
|
||||||
|
gitea_base_url: str = site_settings.BASE_GITEA_URL
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Retrieve git url by product id
|
Retrieve git url by product id
|
||||||
"""
|
"""
|
||||||
# TODO implement this function
|
return f"{gitea_base_url}/prodcuts/{code_depot_name.lower()}.git"
|
||||||
return "TODO-git_url"
|
|
||||||
|
|
||||||
async def _check_if_project_initialized(
|
|
||||||
self,
|
|
||||||
git_url: str,
|
|
||||||
product_id: str
|
|
||||||
) -> bool:
|
|
||||||
"""
|
|
||||||
Check if the project has been initialized
|
|
||||||
"""
|
|
||||||
# TODO implement this function
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def _init_product(
|
|
||||||
self,
|
|
||||||
git_url: str,
|
|
||||||
product_id: str
|
|
||||||
) -> bool:
|
|
||||||
"""
|
|
||||||
Initialize the product
|
|
||||||
"""
|
|
||||||
# TODO implement this function
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def _start_deployment(
|
async def _start_deployment(
|
||||||
self,
|
self,
|
||||||
deployment: Deployment
|
deployment: Deployment,
|
||||||
|
reconsile_base_url: str = site_settings.BASE_RECONSILE_URL,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""
|
"""
|
||||||
Start the deployment
|
Start the deployment
|
||||||
"""
|
"""
|
||||||
# TODO implement this function
|
async with httpx.AsyncClient() as client:
|
||||||
pass
|
response = await client.post(
|
||||||
|
f"{reconsile_base_url}/api/devops/reconcile",
|
||||||
|
json=deployment.model_dump()
|
||||||
|
)
|
||||||
|
if response.status_code != 200:
|
||||||
|
raise HTTPException(status_code=response.status_code, detail=response.text)
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def create_dummy_code_depot(
|
||||||
|
self,
|
||||||
|
code_depot_dao: CodeDepotDao = Depends(get_code_depot_dao)
|
||||||
|
) -> CodeDepotDoc:
|
||||||
|
"""
|
||||||
|
Create a dummy code depot for testing purposes.
|
||||||
|
"""
|
||||||
|
depot_name = f"dummy-depot-{uuid.uuid4()}"
|
||||||
|
code_depot = CodeDepotDoc(
|
||||||
|
depot_name=depot_name,
|
||||||
|
product_id="dummy-product-id",
|
||||||
|
depot_status=DepotStatus.CREATED
|
||||||
|
)
|
||||||
|
|
||||||
|
return await code_depot.insert_one(code_depot)
|
||||||
|
|
||||||
deployment_service = DeploymentService()
|
deployment_service = DeploymentService()
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user