Monitoring api is now protected by key.

This commit is contained in:
Eduardo Silva 2024-04-15 13:59:13 -03:00
parent 847775f87a
commit ddb2304b64
7 changed files with 66 additions and 17 deletions

View file

@ -2,11 +2,11 @@ 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"
HOST_LIST_URL = f"{API_ADDRESS}/monitoring/export_router_list/"
@ -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 update_router_config_timestamp():
global remote_router_config_timestamp
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:
response = requests.get(CONFIG_TIMESTAMP_URL)
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, api_key
try:
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()

View file

@ -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:

View file

@ -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:

View file

@ -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:

View file

@ -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 "$@"

View file

@ -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:

View file

@ -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 *