diff --git a/backup/__init__.py b/backup/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backup/admin.py b/backup/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/backup/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/backup/apps.py b/backup/apps.py new file mode 100644 index 0000000..381fefb --- /dev/null +++ b/backup/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class BackupConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'backup' diff --git a/backup/migrations/0001_initial.py b/backup/migrations/0001_initial.py new file mode 100644 index 0000000..18e270b --- /dev/null +++ b/backup/migrations/0001_initial.py @@ -0,0 +1,47 @@ +# Generated by Django 5.0.3 on 2024-03-17 13:41 + +import uuid +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='BackupProfile', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100, unique=True)), + ('daily_backup', models.BooleanField(default=True)), + ('weekly_backup', models.BooleanField(default=False)), + ('monthly_backup', models.BooleanField(default=False)), + ('daily_retenion', models.IntegerField(default=7)), + ('weekly_retention', models.IntegerField(default=30)), + ('monthly_retenion', models.IntegerField(default=365)), + ('retain_backups_on_error', models.BooleanField(default=True)), + ('daily_day_monday', models.BooleanField(default=True)), + ('daily_day_tuesday', models.BooleanField(default=True)), + ('daily_day_wednesday', models.BooleanField(default=True)), + ('daily_day_thursday', models.BooleanField(default=True)), + ('daily_day_friday', models.BooleanField(default=True)), + ('daily_day_saturday', models.BooleanField(default=True)), + ('daily_day_sunday', models.BooleanField(default=True)), + ('weekly_day', models.CharField(choices=[('monday', 'Monday'), ('tuesday', 'Tuesday'), ('wednesday', 'Wednesday'), ('thursday', 'Thursday'), ('friday', 'Friday'), ('saturday', 'Saturday'), ('sunday', 'Sunday')], max_length=10)), + ('monthly_day', models.IntegerField(choices=[(1, '1st'), (7, '7th'), (14, '14th'), (21, '21st'), (28, '28th')], default=1)), + ('daily_hour', models.IntegerField(choices=[(0, '00:00'), (1, '01:00'), (2, '02:00'), (3, '03:00'), (4, '04:00'), (5, '05:00'), (6, '06:00'), (7, '07:00'), (8, '08:00'), (9, '09:00'), (10, '10:00'), (11, '11:00'), (12, '12:00'), (13, '13:00'), (14, '14:00'), (15, '15:00'), (16, '16:00'), (17, '17:00'), (18, '18:00'), (19, '19:00'), (20, '20:00'), (21, '21:00'), (22, '22:00'), (23, '23:00')], default=3)), + ('weekly_hour', models.IntegerField(choices=[(0, '00:00'), (1, '01:00'), (2, '02:00'), (3, '03:00'), (4, '04:00'), (5, '05:00'), (6, '06:00'), (7, '07:00'), (8, '08:00'), (9, '09:00'), (10, '10:00'), (11, '11:00'), (12, '12:00'), (13, '13:00'), (14, '14:00'), (15, '15:00'), (16, '16:00'), (17, '17:00'), (18, '18:00'), (19, '19:00'), (20, '20:00'), (21, '21:00'), (22, '22:00'), (23, '23:00')], default=1)), + ('monthly_hour', models.IntegerField(choices=[(0, '00:00'), (1, '01:00'), (2, '02:00'), (3, '03:00'), (4, '04:00'), (5, '05:00'), (6, '06:00'), (7, '07:00'), (8, '08:00'), (9, '09:00'), (10, '10:00'), (11, '11:00'), (12, '12:00'), (13, '13:00'), (14, '14:00'), (15, '15:00'), (16, '16:00'), (17, '17:00'), (18, '18:00'), (19, '19:00'), (20, '20:00'), (21, '21:00'), (22, '22:00'), (23, '23:00')], default=0)), + ('max_retry', models.IntegerField(choices=[(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5')], default=3)), + ('retry_interval', models.IntegerField(choices=[('1', '1 Minute'), ('15', '15 Minutes'), ('30', '30 Minutes'), ('60', '1 Hour')], default=30)), + ('backup_interval', models.IntegerField(choices=[(0, 'No interval'), (5, '5 seconds'), (60, '1 minute')], default=60)), + ('updated', models.DateTimeField(auto_now=True)), + ('created', models.DateTimeField(auto_now_add=True)), + ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ], + ), + ] diff --git a/backup/migrations/__init__.py b/backup/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backup/models.py b/backup/models.py new file mode 100644 index 0000000..c813d6f --- /dev/null +++ b/backup/models.py @@ -0,0 +1,49 @@ +from django.db import models +import uuid + + +HOUR_CHOICES = ( + (0, '00:00'), (1, '01:00'), (2, '02:00'), (3, '03:00'), (4, '04:00'), (5, '05:00'), (6, '06:00'), (7, '07:00'), + (8, '08:00'), (9, '09:00'), (10, '10:00'), (11, '11:00'), (12, '12:00'), (13, '13:00'), (14, '14:00'), + (15, '15:00'), (16, '16:00'), (17, '17:00'), (18, '18:00'), (19, '19:00'), (20, '20:00'), (21, '21:00'), + (22, '22:00'), (23, '23:00') +) + + +class BackupProfile(models.Model): + name = models.CharField(max_length=100, unique=True) + daily_backup = models.BooleanField(default=True) + weekly_backup = models.BooleanField(default=False) + monthly_backup = models.BooleanField(default=False) + + daily_retenion = models.IntegerField(default=7) + weekly_retention = models.IntegerField(default=30) + monthly_retenion = models.IntegerField(default=365) + retain_backups_on_error = models.BooleanField(default=True) + + daily_day_monday = models.BooleanField(default=True) + daily_day_tuesday = models.BooleanField(default=True) + daily_day_wednesday = models.BooleanField(default=True) + daily_day_thursday = models.BooleanField(default=True) + daily_day_friday = models.BooleanField(default=True) + daily_day_saturday = models.BooleanField(default=True) + daily_day_sunday = models.BooleanField(default=True) + + weekly_day = models.CharField(max_length=10, choices=(('monday', 'Monday'), ('tuesday', 'Tuesday'), ('wednesday', 'Wednesday'), ('thursday', 'Thursday'), ('friday', 'Friday'), ('saturday', 'Saturday'), ('sunday', 'Sunday'))) + monthly_day = models.IntegerField(default=1, choices=((1, '1st'), (7, '7th'), (14, '14th'), (21, '21st'), (28, '28th'))) + + daily_hour = models.IntegerField(default=3, choices=HOUR_CHOICES) + weekly_hour = models.IntegerField(default=1, choices=HOUR_CHOICES) + monthly_hour = models.IntegerField(default=0, choices=HOUR_CHOICES) + + max_retry = models.IntegerField(default=3, choices=((1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5'))) + retry_interval = models.IntegerField(default=30, choices=(('1', '1 Minute'), ('15', '15 Minutes'), ('30', '30 Minutes'), ('60', '1 Hour'))) + backup_interval = models.IntegerField(default=60, choices=((0, 'No interval'), (5, '5 seconds'), (60, '1 minute'))) + + updated = models.DateTimeField(auto_now=True) + created = models.DateTimeField(auto_now_add=True) + uuid = models.UUIDField(unique=True, editable=False, default=uuid.uuid4) + + def __str__(self): + return self.name + diff --git a/backup/tests.py b/backup/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/backup/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/backup/views.py b/backup/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/backup/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/router_manager/migrations/0008_routerstatus_last_backup_failed_backupschedule.py b/router_manager/migrations/0008_routerstatus_last_backup_failed_backupschedule.py new file mode 100644 index 0000000..e792e64 --- /dev/null +++ b/router_manager/migrations/0008_routerstatus_last_backup_failed_backupschedule.py @@ -0,0 +1,33 @@ +# Generated by Django 5.0.3 on 2024-03-17 13:41 + +import django.db.models.deletion +import uuid +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('router_manager', '0007_alter_routergroup_routers'), + ] + + operations = [ + migrations.AddField( + model_name='routerstatus', + name='last_backup_failed', + field=models.DateTimeField(blank=True, null=True), + ), + migrations.CreateModel( + name='BackupSchedule', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('next_daily_backup', models.DateTimeField(blank=True, null=True)), + ('next_weekly_backup', models.DateTimeField(blank=True, null=True)), + ('next_monthly_backup', models.DateTimeField(blank=True, null=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('created', models.DateTimeField(auto_now_add=True)), + ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('router', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='router_manager.router')), + ], + ), + ] diff --git a/router_manager/migrations/0009_router_backup_profile.py b/router_manager/migrations/0009_router_backup_profile.py new file mode 100644 index 0000000..035229e --- /dev/null +++ b/router_manager/migrations/0009_router_backup_profile.py @@ -0,0 +1,20 @@ +# Generated by Django 5.0.3 on 2024-03-17 13:41 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('backup', '0001_initial'), + ('router_manager', '0008_routerstatus_last_backup_failed_backupschedule'), + ] + + operations = [ + migrations.AddField( + model_name='router', + name='backup_profile', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='backup.backupprofile'), + ), + ] diff --git a/router_manager/models.py b/router_manager/models.py index c1165b4..9132270 100644 --- a/router_manager/models.py +++ b/router_manager/models.py @@ -1,4 +1,5 @@ from django.db import models +from backup.models import BackupProfile import uuid @@ -23,6 +24,7 @@ class Router(models.Model): password = models.CharField(max_length=100, null=True, blank=True) ssh_key = models.ForeignKey(SSHKey, on_delete=models.SET_NULL, null=True, blank=True) monitoring = models.BooleanField(default=True) + backup_profile = models.ForeignKey(BackupProfile, on_delete=models.SET_NULL, null=True, blank=True) router_type = models.CharField(max_length=100, choices=(('routeros', 'Mikrotik (RouterOS)'), ('openwrt', 'OpenWRT'))) enabled = models.BooleanField(default=True) @@ -40,6 +42,7 @@ class RouterStatus(models.Model): status_online = models.BooleanField(default=False) last_status_change = models.DateTimeField(blank=True, null=True) last_backup = models.DateTimeField(blank=True, null=True) + last_backup_failed = models.DateTimeField(blank=True, null=True) updated = models.DateTimeField(auto_now=True) created = models.DateTimeField(auto_now_add=True) @@ -58,3 +61,17 @@ class RouterGroup(models.Model): def __str__(self): return self.name + + +class BackupSchedule(models.Model): + router = models.OneToOneField(Router, on_delete=models.CASCADE) + next_daily_backup = models.DateTimeField(null=True, blank=True) + next_weekly_backup = models.DateTimeField(null=True, blank=True) + next_monthly_backup = models.DateTimeField(null=True, blank=True) + + updated = models.DateTimeField(auto_now=True) + created = models.DateTimeField(auto_now_add=True) + uuid = models.UUIDField(unique=True, editable=False, default=uuid.uuid4) + + + diff --git a/routerfleet/settings.py b/routerfleet/settings.py index 296fe51..3b0a4a8 100644 --- a/routerfleet/settings.py +++ b/routerfleet/settings.py @@ -41,7 +41,8 @@ INSTALLED_APPS = [ 'crispy_bootstrap4', 'user_manager', 'router_manager', - 'monitoring' + 'monitoring', + 'backup', ] MIDDLEWARE = [