Compare commits

...

6 Commits

2
.gitignore vendored

@ -141,3 +141,5 @@ cython_debug/
# Project specific: # Project specific:
.sync_token .sync_token
config.yaml config.yaml
*.key
*.crt

@ -17,10 +17,7 @@ async def __main():
bot_corout = send_messages( bot_corout = send_messages(
message_queue, message_queue,
config.username, config
config.homeserver,
config.password,
config.alert_rooms
) )
format_corout = format_alerts( format_corout = format_alerts(
alert_queue, alert_queue,
@ -28,8 +25,7 @@ async def __main():
) )
webhook_corout = run_webhook( webhook_corout = run_webhook(
alert_queue, alert_queue,
config.host, config
config.port
) )

@ -9,6 +9,7 @@ from typing import (
) )
from matrix_bot.client import Client from matrix_bot.client import Client
from matrix_bot.invite_policy import WhiteList from matrix_bot.invite_policy import WhiteList
from .config import Config
from .format import Message from .format import Message
async def __send_messsages( async def __send_messsages(
@ -31,27 +32,24 @@ async def __send_messsages(
async def send_messages( async def send_messages(
message_queue: asyncio.Queue[dict[str, Any]], # For now, type will change in the futur message_queue: asyncio.Queue[dict[str, Any]], # For now, type will change in the futur
username: str, config: Config
homeserver: str,
password: str,
alert_rooms: list[str]
): ):
""" """
Initialize the bot and send messages added to the queue to the alert_rooms. Initialize the bot and send messages added to the queue to the alert_rooms.
""" """
bot = await Client( bot = await Client(
username, config.username,
homeserver, config.homeserver,
password config.password
) )
invite_policy = await WhiteList(bot, alert_rooms) invite_policy = await WhiteList(bot, config.alert_rooms)
bot.set_invite_policy(invite_policy) bot.set_invite_policy(invite_policy)
await asyncio.gather( await asyncio.gather(
bot.run(), bot.run(),
__send_messsages( __send_messsages(
message_queue, message_queue,
bot, bot,
alert_rooms config.alert_rooms
) )
) )

@ -5,14 +5,38 @@ Config related tools.
import dataclasses import dataclasses
import yaml import yaml
from typing import Optional
@dataclasses.dataclass @dataclasses.dataclass
class Config: class Config:
username: str username: str
homeserver: str homeserver: str
password: str password: str
port: int
host: str
alert_rooms: list[str] alert_rooms: list[str]
port: int = 8000
host: str = "127.0.0.1"
endpoint: str = "/webhook"
tls: bool = False
tls_auth: bool = False
tls_crt: Optional[str] = None
tls_key: Optional[str] = None
ca_crt: Optional[str] = None
def check_integrity(self)->bool:
""" Check the integrity of the config.
Raise an error if the config is invalid,
should always return True (or raise an error).
"""
if self.tls_auth and not self.tls:
raise ValueError("tls_auth is enable, but not tls.")
if self.tls and self.tls_crt is None:
raise ValueError("tls is enable but tls_crt was not provided")
if self.tls and self.tls_key is None:
raise ValueError("tls is enable but tls_key was not provided")
if self.tls_auth and self.ca_crt is None:
raise ValueError("tls_auth is enable, but ca_crt was not provided")
return True
def load_config(file:str)->Config: def load_config(file:str)->Config:
""" """
@ -20,5 +44,7 @@ def load_config(file:str)->Config:
""" """
with open(file, 'r') as f: with open(file, 'r') as f:
data = yaml.load(f, Loader=yaml.loader.SafeLoader) data = yaml.load(f, Loader=yaml.loader.SafeLoader)
return Config(**data) config = Config(**data)
config.check_integrity()
return config

@ -5,31 +5,56 @@ The webhook receiving the alerts from alertmanager.
import asyncio import asyncio
import aiohttp.web import aiohttp.web
import aiohttp.web_request import aiohttp.web_request
import ssl
from typing import ( from typing import (
Any, Any,
NoReturn NoReturn
) )
from .config import Config
def load_ssl_context(config:Config)->ssl.SSLContext:
"""
Load the SSL context from the config.
"""
ca_path = None
if config.tls_auth:
ca_path = config.ca_crt
ssl_context = ssl.create_default_context(
purpose=ssl.Purpose.CLIENT_AUTH,
cafile=ca_path
)
if config.tls_auth:
ssl_context.verify_mode = ssl.CERT_REQUIRED
ssl_context.load_cert_chain(config.tls_crt, config.tls_key)
return ssl_context
ENDPOINT = "/webhook"
async def run_webhook( async def run_webhook(
alert_queue: asyncio.Queue[dict[str, Any]], alert_queue: asyncio.Queue[dict[str, Any]],
host: str, config: Config
port: int
)->NoReturn: )->NoReturn:
""" """
Run the webhook endpoint and put the alerts in the queue. Run the webhook endpoint and put the alerts in the queue.
""" """
async def handler(request:aiohttp.web_request.Request): async def handler(request:aiohttp.web_request.Request)->aiohttp.web.Response:
alert = await request.json() alert = await request.json()
await alert_queue.put(alert) await alert_queue.put(alert)
return aiohttp.web.Response() return aiohttp.web.Response()
async def health(request:aiohttp.web_request.Request)->aiohttp.web.Response:
return aiohttp.web.Response(text="OK")
app = aiohttp.web.Application() app = aiohttp.web.Application()
app.add_routes([aiohttp.web.post(ENDPOINT, handler)]) app.add_routes([
aiohttp.web.post(config.endpoint, handler),
aiohttp.web.get("/health", health)
])
runner = aiohttp.web.AppRunner(app) runner = aiohttp.web.AppRunner(app)
await runner.setup() await runner.setup()
site = aiohttp.web.TCPSite(runner, host, port) ssl_context = None
if config.tls:
ssl_context = load_ssl_context(config)
site = aiohttp.web.TCPSite(runner, config.host, config.port, ssl_context=ssl_context)
await site.start() await site.start()

Loading…
Cancel
Save