diff --git a/containers/monitoring/monitoring.py b/containers/monitoring/monitoring.py index 4210f5c..ac82367 100644 --- a/containers/monitoring/monitoring.py +++ b/containers/monitoring/monitoring.py @@ -2,12 +2,12 @@ import requests import time from datetime import datetime from subprocess import Popen, PIPE +import os +import uuid + DEBUG = False -if DEBUG: - API_ADDRESS = "http://localhost:8000" -else: - API_ADDRESS = "http://routerfleet:8001" +API_ADDRESS = "http://routerfleet:8001" HOST_LIST_URL = f"{API_ADDRESS}/monitoring/export_router_list/" UPDATE_STATUS_URL = f"{API_ADDRESS}/monitoring/update_router_status/" @@ -23,16 +23,34 @@ host_list_update_timestamp = 0 notification_count = 0 current_router_config_timestamp = '' remote_router_config_timestamp = '' +api_key = '' def get_verbose_status(status): return "online" if status else "offline" +def get_api_key(): + api_key_temp = None + api_file_path = "/app_secrets/monitoring_key" + + if os.path.exists(api_file_path) and os.path.isfile(api_file_path): + with open(api_file_path, 'r') as api_file: + api_file_content = api_file.read().strip() + try: + uuid_test = uuid.UUID(api_file_content) + + if str(uuid_test) == api_file_content: + api_key_temp = str(uuid_test) + except: + pass + return api_key_temp + + def update_router_config_timestamp(): - global remote_router_config_timestamp + global remote_router_config_timestamp, api_key try: - response = requests.get(CONFIG_TIMESTAMP_URL) + response = requests.get(f"{CONFIG_TIMESTAMP_URL}?key={api_key}") if response.status_code == 200: remote_router_config_timestamp_temp = response.json()['router_config'] if remote_router_config_timestamp_temp != remote_router_config_timestamp: @@ -48,9 +66,9 @@ def update_router_config_timestamp(): def fetch_host_list(): - global host_list_update_timestamp, current_router_config_timestamp, remote_router_config_timestamp + global host_list_update_timestamp, current_router_config_timestamp, remote_router_config_timestamp, api_key try: - response = requests.get(HOST_LIST_URL) + response = requests.get(f"{HOST_LIST_URL}?key={api_key}") if response.status_code == 200: host_list_update_timestamp = time.time() remote_router_config_timestamp = response.json()['router_config'] @@ -64,12 +82,12 @@ def fetch_host_list(): def update_host_status(uuid, status): - global notification_count + global notification_count, api_key if notification_count >= MAX_NOTIFICATIONS_PER_MONITOR_INTERVAL: print(f"{datetime.now()} - Notification limit reached. Skipping Remote API update for {host_list[uuid]['address']}") return # Skip if notification limit is reached try: - response = requests.get(f"{UPDATE_STATUS_URL}?uuid={uuid}&status={get_verbose_status(status)}") + response = requests.get(f"{UPDATE_STATUS_URL}?key={api_key}&uuid={uuid}&status={get_verbose_status(status)}") if response.status_code == 200: print(f"{datetime.now()} - Remote API Status updated for {host_list[uuid]['address']} to {get_verbose_status(status)}") notification_count += 1 @@ -93,7 +111,12 @@ def check_host_status(host_uuid): def update_and_monitor(): - global host_list, host_list_update_timestamp, notification_count, current_router_config_timestamp, remote_router_config_timestamp + global host_list, host_list_update_timestamp, notification_count, current_router_config_timestamp, remote_router_config_timestamp, api_key + api_key = get_api_key() + if not api_key: + print(f"{datetime.now()} - Monitoring key not found or invalid. Exiting...") + exit(1) + while True: update_router_config_timestamp() current_time = time.time() diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 14bc455..2e3c4e7 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -26,13 +26,14 @@ services: - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - TZ=${TIMEZONE} - - COMPOSE_VERSION=02b + - COMPOSE_VERSION=02c - COMPOSE_TYPE=with-postgres volumes: - sqlite_volume:/var/lib/routerfleet_sqlite/ - media_root:/var/lib/routerfleet/ - static_volume:/app_static_files/ + - app_secrets:/app_secrets/ command: /bin/bash /app/init.sh depends_on: - routerfleet-postgres @@ -56,6 +57,8 @@ services: dockerfile: Dockerfile-monitoring environment: - TZ=${TIMEZONE} + volumes: + - app_secrets:/app_secrets/ depends_on: - routerfleet @@ -84,3 +87,4 @@ volumes: media_root: postgres_data: sqlite_volume: + app_secrets: \ No newline at end of file diff --git a/docker-compose-no-postgres.yml b/docker-compose-no-postgres.yml index 9a85b48..1462224 100644 --- a/docker-compose-no-postgres.yml +++ b/docker-compose-no-postgres.yml @@ -13,12 +13,13 @@ services: - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - TZ=${TIMEZONE} - - COMPOSE_VERSION=02b + - COMPOSE_VERSION=02c - COMPOSE_TYPE=no-postgres volumes: - sqlite_volume:/var/lib/routerfleet_sqlite/ - media_root:/var/lib/routerfleet/ - static_volume:/app_static_files/ + - app_secrets:/app_secrets/ command: /bin/bash /app/init.sh routerfleet-cron: @@ -36,6 +37,8 @@ services: image: eduardosilva/routerfleet-monitoring:latest environment: - TZ=${TIMEZONE} + volumes: + - app_secrets:/app_secrets/ depends_on: - routerfleet @@ -61,3 +64,4 @@ volumes: media_root: postgres_data: sqlite_volume: + app_secrets: diff --git a/docker-compose.yml b/docker-compose.yml index 86a5b15..3ca574a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,12 +25,13 @@ services: - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - TZ=${TIMEZONE} - - COMPOSE_VERSION=02b + - COMPOSE_VERSION=02c - COMPOSE_TYPE=with-postgres volumes: - sqlite_volume:/var/lib/routerfleet_sqlite/ - media_root:/var/lib/routerfleet/ - static_volume:/app_static_files/ + - app_secrets:/app_secrets/ command: /bin/bash /app/init.sh depends_on: - routerfleet-postgres @@ -50,6 +51,8 @@ services: image: eduardosilva/routerfleet-monitoring:latest environment: - TZ=${TIMEZONE} + volumes: + - app_secrets:/app_secrets/ depends_on: - routerfleet @@ -75,3 +78,4 @@ volumes: media_root: postgres_data: sqlite_volume: + app_secrets: diff --git a/entrypoint.sh b/entrypoint.sh index fb2e9f9..b02333d 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -3,7 +3,7 @@ PRODUCTION_SETTINGS_FILE="/app/routerfleet/production_settings.py" set -e -if [[ "$COMPOSE_VERSION" != "02b" ]]; then +if [[ "$COMPOSE_VERSION" != "02c" ]]; then echo "ERROR: Please upgrade your docker compose file. Exiting." exit 1 fi @@ -78,6 +78,12 @@ if [ -n "$TZ" ]; then echo "TIME_ZONE = '$TZ'" >> $PRODUCTION_SETTINGS_FILE fi +if [ ! -f /app_secrets/monitoring_key ]; then + cat /proc/sys/kernel/random/uuid > /app_secrets/monitoring_key +fi +echo "MONITORING_KEY = '$(cat /app_secrets/monitoring_key)'" >> $PRODUCTION_SETTINGS_FILE + + sed -i "/^ path('admin\/', admin.site.urls),/s/^ / # /" /app/routerfleet/urls.py exec "$@" diff --git a/monitoring/views.py b/monitoring/views.py index f2b714d..45a56ea 100644 --- a/monitoring/views.py +++ b/monitoring/views.py @@ -4,11 +4,13 @@ from monitoring.models import RouterDownTime from router_manager.models import Router, RouterStatus, RouterGroup from django.http import JsonResponse from django.utils import timezone - +from django.conf import settings from routerfleet_tools.models import WebadminSettings def view_router_config_timestamp(request): + if not request.user.is_authenticated and request.GET.get('key') != settings.MONITORING_KEY: + return JsonResponse({'error': 'Not authenticated'}, status=403) webadmin_settings, _ = WebadminSettings.objects.get_or_create(name='webadmin_settings') if not webadmin_settings.router_config_last_updated: webadmin_settings.router_config_last_updated = timezone.now() @@ -18,6 +20,8 @@ def view_router_config_timestamp(request): def view_router_last_status_change(request): + if not request.user.is_authenticated and request.GET.get('key') != settings.MONITORING_KEY: + return JsonResponse({'error': 'Not authenticated'}, status=403) last_router_status_change = RouterStatus.objects.filter(last_status_change__isnull=False).order_by('-last_status_change').first() if last_router_status_change: last_status_change_timestamp = last_router_status_change.last_status_change.isoformat() @@ -27,6 +31,8 @@ def view_router_last_status_change(request): def view_export_router_list(request): + if not request.user.is_authenticated and request.GET.get('key') != settings.MONITORING_KEY: + return JsonResponse({'error': 'Not authenticated'}, status=403) webadmin_settings, _ = WebadminSettings.objects.get_or_create(name='webadmin_settings') # Not updating the monitoring last run here, as this view is also used on the dashboard if not webadmin_settings.router_config_last_updated: @@ -55,6 +61,8 @@ def view_export_router_list(request): def view_update_router_status(request): + if not request.user.is_authenticated and request.GET.get('key') != settings.MONITORING_KEY: + return JsonResponse({'error': 'Not authenticated'}, status=403) router = Router.objects.get(uuid=request.GET.get('uuid')) new_status = request.GET.get('status') if router.routerstatus.status_online: diff --git a/routerfleet/settings.py b/routerfleet/settings.py index 23c727e..9088ce8 100644 --- a/routerfleet/settings.py +++ b/routerfleet/settings.py @@ -140,6 +140,6 @@ STATICFILES_DIRS = [ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' MEDIA_ROOT = '/var/lib/routerfleet/' -ROUTERFLEET_VERSION = 7011 +ROUTERFLEET_VERSION = 7012 from routerfleet.production_settings import *