Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kraken structure refactor #2525

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core/services/kraken/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from api.app import app

# Exports
__all__ = ["app"]
37 changes: 37 additions & 0 deletions core/services/kraken/api/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Path
from os import path
# FastAPI
from fastapi import FastAPI
from fastapi_versioning import VersionedFastAPI
from fastapi.staticfiles import StaticFiles
# Routers
from api.v1.routers import index_router_v1, extension_router_v1
from api.v2.routers import index_router_v2, extension_router_v2, container_router_v2
from commonwealth.utils.apis import GenericErrorHandlingRoute

#
# Main API App
#

app = FastAPI(
title="Kraken API",
description="Kraken is the BlueOS service responsible for installing and managing extensions.",
)
app.router.route_class = GenericErrorHandlingRoute

# Adds routers to the app

# API v1
app.include_router(index_router_v1)
app.include_router(extension_router_v1)

# API v2
app.include_router(index_router_v2)
app.include_router(extension_router_v2)
app.include_router(container_router_v2)

# Adds API versioning
app = VersionedFastAPI(app, version="1.0.0", prefix_format="/v{major}.{minor}", enable_latest=True)

# Mount static files
app.mount("/static", StaticFiles(directory=path.join(path.dirname(__file__), "static")), name="static")
Binary file added core/services/kraken/api/static/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions core/services/kraken/api/static/pages/root.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kraken</title>
<style>
body {
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #007bff;
}
.container {
text-align: center;
color: #fff;
}
img {
max-width: 100%;
height: auto;
}
h1 {
font-size: 2.5rem;
}
</style>
</head>
<body>
<div class="container">
<h1>You have found the Kraken!</h1>
<img alt="" src="../assets/logo.png" />
<h3>Check out Kraken's <a href="../../v1.0/docs" style="color: #FFD700;">docs</a></h3>
</div>
</body>
</html>
5 changes: 5 additions & 0 deletions core/services/kraken/api/v1/routers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Routers
from api.v1.routers.index import index_router_v1
from api.v1.routers.extension import extension_router_v1

__all__ = ["index_router_v1", "extension_router_v1"]
80 changes: 80 additions & 0 deletions core/services/kraken/api/v1/routers/extension.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from typing import Any

from fastapi import APIRouter, status
from fastapi.responses import Response
from fastapi_versioning import version

from kraken.models import ExtensionModel
# Just proxy to V2
import api.v2.routers.extension as v2_ext_api


# Creates Extension router
extension_router_v1 = APIRouter(
prefix="/extension",
tags=["extension"],
responses={
status.HTTP_404_NOT_FOUND: {"description": "Not found"}
},
)

# Endpoints

@extension_router_v1.post("/install", status_code=status.HTTP_201_CREATED)
@version(1, 0)
async def install(extension: ExtensionModel) -> Any:
"""
Install an extension.
"""

return await v2_ext_api.install(extension)


@extension_router_v1.post("/uninstall", status_code=status.HTTP_200_OK)
@version(1, 0)
async def uninstall(extension_identifier: str) -> Response:
"""
Uninstall an extension.
"""

return await v2_ext_api.uninstall(extension_identifier)


@extension_router_v1.post("/update", status_code=status.HTTP_201_CREATED)
@version(1, 0)
async def update(extension_identifier: str, new_version: str) -> Response:
"""
Update an extension.
"""

return await v2_ext_api.update(extension_identifier, new_version)


@extension_router_v1.post("/enable", status_code=status.HTTP_200_OK)
@version(1, 0)
async def enable(extension_identifier: str) -> Response:
"""
Enable an extension.
"""

return await v2_ext_api.enable(extension_identifier)


@extension_router_v1.post("/disable", status_code=status.HTTP_200_OK)
@version(1, 0)
async def disable(extension_identifier: str) -> Response:
"""
Disable an extension.
"""

return await v2_ext_api.disable(extension_identifier)


@extension_router_v1.post("/restart", status_code=status.HTTP_202_ACCEPTED)
@version(1, 0)
async def restart(extension_identifier: str) -> Response:
"""
Restart an extension.
"""

return await v2_ext_api.restart(extension_identifier)
82 changes: 82 additions & 0 deletions core/services/kraken/api/v1/routers/index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from typing import Any, Iterable

from fastapi import APIRouter, status
from fastapi.responses import Response, HTMLResponse, PlainTextResponse
from fastapi_versioning import version

# Just proxy to V2
import api.v2.routers.index as v2_index_api
import api.v2.routers.container as v2_container_api
import api.v2.routers.extension as v2_ext_api


# Creates Root Kraken router
index_router_v1 = APIRouter(
responses={
status.HTTP_404_NOT_FOUND: {"description": "Not found"}
},
)

# Endpoints

@index_router_v1.get("/extensions_manifest", status_code=status.HTTP_200_OK)
@version(1, 0)
async def fetch_manifest() -> Any:
"""
Fetch the manifest of all extensions.
"""

return await v2_ext_api.manifest()


@index_router_v1.get("/installed_extensions", status_code=status.HTTP_200_OK)
@version(1, 0)
async def get_installed_extensions() -> Any:
"""
List all installed extensions, sorted by name.
"""

return await v2_ext_api.list()


@index_router_v1.get("/list_containers", status_code=status.HTTP_200_OK)
@version(1, 0)
async def list_containers() -> Any:
"""
List all containers.
"""

return await v2_container_api.list()


@index_router_v1.get("/log", status_code=status.HTTP_200_OK, response_class=PlainTextResponse)
@version(1, 0)
async def log_containers(container_name: str) -> Iterable[bytes]:
"""
Get logs of a container.
"""

return await v2_index_api.log(container_name)


@index_router_v1.get("/stats", status_code=status.HTTP_200_OK)
@version(1, 0)
async def load_stats() -> Any:
"""
List all containers.
"""

return await v2_container_api.stats()


@index_router_v1.get("/", response_class=HTMLResponse, status_code=200)
@version(1, 0)
async def root() -> Response:
html_content = """
<html>
<head>
<title>Kraken</title>
</head>
</html>
"""
return HTMLResponse(content=html_content, status_code=200)
6 changes: 6 additions & 0 deletions core/services/kraken/api/v2/routers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Routers
from api.v2.routers.index import index_router_v2
from api.v2.routers.container import container_router_v2
from api.v2.routers.extension import extension_router_v2

__all__ = ["index_router_v2", "container_router_v2", "extension_router_v2"]
54 changes: 54 additions & 0 deletions core/services/kraken/api/v2/routers/container.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from fastapi import APIRouter, status
from fastapi_versioning import version

from kraken import Kraken
from kraken.models import ContainerModel, ContainerUsageModel


# Creates Extension router
container_router_v2 = APIRouter(
prefix="/container",
tags=["container"],
responses={
status.HTTP_404_NOT_FOUND: {"description": "Not found"}
},
)

# Endpoints

@container_router_v2.get("/", status_code=status.HTTP_200_OK, response_model=list[ContainerModel])
@version(2, 0)
async def list() -> list[ContainerModel]:
"""
List all running containers.
"""

containers = await Kraken.list_containers()
return [
ContainerModel(
name=container["Names"][0],
image=container["Image"],
image_id=container["ImageID"],
status=container["Status"],
)
for container in containers
]


@container_router_v2.get("/stats", status_code=status.HTTP_200_OK, response_model=dict[str, ContainerUsageModel])
@version(2, 0)
async def stats() -> dict[str, ContainerUsageModel]:
"""
List stats of all running containers.
"""

stats = await Kraken.stats()

return {
key: ContainerUsageModel(
cpu=usage[0],
memory=usage[1],
disk=usage[2],
)
for key, usage in stats.items()
}
Loading
Loading