Browse Source

i am first

master
gsd 4 weeks ago
commit
9e584d1114
  1. 5
      Dockerfile
  2. 11
      docker-compose.yaml
  3. 77
      server.py

5
Dockerfile

@ -0,0 +1,5 @@
FROM python:3.10
RUN pip install fastapi uvicorn
WORKDIR /app
COPY server.py /app/
ENTRYPOINT ["python3", "server.py"]

11
docker-compose.yaml

@ -0,0 +1,11 @@
services:
node_exporter_relay:
build: ./
environment:
- NEC_HOST=0.0.0.0
- NEC_PORT=9100
- DEAD_AFTER=60
ports:
- 9100:9100
env_file:
- .env

77
server.py

@ -0,0 +1,77 @@
from fastapi import FastAPI
from fastapi import Request
from fastapi.responses import Response
from fastapi import BackgroundTasks
import uvicorn
import os
from time import time
import asyncio
class Collector:
app = FastAPI()
secrets = []
hosts = []
store = {}
def __init__(self) -> None:
self.secrets = os.getenv("KEYS", "secret").split(",")
self.hosts = os.getenv("HOSTS", "srv").split(",")
self.dead_after = int(os.getenv("DEAD_AFTER", "60"))
self.build_routes()
def check_headers(self, request: Request):
if not request.headers.get("Secret", ""):
print("secret empty")
return Response(status_code=400)
if not request.headers.get("Host", ""):
print("host empty")
return Response(status_code=400)
if not request.headers.get("Secret", "") in self.secrets:
return Response(status_code=400)
if not request.headers.get("Host", "").split(":")[0] in self.hosts:
print(request.headers.get("Host", ""))
print(request.headers)
return Response(status_code=400)
return None
async def deadline(self, host):
await asyncio.sleep(self.dead_after)
if host in self.store:
if time()+1 - self.store[host]['timestamp'] > self.dead_after:
print(f"{host} is dead")
del self.store[host]
def build_routes(self):
@self.app.get("/metrics")
async def get(request: Request):
response: Response = self.check_headers(request)
if response:
return response
if request.headers.get("Host", "").split(":")[0] in self.store and self.store[request.headers.get("Host", "").split(":")[0]]['data']:
return Response(content=self.store[request.headers.get("Host", "").split(":")[0]]['data'], status_code=200)
else:
return Response(status_code=404)
@self.app.post("/metrics")
async def post(request: Request, background_tasks: BackgroundTasks):
response: Response = self.check_headers(request)
if response:
return response
host = request.headers.get("Host", "").split(":")[0]
self.store[host] = {
"data":await request.body(),
"timestamp": time()
}
background_tasks.add_task(self.deadline, host)
return Response(status_code=200)
if __name__ == "__main__":
collector = Collector()
uvicorn.run(collector.app, host = os.getenv("NEC_HOST", "0.0.0.0"), port = int(os.getenv("NEC_PORT", "9100")))
Loading…
Cancel
Save