Skip to content

Commit

Permalink
feat: Allow deletion of remote repository (#494)
Browse files Browse the repository at this point in the history
  • Loading branch information
daryllimyt authored Nov 6, 2024
1 parent 34e4b93 commit 5b17947
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 30 deletions.
6 changes: 3 additions & 3 deletions frontend/src/client/services.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1205,15 +1205,15 @@ export const registryRepositoriesUpdateRegistryRepository = (data: RegistryRepos
* Delete Registry Repository
* Delete a registry repository.
* @param data The data for the request.
* @param data.origin
* @param data.id
* @returns void Successful Response
* @throws ApiError
*/
export const registryRepositoriesDeleteRegistryRepository = (data: RegistryRepositoriesDeleteRegistryRepositoryData): CancelablePromise<RegistryRepositoriesDeleteRegistryRepositoryResponse> => { return __request(OpenAPI, {
method: 'DELETE',
url: '/registry/repos/{origin}',
url: '/registry/repos/{id}',
path: {
origin: data.origin
id: data.id
},
errors: {
422: 'Validation Error'
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/client/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1602,7 +1602,7 @@ export type RegistryRepositoriesUpdateRegistryRepositoryData = {
export type RegistryRepositoriesUpdateRegistryRepositoryResponse = RegistryRepositoryRead;

export type RegistryRepositoriesDeleteRegistryRepositoryData = {
origin: string;
id: string;
};

export type RegistryRepositoriesDeleteRegistryRepositoryResponse = void;
Expand Down Expand Up @@ -2481,6 +2481,8 @@ export type $OpenApiTs = {
422: HTTPValidationError;
};
};
};
'/registry/repos/{id}': {
delete: {
req: RegistryRepositoriesDeleteRegistryRepositoryData;
res: {
Expand Down
8 changes: 6 additions & 2 deletions frontend/src/components/registry/registry-repos-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,13 @@ export function RegistryRepositoriesTable() {
console.error("No repository selected")
return
}
console.log("Deleting repository", selectedRepo.origin)
console.log(
"Deleting repository",
selectedRepo.origin,
selectedRepo.id
)
try {
await deleteRepo({ origin: selectedRepo.origin })
await deleteRepo({ id: selectedRepo.id })
} catch (error) {
console.error("Error deleting repository", error)
} finally {
Expand Down
38 changes: 19 additions & 19 deletions tracecat/registry/repositories/router.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from fastapi import APIRouter, HTTPException, Query, status
from pydantic import UUID4

from tracecat.auth.credentials import RoleACL
from tracecat.auth.dependencies import OrgUserOrServiceRole, OrgUserRole
Expand Down Expand Up @@ -46,7 +47,7 @@ async def sync_registry_repositories(
# Check if the base registry repository already exists
await ensure_base_repository(session=session, role=role)
if origins is None:
repos = await repos_service.list_repositories()
repos = list(await repos_service.list_repositories())
else:
# If origins are provided, only sync those repositories
repos: list[RegistryRepository] = []
Expand All @@ -67,7 +68,7 @@ async def sync_registry_repositories(
try:
await actions_service.sync_actions(repos)
except RegistryError as e:
logger.warning("Cannot sync repository", origin=origin, exc=e)
logger.warning("Cannot sync repository", exc=e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)
) from e
Expand Down Expand Up @@ -138,10 +139,11 @@ async def create_registry_repository(
logger.info("Creating registry", params=params)
created_repository = await service.create_repository(params)
return RegistryRepositoryRead(
origin=created_repository.origin,
actions=[
RegistryActionRead.model_validate(action, from_attributes=True)
for action in created_repository.actions
]
],
)
except Exception as e:
raise HTTPException(
Expand Down Expand Up @@ -170,32 +172,30 @@ async def update_registry_repository(
updated_repository = await service.update_repository(repository)
return RegistryRepositoryRead(
origin=updated_repository.origin,
actions=[action.to_read_model() for action in updated_repository.actions],
actions=[
RegistryActionRead.model_validate(action, from_attributes=True)
for action in updated_repository.actions
],
)


@router.delete("/{origin:path}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete("/{id:uuid}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_registry_repository(
role: OrgUserOrServiceRole, session: AsyncDBSession, origin: str
role: OrgUserOrServiceRole, session: AsyncDBSession, id: UUID4
):
"""Delete a registry repository."""
logger.info("Deleting registry repository", origin=origin)
if origin == DEFAULT_REGISTRY_ORIGIN:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="You cannot delete the base Tracecat repository.",
)
elif origin == CUSTOM_REPOSITORY_ORIGIN:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="You cannot delete the custom repository.",
)
service = RegistryReposService(session, role)
repository = await service.get_repository(origin)
repository = await service.get_repository_by_id(id)
if repository is None:
logger.error("Registry repository not found", origin=origin)
logger.error("Registry repository not found", id=id)
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Registry repository not found",
)
logger.info("Deleting registry repository", id=id)
if repository.origin in (DEFAULT_REGISTRY_ORIGIN, CUSTOM_REPOSITORY_ORIGIN):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"The {repository.origin!r} repository cannot be deleted.",
)
await service.delete_repository(repository)
16 changes: 11 additions & 5 deletions tracecat/registry/repositories/service.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from __future__ import annotations

from collections.abc import AsyncGenerator
from collections.abc import AsyncGenerator, Sequence
from contextlib import asynccontextmanager

from pydantic import UUID4
from sqlmodel import select
from sqlmodel.ext.asyncio.session import AsyncSession

Expand Down Expand Up @@ -31,7 +32,7 @@ async def with_session(
async with get_async_session_context_manager() as session:
yield RegistryReposService(session, role=role)

async def list_repositories(self) -> list[RegistryRepository]:
async def list_repositories(self) -> Sequence[RegistryRepository]:
"""Get all registry repositories."""
statement = select(RegistryRepository)
result = await self.session.exec(statement)
Expand All @@ -45,6 +46,12 @@ async def get_repository(self, origin: str) -> RegistryRepository | None:
result = await self.session.exec(statement)
return result.one_or_none()

async def get_repository_by_id(self, id: UUID4) -> RegistryRepository | None:
"""Get a registry by ID."""
statement = select(RegistryRepository).where(RegistryRepository.id == id)
result = await self.session.exec(statement)
return result.one_or_none()

async def create_repository(
self, params: RegistryRepositoryCreate
) -> RegistryRepository:
Expand All @@ -63,11 +70,10 @@ async def update_repository(
"""Update a registry repository."""
self.session.add(repository)
await self.session.commit()
await self.session.refresh(repository)
return repository

async def delete_repository(
self, repository: RegistryRepository
) -> RegistryRepository:
async def delete_repository(self, repository: RegistryRepository) -> None:
"""Delete a registry repository."""
await self.session.delete(repository)
await self.session.commit()

0 comments on commit 5b17947

Please sign in to comment.