mirror of
https://github.com/eduardogsilva/routerfleet.git
synced 2025-06-20 17:15:39 +02:00
Message notification and sending
This commit is contained in:
parent
dfb4285ab3
commit
034bc7057b
9 changed files with 182 additions and 3 deletions
|
@ -7,6 +7,7 @@ from django.utils import timezone
|
|||
|
||||
from backup.models import BackupProfile
|
||||
from backup_data.models import RouterBackup
|
||||
from message_center.functions import notify_backup_fail
|
||||
from router_manager.models import Router, BackupSchedule, RouterStatus
|
||||
from routerlib.backup_functions import perform_backup
|
||||
|
||||
|
@ -249,6 +250,7 @@ def view_housekeeping(requests):
|
|||
backup.save()
|
||||
backup.router.routerstatus.last_backup_failed = timezone.now()
|
||||
backup.router.routerstatus.save()
|
||||
notify_backup_fail(backup)
|
||||
|
||||
if not RouterBackup.objects.filter(router=backup.router, success=False, error=False).exists():
|
||||
backup.router.routerstatus.backup_lock = None
|
||||
|
|
105
message_center/functions.py
Normal file
105
message_center/functions.py
Normal file
|
@ -0,0 +1,105 @@
|
|||
import datetime
|
||||
|
||||
from router_manager.models import Router
|
||||
from .models import MessageChannel, Notification, MessageSettings, Message
|
||||
from backup_data.models import RouterBackup
|
||||
import requests
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
def send_notification_message(message: Message):
|
||||
message_settings, _ = MessageSettings.objects.get_or_create(name='message_settings')
|
||||
if message.status != 'pending':
|
||||
return
|
||||
if message.retry_count > message_settings.max_retry:
|
||||
message.status = 'failed'
|
||||
message.completed = timezone.now()
|
||||
message.save()
|
||||
return
|
||||
|
||||
message_response = {'status': 'pending', 'error_message': '', 'error_status_code': 0}
|
||||
if message.channel.channel_type == 'callmebot':
|
||||
url = f'https://api.callmebot.com/whatsapp.php?phone={message.channel.destination}&text={message.message}&apikey={message.channel.token}'
|
||||
elif message.channel.channel_type == 'telegram':
|
||||
url = f'https://api.telegram.org/bot{message.channel.token}/sendMessage?chat_id={message.channel.destination}&text={message.message}'
|
||||
else:
|
||||
message_response['status'] = 'failed'
|
||||
message_response['error_message'] = 'Failed to send message: Invalid channel type'
|
||||
message_response['error_status_code'] = 0
|
||||
|
||||
if message_response['status'] == 'pending':
|
||||
try:
|
||||
response = requests.get(url)
|
||||
if response.status_code == 200:
|
||||
message_response['status'] = 'sent'
|
||||
else:
|
||||
message_response['status'] = 'failed'
|
||||
message_response['error_message'] = response.text
|
||||
message_response['error_status_code'] = response.status_code
|
||||
except:
|
||||
message_response['status'] = 'failed'
|
||||
message_response['error_message'] = 'Failed to send message: Request exception'
|
||||
message_response['error_status_code'] = 0
|
||||
|
||||
if message_response['status'] == 'sent':
|
||||
message.status = 'sent'
|
||||
message.completed = timezone.now()
|
||||
message.save()
|
||||
else:
|
||||
message.retry_count += 1
|
||||
message.error_message = message_response['error_message']
|
||||
message.error_status_code = message_response['error_status_code']
|
||||
message.next_retry = timezone.now() + datetime.timedelta(seconds=message_settings.retry_interval)
|
||||
message.save()
|
||||
return
|
||||
|
||||
|
||||
def notify_router_status_update(router: Router):
|
||||
message_channel_list = MessageChannel.objects.filter(enabled=True)
|
||||
message_settings, _ = MessageSettings.objects.get_or_create(name='message_settings')
|
||||
|
||||
if message_settings.concatenate_status_change:
|
||||
if router.routerstatus.status_online:
|
||||
if message_channel_list.filter(status_change_online=True):
|
||||
Notification.objects.create(notification_type='status_online', router=router)
|
||||
else:
|
||||
if message_channel_list.filter(status_change_offline=True):
|
||||
Notification.objects.create(notification_type='status_offline', router=router)
|
||||
else:
|
||||
if router.routerstatus.status_online:
|
||||
for message_channel in message_channel_list.filter(status_change_online=True):
|
||||
Message.objects.create(
|
||||
channel=message_channel,
|
||||
subject='Router status change: Online',
|
||||
message=f'Router {router.name} ({router.address}) is now online'
|
||||
)
|
||||
else:
|
||||
for message_channel in message_channel_list.filter(status_change_offline=True):
|
||||
Message.objects.create(
|
||||
channel=message_channel,
|
||||
subject='Router status change: Offline',
|
||||
message=f'Router {router.name} ({router.address}) is now offline'
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
def notify_backup_fail(router_backup: RouterBackup):
|
||||
message_settings, _ = MessageSettings.objects.get_or_create(name='message_settings')
|
||||
message_channel_list = MessageChannel.objects.filter(enabled=True, backup_fail=True)
|
||||
|
||||
if not message_channel_list:
|
||||
return
|
||||
|
||||
if message_settings.concatenate_backup_fails:
|
||||
Notification.objects.create(notification_type='backup_fail', router=router_backup.router, router_backup=router_backup)
|
||||
else:
|
||||
error_message = f'Backup {router_backup.id} failed for router {router_backup.router.name} ({router_backup.router.address})'
|
||||
if router_backup.error_message:
|
||||
error_message += f'\n\nError message: {router_backup.error_message}'
|
||||
for message_channel in message_channel_list:
|
||||
Message.objects.create(
|
||||
channel=message_channel,
|
||||
subject=f'Backup failed: {router_backup.id}',
|
||||
message=error_message
|
||||
)
|
||||
return
|
18
message_center/migrations/0003_message_error_status_code.py
Normal file
18
message_center/migrations/0003_message_error_status_code.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 5.0.4 on 2024-04-16 18:28
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('message_center', '0002_alter_messagechannel_channel_type'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='message',
|
||||
name='error_status_code',
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
]
|
18
message_center/migrations/0004_message_next_retry.py
Normal file
18
message_center/migrations/0004_message_next_retry.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 5.0.4 on 2024-04-16 18:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('message_center', '0003_message_error_status_code'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='message',
|
||||
name='next_retry',
|
||||
field=models.DateTimeField(blank=True, null=True),
|
||||
),
|
||||
]
|
|
@ -35,6 +35,9 @@ class MessageChannel(models.Model):
|
|||
created = models.DateTimeField(auto_now_add=True)
|
||||
uuid = models.UUIDField(unique=True, default=uuid.uuid4, editable=False)
|
||||
|
||||
def __str__(self):
|
||||
return self.name + ' (' + self.channel_type + ')'
|
||||
|
||||
|
||||
class Message(models.Model):
|
||||
channel = models.ForeignKey(MessageChannel, on_delete=models.CASCADE)
|
||||
|
@ -44,7 +47,9 @@ class Message(models.Model):
|
|||
('pending', 'Pending'), ('sent', 'Sent'), ('failed', 'Failed'),
|
||||
), default='pending')
|
||||
retry_count = models.IntegerField(default=0)
|
||||
next_retry = models.DateTimeField(blank=True, null=True)
|
||||
error_message = models.TextField(blank=True, null=True)
|
||||
error_status_code = models.IntegerField(blank=True, null=True)
|
||||
completed = models.DateTimeField(blank=True, null=True)
|
||||
|
||||
updated = models.DateTimeField(auto_now=True)
|
||||
|
|
|
@ -1,9 +1,34 @@
|
|||
from django.shortcuts import render, redirect
|
||||
from django.http import JsonResponse, Http404
|
||||
from django.shortcuts import render, redirect, Http404, get_object_or_404
|
||||
from django.contrib import messages
|
||||
|
||||
from router_manager.models import Router
|
||||
from user_manager.models import UserAcl
|
||||
from .forms import MessageSettingsForm, MessageChannelForm
|
||||
from .models import Notification, MessageChannel, Message, MessageSettings
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.conf import settings
|
||||
from .functions import notify_router_status_update, notify_backup_fail, send_notification_message
|
||||
from backup_data.models import RouterBackup
|
||||
|
||||
|
||||
def view_debug_test_messages(request):
|
||||
if not settings.DEBUG:
|
||||
raise Http404
|
||||
data = {'status': 'success'}
|
||||
router = None
|
||||
router_backup = None
|
||||
if request.GET.get('router_uuid'):
|
||||
router = get_object_or_404(Router, uuid=request.GET.get('router_uuid'))
|
||||
print(f'Creating test message for router {router.name}')
|
||||
notify_router_status_update(router)
|
||||
elif request.GET.get('backup_id'):
|
||||
router_backup = get_object_or_404(RouterBackup, id=request.GET.get('backup_id'))
|
||||
notify_backup_fail(router_backup)
|
||||
else:
|
||||
for message in Message.objects.filter(status='pending'):
|
||||
send_notification_message(message)
|
||||
return JsonResponse(data)
|
||||
|
||||
|
||||
@login_required()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from django.shortcuts import render, get_object_or_404
|
||||
|
||||
from message_center.functions import notify_router_status_update
|
||||
from monitoring.models import RouterDownTime
|
||||
from router_manager.models import Router, RouterStatus, RouterGroup
|
||||
from django.http import JsonResponse
|
||||
|
@ -78,7 +79,6 @@ def view_update_router_status(request):
|
|||
router.routerstatus.save()
|
||||
|
||||
if current_status != new_status:
|
||||
|
||||
if new_status == 'online':
|
||||
router.routerstatus.status_online = True
|
||||
downtime = RouterDownTime.objects.filter(router=router, end_time=None).first()
|
||||
|
@ -92,6 +92,7 @@ def view_update_router_status(request):
|
|||
router.routerstatus.save()
|
||||
if downtime:
|
||||
RouterDownTime.objects.filter(router=router, end_time=None).exclude(uuid=downtime.uuid).delete()
|
||||
notify_router_status_update(router)
|
||||
|
||||
webadmin_settings, _ = WebadminSettings.objects.get_or_create(name='webadmin_settings')
|
||||
webadmin_settings.monitoring_last_run = timezone.now()
|
||||
|
|
|
@ -9,12 +9,13 @@ from backup.views import view_backup_profile_list, view_manage_backup_profile, v
|
|||
from monitoring.views import view_export_router_list, view_update_router_status, view_router_config_timestamp, view_router_last_status_change
|
||||
from backup_data.views import view_generate_backup_schedule, view_create_backup_tasks, view_perform_backup_tasks, view_housekeeping
|
||||
from routerfleet_tools.views import cron_check_updates
|
||||
from message_center.views import view_message_channel_list, view_manage_message_settings, view_manage_message_channel
|
||||
from message_center.views import view_message_channel_list, view_manage_message_settings, view_manage_message_channel, view_debug_test_messages
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('debug/run_backups/', view_debug_run_backups, name='debug_run_backups'),
|
||||
path('debug/test_messages/', view_debug_test_messages, name='debug_test_messages'),
|
||||
path('', view_dashboard, name='dashboard'),
|
||||
path('status/', view_status, name='status'),
|
||||
path('user/list/', view_user_list, name='user_list'),
|
||||
|
|
|
@ -4,6 +4,8 @@ from backup_data.models import RouterBackup
|
|||
import os
|
||||
from scp import SCPClient
|
||||
from django.core.files.base import ContentFile
|
||||
|
||||
from message_center.functions import notify_backup_fail
|
||||
from routerlib.functions import gen_backup_name, connect_to_ssh, get_router_backup_file_extension
|
||||
|
||||
|
||||
|
@ -18,12 +20,14 @@ def perform_backup(router_backup: RouterBackup):
|
|||
router_backup.save()
|
||||
router_backup.router.routerstatus.backup_lock = None
|
||||
router_backup.router.routerstatus.save()
|
||||
notify_backup_fail(router_backup)
|
||||
return
|
||||
if router_backup.retry_count > router_backup.router.backup_profile.max_retry:
|
||||
router_backup.error = True
|
||||
router_backup.save()
|
||||
router_backup.router.routerstatus.backup_lock = None
|
||||
router_backup.router.routerstatus.save()
|
||||
notify_backup_fail(router_backup)
|
||||
return
|
||||
|
||||
if router_backup.backup_pending_retrieval:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue