(feature) Add snapshot discovery action to host view
Add a staff-only POST action on host detail pages to discover existing snapshots for that host and record them into SQL. Show success or failure feedback through Django messages, and keep the action non-destructive before adding heavier backup or retention controls. Cover the action with view tests for successful discovery, redirect behavior, and method safety.
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
from pobsync_backend.models import BackupRun, HostConfig, ScheduleConfig, SnapshotRecord
|
||||
from pobsync.util import write_yaml_atomic
|
||||
from pobsync_backend.models import BackupRun, GlobalConfig, HostConfig, ScheduleConfig, SnapshotRecord
|
||||
|
||||
|
||||
class ViewTests(TestCase):
|
||||
@@ -63,6 +66,7 @@ class ViewTests(TestCase):
|
||||
self.assertContains(response, "web-01.example.test")
|
||||
self.assertContains(response, "15 2 * * *")
|
||||
self.assertContains(response, "20260519-021500Z__ABCDEFGH")
|
||||
self.assertContains(response, "Discover snapshots")
|
||||
|
||||
def test_host_detail_returns_404_for_unknown_host(self) -> None:
|
||||
self.client.force_login(self.staff_user)
|
||||
@@ -71,6 +75,31 @@ class ViewTests(TestCase):
|
||||
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_discover_host_snapshots_action_discovers_and_redirects(self) -> None:
|
||||
self.client.force_login(self.staff_user)
|
||||
with TemporaryDirectory() as tmp:
|
||||
backup_root = Path(tmp) / "backups"
|
||||
GlobalConfig.objects.create(name="default", backup_root=str(backup_root))
|
||||
host = HostConfig.objects.create(host="web-01", address="web-01.example.test")
|
||||
snapshot_dir = backup_root / host.host / "scheduled" / "20260519-021500Z__ABCDEFGH"
|
||||
meta_dir = snapshot_dir / "meta"
|
||||
meta_dir.mkdir(parents=True)
|
||||
write_yaml_atomic(meta_dir / "meta.yaml", {"status": "success", "started_at": "2026-05-19T02:15:00Z"})
|
||||
|
||||
response = self.client.post(reverse("discover_host_snapshots", args=[host.host]), follow=True)
|
||||
|
||||
self.assertRedirects(response, reverse("host_detail", args=[host.host]))
|
||||
self.assertContains(response, "Snapshot discovery scanned 1 items")
|
||||
self.assertTrue(SnapshotRecord.objects.filter(host=host, dirname=snapshot_dir.name).exists())
|
||||
|
||||
def test_discover_host_snapshots_requires_post(self) -> None:
|
||||
self.client.force_login(self.staff_user)
|
||||
host = HostConfig.objects.create(host="web-01", address="web-01.example.test")
|
||||
|
||||
response = self.client.get(reverse("discover_host_snapshots", args=[host.host]))
|
||||
|
||||
self.assertEqual(response.status_code, 405)
|
||||
|
||||
def _snapshot(self, host: HostConfig, dirname: str) -> SnapshotRecord:
|
||||
started_at = datetime.strptime(dirname.split("__", 1)[0], "%Y%m%d-%H%M%SZ").replace(tzinfo=timezone.utc)
|
||||
return SnapshotRecord.objects.create(
|
||||
|
||||
Reference in New Issue
Block a user