Implement event log

This commit is contained in:
2022-09-25 20:02:52 +02:00
parent 8886b23434
commit 1a46cf7ef3
11 changed files with 197 additions and 128 deletions

View File

@@ -9,6 +9,7 @@ from .user import user_auth
from .map_tiles import map_tiles, map_meta
from .templates import j2env
from .monitoring import monitoring, ws_manager
from .api import api
app = FastAPI()
@@ -16,6 +17,7 @@ app.mount("/user/", user_auth)
app.mount("/map/", map_meta)
app.mount("/tiles/", map_tiles)
app.mount("/ipmi/", monitoring)
app.mount("/api/", api)
installer = j2env.get_template("install.lua").render(deploy_path=settings.deploy_path)

40
server/server/api.py Normal file
View File

@@ -0,0 +1,40 @@
from datetime import datetime
from typing import Any
from bson import ObjectId
from fastapi import Body, FastAPI, status
from pydantic import BaseModel, Field
import pymongo
from .db import events, PyObjectId, create_event
api = FastAPI()
class Event(BaseModel):
id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
timestamp: datetime
value: Any
class Config:
json_encoders = {ObjectId: str}
@api.get("/events", response_model=list[Event])
async def get_events():
return await events.find().sort("timestamp", pymongo.DESCENDING).to_list(None)
"""
@api.get("/events/{id}", response_model=Event)
async def get_single_event(id: PyObjectId):
if (event := await events.find_one({"_id": id})) is not None:
return event
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
"""
# TODO auth
@api.post("/events", response_model=Event, status_code=status.HTTP_201_CREATED)
async def push_event(value: Any = Body(...)):
return await create_event(value)

View File

@@ -1,3 +1,5 @@
from datetime import datetime
from bson import ObjectId
import motor.motor_asyncio as motor
from .settings import settings
@@ -8,6 +10,16 @@ db = client["controlpanel"]
events: motor.AsyncIOMotorCollection = db["events"]
async def create_event(value: any):
event = {
"timestamp": datetime.now(),
"value": value,
}
new_event = await events.insert_one(event)
created_event = await events.find_one({"_id": new_event.inserted_id})
return created_event
class PyObjectId(ObjectId):
@classmethod
def __get_validators__(cls):

View File

@@ -1,21 +1,11 @@
import asyncio
from typing import Any
from uuid import UUID
from datetime import datetime
from bson import ObjectId
from fastapi import (
Body,
FastAPI,
HTTPException,
WebSocket,
WebSocketDisconnect,
status,
)
from fastapi.responses import JSONResponse
from pydantic import BaseModel, Field, ValidationError
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from pydantic import BaseModel, ValidationError
from .db import PyObjectId, events
from .db import create_event
monitoring = FastAPI()
@@ -75,7 +65,7 @@ class WSManager:
await socket.close()
return
print(f"[WS] Computer {uuid} connected")
await create_event({"type": "computer_connect", "computer_id": str(uuid)})
self.computers[uuid] = socket
if len(self.viewers.get(uuid, [])) > 0:
@@ -96,7 +86,7 @@ class WSManager:
break
del self.computers[uuid]
print(f"[WS] Computer {uuid} disconnected")
await create_event({"type": "computer_disconnect", "computer_id": str(uuid)})
async def on_browser_connect(self, socket: WebSocket, uuid: UUID):
print(f"[WS] Browser connected for {uuid}")
@@ -135,41 +125,3 @@ async def computer_ws(socket: WebSocket, uuid: UUID):
async def browser_ws(socket: WebSocket, uuid: UUID):
await socket.accept()
await ws_manager.on_browser_connect(socket, uuid)
class Event(BaseModel):
id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
timestamp: datetime
value: Any
class Config:
allow_population_by_field_name = True
arbitrary_types_allowed = True
json_encoders = {ObjectId: str}
@monitoring.get("/events", response_model=list[Event])
async def get_events():
print("get /events")
return await events.find().to_list(1000)
@monitoring.get("/events/{id}", response_model=Event)
async def get_single_event(id: PyObjectId):
if (event := await events.find_one({"_id": id})) is not None:
return event
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
@monitoring.post(
"/push_event", response_model=Event, status_code=status.HTTP_201_CREATED
)
async def push_event(value: Any = Body(...)):
event = {
"timestamp": datetime.now(),
"value": value,
}
new_event = await events.insert_one(event)
created_event = await events.find_one({"_id": new_event.inserted_id})
return created_event