diff --git a/Dockerfile b/Dockerfile index b8367ad..910503a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,9 @@ COPY ./requirements.txt . COPY ./sync.py . COPY ./src ./src -RUN pip install -r requirements.txt +RUN pip install --no-cache-dir --upgrade -r requirements.txt +RUN pip install uvicorn["standard"] -CMD ["python", "/app/sync.py"] + +CMD ["uvicorn", "sync:app", "--host", "0.0.0.0", "--port", "80", "--reload"] +#CMD ["uvicorn", "run", "app/sync.py", "--port", "80"] diff --git a/requirements.txt b/requirements.txt index 9a2f608..164fe63 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,4 @@ requests==2.32.3 PyYAML==6.0.2 +fastapi==0.95.1 +uvicorn==0.22.0 \ No newline at end of file diff --git a/sync.py b/sync.py index 914adac..294fe7c 100644 --- a/sync.py +++ b/sync.py @@ -3,7 +3,9 @@ import os import yaml import requests - +from pydantic import BaseModel +from fastapi import FastAPI, Request +from typing import Dict, Any from http.server import BaseHTTPRequestHandler, HTTPServer from src.json_log_formatter import JsonFormatter @@ -23,6 +25,11 @@ LOKI_API_ENDPOINT = os.environ['LOKI_API_ENDPOINT'] LOKI_POST_HEADERS = {"Content-Type": "application/yaml"} +app = FastAPI() + +class StringPayload(BaseModel): + text: str + def create_or_update_alerting_rule_group( rule_namespace, yaml_rule_group_definition, @@ -57,78 +64,66 @@ def get_alerting_rules_in_namespace(rule_namespace,): return yaml.safe_load(response.text)[rule_namespace][0] - -class LokiRuleGroupHandler(BaseHTTPRequestHandler): - def do_POST(self): - content_length = int(self.headers['Content-Length']) - request_body = self.rfile.read(content_length).decode('utf-8') - request_data = json.loads(request_body) - - parent = request_data['parent'] - rule_group = yaml.dump(parent.get('spec', {})) - try: +@app.post("/sync") +async def post(request: Request): + request_data = await request.json() # Accepts any dynamic JSON payload + #request_data = json.loads(request_body) + print(request_data) + parent = request_data['parent'] + rule_group = yaml.dump(parent.get('spec', {})) + try: rule_group_namespace = request_data['parent']['spec']['name'] - except Exception: + except Exception: status = 'Degraded' logger.exception(f'failed to parse request: {request_data}') - - if self.path.endswith('/finalize'): - # Handle the finalize hook - try: - response = delete_alerting_rule_group( - rule_name=rule_group_namespace, - rule_namespace=rule_group_namespace, - ) - response_data = { - "finalized": response.ok - } - self.send_response(200) - self.send_header('Content-Type', 'application/json') - self.end_headers() - self.wfile.write(json.dumps(response_data).encode('utf-8')) - except Exception: - response_data = { - "finalized": True - } - self.send_response(200) - self.send_header('Content-Type', 'application/json') - self.end_headers() - self.wfile.write(json.dumps(response_data).encode('utf-8')) - logger.warning( - f'failed to delete rule group from request, did it exist?: {request_data}' - ) - - else: - # Sync the object with the external API - try: - response = create_or_update_alerting_rule_group( + try: + response = create_or_update_alerting_rule_group( rule_namespace=rule_group_namespace, yaml_rule_group_definition=rule_group ) # check if rule group was created - if yaml.safe_load(rule_group) == get_alerting_rules_in_namespace( + if yaml.safe_load(rule_group) == get_alerting_rules_in_namespace( rule_namespace=rule_group_namespace - ): + ): status = 'Healthy' - else: + else: status = 'Progressing' - except Exception: + except Exception: status = "Degraded" logger.exception(f'failed to create rule group: {rule_group}') - - - # Prepare the response for Metacontroller - response_data = { + response_data = { 'status': { 'health': { 'status': status }, }, - } + } + + return response_data - self.send_response(200) - self.send_header('Content-Type', 'application/json') - self.end_headers() - self.wfile.write(json.dumps(response_data).encode('utf-8')) +@app.post("/finalize") +async def finalize(request: Request): + request_data = await request.json() + parent = request_data['parent'] + rule_group = yaml.dump(parent.get('spec', {})) + try: + rule_group_namespace = request_data['parent']['spec']['name'] + except Exception: + status = 'Degraded' + logger.exception(f'failed to parse request: {request_data}') + try: + response = delete_alerting_rule_group( + rule_name=rule_group_namespace, + rule_namespace=rule_group_namespace, + ) + response_data = { + "finalized": response.ok + } + return response_data + except Exception: + response_data = { + "finalized": True + } + return response_data + -HTTPServer(("", 80), LokiRuleGroupHandler).serve_forever()