(feature) Require delete count confirmation for retention apply
Make manual retention application more explicit by requiring operators to confirm both the host name and the current number of planned deletions. This reduces the risk of applying a stale or misunderstood retention plan when the delete set changes between review and confirmation.
This commit is contained in:
@@ -1412,6 +1412,8 @@ class ViewTests(TestCase):
|
||||
self.assertContains(response, "newest")
|
||||
self.assertContains(response, "Would Delete")
|
||||
self.assertContains(response, "outside retention policy")
|
||||
self.assertContains(response, "Confirm delete count")
|
||||
self.assertContains(response, "Type 1 to confirm the current number of planned deletions.")
|
||||
|
||||
def test_retention_plan_warns_when_scheduled_prune_limit_is_exceeded(self) -> None:
|
||||
self.client.force_login(self.staff_user)
|
||||
@@ -1546,6 +1548,7 @@ class ViewTests(TestCase):
|
||||
"kind": "scheduled",
|
||||
"max_delete": "1",
|
||||
"confirm_host": host.host,
|
||||
"confirm_delete_count": "1",
|
||||
},
|
||||
follow=True,
|
||||
)
|
||||
@@ -1569,6 +1572,7 @@ class ViewTests(TestCase):
|
||||
"kind": "scheduled",
|
||||
"max_delete": "1",
|
||||
"confirm_host": "wrong",
|
||||
"confirm_delete_count": "1",
|
||||
},
|
||||
follow=True,
|
||||
)
|
||||
@@ -1577,6 +1581,34 @@ class ViewTests(TestCase):
|
||||
self.assertContains(response, "Retention apply confirmation is invalid.")
|
||||
self.assertEqual(SnapshotRecord.objects.count(), 1)
|
||||
|
||||
def test_retention_apply_rejects_mismatched_delete_count_confirmation(self) -> None:
|
||||
self.client.force_login(self.staff_user)
|
||||
host = HostConfig.objects.create(
|
||||
host="web-01",
|
||||
address="web-01.example.test",
|
||||
retention_daily=0,
|
||||
retention_weekly=0,
|
||||
retention_monthly=0,
|
||||
retention_yearly=0,
|
||||
)
|
||||
self._snapshot(host, "20260518-021500Z__OLDSNAP")
|
||||
self._snapshot(host, "20260519-021500Z__NEWSNAP")
|
||||
|
||||
response = self.client.post(
|
||||
reverse("apply_host_retention", args=[host.host]),
|
||||
{
|
||||
"kind": "scheduled",
|
||||
"max_delete": "1",
|
||||
"confirm_host": host.host,
|
||||
"confirm_delete_count": "0",
|
||||
},
|
||||
follow=True,
|
||||
)
|
||||
|
||||
self.assertRedirects(response, reverse("host_retention_plan", args=[host.host]))
|
||||
self.assertContains(response, "Retention apply confirmation is invalid.")
|
||||
self.assertEqual(SnapshotRecord.objects.count(), 2)
|
||||
|
||||
def test_retention_apply_requires_post(self) -> None:
|
||||
self.client.force_login(self.staff_user)
|
||||
host = HostConfig.objects.create(host="web-01", address="web-01.example.test")
|
||||
|
||||
Reference in New Issue
Block a user