sts-sponsors team mailing list archive
-
sts-sponsors team
-
Mailing list archive
-
Message #05337
[Merge] ~thorsten-merten/maas-site-manager:MAASENG-1290-extend-models-and-views into maas-site-manager:main
Thorsten Merten has proposed merging ~thorsten-merten/maas-site-manager:MAASENG-1290-extend-models-and-views into maas-site-manager:main.
Commit message:
feat: expand data model as in frontend spec and add token list view
* add site_data table with props
* add props to site
(not using another table as it ain't
much and will almost never change)
* update schema accordingly
Requested reviews:
MAAS Committers (maas-committers)
For more details, see:
https://code.launchpad.net/~thorsten-merten/maas-site-manager/+git/maas-site-manager/+merge/437801
--
Your team MAAS Committers is requested to review the proposed merge of ~thorsten-merten/maas-site-manager:MAASENG-1290-extend-models-and-views into maas-site-manager:main.
diff --git a/msm/db/_tables.py b/msm/db/_tables.py
index 3d8a2d7..a69f1c7 100644
--- a/msm/db/_tables.py
+++ b/msm/db/_tables.py
@@ -2,8 +2,11 @@ from uuid import uuid4
from sqlalchemy import (
Column,
+ DECIMAL,
+ ForeignKey,
Integer,
MetaData,
+ String,
Table,
Text,
)
@@ -15,17 +18,43 @@ METADATA = MetaData()
Site = Table(
"site",
METADATA,
+ Column("alias", String(250), unique=True),
+ Column("city", String(250)),
Column("id", Integer, primary_key=True, index=True),
- Column("name", Text, nullable=False, unique=True),
Column("last_checkin", DateTime),
+ # Decimal(8/6)/(9/6) = 16cm precision
+ Column("latitude", DECIMAL(precision=8, scale=6)),
+ Column("longitude", DECIMAL(precision=9, scale=6)),
+ Column("name", String(250)),
+ Column("note", Text),
+ Column("region", String(250)),
+ Column("street", String(250)),
+ Column("timezone", String(3)),
+ Column("url", String(2048)),
)
+
Token = Table(
"token",
METADATA,
Column("id", Integer, primary_key=True, index=True),
+ Column("site_id", Integer, ForeignKey("site.id"), index=True),
Column(
"value", UUID(as_uuid=True), nullable=False, index=True, default=uuid4
),
Column("expiration", DateTime, nullable=False),
)
+
+SiteData = Table(
+ "site_data",
+ METADATA,
+ Column("id", Integer, primary_key=True, index=True),
+ Column(
+ "site_id", Integer, ForeignKey("site.id"), index=True, nullable=False
+ ),
+ Column("total_machines", Integer),
+ Column("occupied_machines", Integer),
+ Column("ready_machines", Integer),
+ Column("error_machines", Integer),
+ Column("last_seen", DateTime),
+)
diff --git a/msm/db/queries.py b/msm/db/queries.py
index 50e116b..8821458 100644
--- a/msm/db/queries.py
+++ b/msm/db/queries.py
@@ -22,6 +22,13 @@ async def get_sites(session: AsyncSession) -> Iterable[dict[str, Any]]:
return (row._asdict() for row in result.all())
+async def get_tokens(session: AsyncSession) -> Iterable[dict[str, Any]]:
+ result = await session.execute(
+ select(Token.c.id, Token.c.site_id, Token.c.value, Token.c.expiration)
+ )
+ return (row._asdict() for row in result.all())
+
+
async def create_tokens(
session: AsyncSession, duration: timedelta, count: int = 1
) -> tuple[datetime, list[UUID]]:
diff --git a/msm/user_api/_base.py b/msm/user_api/_base.py
index ad03d48..76bf796 100644
--- a/msm/user_api/_base.py
+++ b/msm/user_api/_base.py
@@ -20,6 +20,14 @@ async def sites(
return [schema.Site(**entry) for entry in await queries.get_sites(session)]
+async def tokens(
+ session: AsyncSession = Depends(db_session),
+) -> list[schema.Token]:
+ return [
+ schema.Token(**entry) for entry in await queries.get_tokens(session)
+ ]
+
+
async def tokens_post(
create_request: schema.CreateTokensRequest,
session: AsyncSession = Depends(db_session),
diff --git a/msm/user_api/_schema.py b/msm/user_api/_schema.py
index 04440a3..6f65589 100644
--- a/msm/user_api/_schema.py
+++ b/msm/user_api/_schema.py
@@ -2,31 +2,113 @@ from datetime import (
datetime,
timedelta,
)
+from decimal import Decimal
from uuid import UUID
from pydantic import BaseModel
+<<<<<<< msm/user_api/_schema.py
class Site(BaseModel):
"""A MAAS installation."""
id: int
+=======
+class CreateSite(BaseModel):
+ """
+ To create a site name, alias, and URL are needed
+ """
+>>>>>>> msm/user_api/_schema.py
name: str
last_checkin: datetime | None
+ alias: str
+ city: str | None
+ latitude: Decimal | None
+ longitude: Decimal | None
+ note: str | None
+ region: str | None
+ street: str | None
+ timezone: str | None
+ url: str
+
+
+class CreateSiteData(BaseModel):
+ """
+ All SiteData is obligatory
+ """
+ site_id: int
+ total_machines: int
+ occupied_machines: int
+ ready_machines: int
+ error_machines: int
+ last_seen: datetime
+
+
+class SiteData(CreateSiteData):
+ """
+ SiteData persisted to the database
+ """
+ id: int
+
+
+class Site(CreateSite):
+ """
+ A site persisted to the database
+ """
+ id: int
+
+
+class SiteWithData(Site):
+
+ """
+ A site, together with its SiteData
+ """
+ id: int
+ site_data: SiteData
+
+
+class CreateToken(BaseModel):
+ """
+ To create a token a value and an expiration
+ time need to be generated
+ """
+ site_id: int | None
+ value: UUID
+ expiration: datetime
+
+
+class Token(CreateToken):
+ """
+ A token persisted to the database
+ """
+ id: int
class CreateTokensRequest(BaseModel):
+<<<<<<< msm/user_api/_schema.py
"""Request to create one or more tokens, with a certain validity, expressed
in seconds.
"""
+=======
+ """
+ When creating tokens, we need the count
+ and the time to live (duration in seconds)
+ """
+>>>>>>> msm/user_api/_schema.py
count: int = 1
duration: timedelta
class CreateTokensResponse(BaseModel):
+<<<<<<< msm/user_api/_schema.py
"""List of created tokens, along with their duration."""
+=======
+ """
+ After creating tokens the generated tokens are returned
+ """
+>>>>>>> msm/user_api/_schema.py
expiration: datetime
tokens: list[UUID]
diff --git a/msm/user_api/_setup.py b/msm/user_api/_setup.py
index b8b524e..f181be3 100644
--- a/msm/user_api/_setup.py
+++ b/msm/user_api/_setup.py
@@ -19,5 +19,6 @@ def create_app(db_dsn: str = DEFAULT_DB_DSN) -> FastAPI:
app.state.db = db
app.router.add_api_route("/", _base.root, methods=["GET"])
app.router.add_api_route("/sites", _base.sites, methods=["GET"])
+ app.router.add_api_route("/tokens", _base.tokens, methods=["GET"])
app.router.add_api_route("/tokens", _base.tokens_post, methods=["POST"])
return app
Follow ups